From af70dd5dfef1d30da345b19c8e4a9241b71a1fe4 Mon Sep 17 00:00:00 2001 From: eeintech Date: Mon, 20 Jul 2020 16:16:26 -0500 Subject: [PATCH 01/58] Allowing Part thumbnail (image) update via API --- InvenTree/part/api.py | 20 +++++++++++++++++++- InvenTree/part/serializers.py | 12 ++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index 472ab1996e..9db4ef5425 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -190,6 +190,21 @@ class PartThumbs(generics.ListAPIView): return Response(data) +class PartThumbsUpdate(generics.RetrieveUpdateAPIView): + """ API endpoint for updating Part thumbnails""" + + queryset = Part.objects.all() + serializer_class = part_serializers.PartThumbSerializerUpdate + + permission_classes = [ + permissions.IsAuthenticated, + ] + + filter_backends = [ + DjangoFilterBackend + ] + + class PartDetail(generics.RetrieveUpdateDestroyAPIView): """ API endpoint for detail view of a single Part object """ @@ -716,7 +731,10 @@ part_api_urls = [ url(r'^.*$', PartParameterList.as_view(), name='api-part-param-list'), ])), - url(r'^thumbs/', PartThumbs.as_view(), name='api-part-thumbs'), + url(r'^thumbs/', include([ + url(r'^$', PartThumbs.as_view(), name='api-part-thumbs'), + url(r'^(?P\d+)/?', PartThumbsUpdate.as_view(), name='api-part-thumbs-update'), + ])), url(r'^(?P\d+)/?', PartDetail.as_view(), name='api-part-detail'), diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index f625a02c41..a77b0f1c3f 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -92,6 +92,18 @@ class PartThumbSerializer(serializers.Serializer): count = serializers.IntegerField(read_only=True) +class PartThumbSerializerUpdate(InvenTreeModelSerializer): + """ Serializer for updating Part thumbnail """ + + image = InvenTreeAttachmentSerializerField(required=True) + + class Meta: + model = Part + fields = [ + 'image', + ] + + class PartBriefSerializer(InvenTreeModelSerializer): """ Serializer for Part (brief detail) """ From f386039d5a9a26d65a67deb3e5babf9cd2f8f17e Mon Sep 17 00:00:00 2001 From: eeintech Date: Tue, 21 Jul 2020 16:01:17 -0500 Subject: [PATCH 02/58] Added validation method for uploaded file using imghdr library --- InvenTree/part/serializers.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index a77b0f1c3f..d460748468 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -1,6 +1,7 @@ """ JSON serializers for Part app """ +import imghdr from rest_framework import serializers @@ -95,6 +96,15 @@ class PartThumbSerializer(serializers.Serializer): class PartThumbSerializerUpdate(InvenTreeModelSerializer): """ Serializer for updating Part thumbnail """ + def validate_image(self, value): + """ + Check that file is an image. + """ + validate = imghdr.what(value) + if not validate: + raise serializers.ValidationError("File is not an image") + return value + image = InvenTreeAttachmentSerializerField(required=True) class Meta: From d90edab59f0c6e3bf18d0ba2d5c436fa4c65b454 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 30 Jul 2020 20:23:46 +1000 Subject: [PATCH 03/58] Staff users are allowed to delete stock items that otherwise are not able to be deleted --- InvenTree/stock/templates/stock/item_base.html | 2 +- InvenTree/stock/templates/stock/item_delete.html | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index 63804291ec..a35b5f0346 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -115,7 +115,7 @@ InvenTree | {% trans "Stock Item" %} - {{ item }} {% endif %}
  • {% trans "Duplicate stock item" %}
  • {% trans "Edit stock item" %}
  • - {% if item.can_delete %} + {% if item.can_delete or user.is_staff %}
  • {% trans "Delete stock item" %}
  • {% endif %} diff --git a/InvenTree/stock/templates/stock/item_delete.html b/InvenTree/stock/templates/stock/item_delete.html index 9e908a0d67..09d9397ecc 100644 --- a/InvenTree/stock/templates/stock/item_delete.html +++ b/InvenTree/stock/templates/stock/item_delete.html @@ -1,11 +1,14 @@ {% extends "modal_delete_form.html" %} +{% load i18n %} +{% load inventree_extras %} + {% block pre_form_content %}
    -Are you sure you want to delete this stock item? +{% trans "Are you sure you want to delete this stock item?" %}
    -This will remove {{ item.quantity }} units of {{ item.part.full_name }} from stock. +This will remove {% decimal item.quantity %} units of {{ item.part.full_name }} from stock.
    {% endblock %} \ No newline at end of file From b7f30ee13648f656c3a8b86eff2f016714b650f4 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 30 Jul 2020 20:26:14 +1000 Subject: [PATCH 04/58] Update translations --- InvenTree/locale/de/LC_MESSAGES/django.mo | Bin 50749 -> 50558 bytes InvenTree/locale/de/LC_MESSAGES/django.po | 602 ++++++++++++++-------- InvenTree/locale/en/LC_MESSAGES/django.po | 551 ++++++++++++-------- InvenTree/locale/es/LC_MESSAGES/django.po | 551 ++++++++++++-------- 4 files changed, 1033 insertions(+), 671 deletions(-) diff --git a/InvenTree/locale/de/LC_MESSAGES/django.mo b/InvenTree/locale/de/LC_MESSAGES/django.mo index 93b1affc812a1b20499aa917caeb284ddbaf61c9..766a862f9d50bc0ab1252c60a0bf54afb543b655 100644 GIT binary patch delta 15762 zcmYk?2Y63c1IO_zlSD{Dh>%D`VnjmhEq3j_Hx+7AswmegYL6NhOH$D5H*2OsEJL*g1877$k}T14_QCQT#WBr zBcg^sVO@NLg|Jc`V=F92`Zd(1tVHJOoVEFWDW<#%mL-26s(b}%A{iKfzhF+hZ~X^D zT{65FH4wv4D~>^JX?fIErC58QRyrOv;pxapIq%y16{rE%VJLotTKP%Tf-*1)@1y$3 zTaWz@BT|TnGRmU1v>Iy0bub#6q8bji`Lj_SFSYrbQSDBnCVm06piJwpm`eH~>gc-E zH}z8Mv;Ug$XfjkV4b^ZVYR0QkXP=J6@RBWmh^qerHIcvu=By)8cc~I;tDB%MZCmul zE~tg}unuUz{+A?UBpDTOCC1`KOu&bzfub536RcHHTig)UVP|ZFeX%-j#U%XMmgl2T z6N<$A7>_#Y8ZHrSS##9u(iJP>7}UzPp&A}W-TqUk9s0t04K;yZZ23LZ-FS-X*T1nz zhoKe{huWd?R<{um4bT;J6#cBDP#sUP&Osf;QuN22sJoMnn)n4&`E4wW&MS^n6pEnA zYocDqPRJ+58IH7fof$;baJ6+Gs^LY{QT&Pi7}~@P7=hZta;TkXi0ZJ7%^!%`xrw%X z0ct|4P&>09wF757Y0m#UB3j8E)Gg1^)TE$bpJv)Z#uOX^lPjt1iF+_6WbkvIHVI-zuEc^udPzklt7N{fYhdT3tm=~v@j(QOWp}W#XwxCv&j@r_5Ha`P3p`UH}Bh(%6YioWu zMWA-33I=0yRCy1Z9*LUJRMZ4k*zzsNrFWgfL_#UZK+Px%Rq-imVE=aJ))zo^6oaZ? z1vSy8s4eb&sdkdLCX6)WR?EWr3qiT37$Qya@r&=Ylbb5I|k<)~YI z2;=ZJR>PnU=2kaGZE;J~Km#xY$Dod2CaS-=s0pt?Eo>wD>HXhJM0enjGVm1Yj4q&l zYF$PB9&ind;uF*k73gT{#aqjwK44W*uWu*Rof(5+xDxZ@ZkvA!UCrosBDy?JQ7g#X z$ry=hkbng+1vNk?>l>(}Sc>|9Z9&!h40RW-+5F$JAZee@W@n0^CYaROzW>e1s7*!} zEP*R*h2u8;J!&F;UCdS%M(tDy)XpTK255#_KtI%77>U~Iu~-OapmsLR=5Ou7{%Z#g zkfAL-h57I*YC>74Gc4KFt55?UMg7dUgoQ8@)z4q3 zg}Fi9%>bdO9Vm*rtz~U~4eKkY4m+SGnu?mp2-J!vq1w+x-HGKky$y8)2T=<-hk83Q zOu6g)M#PJZzfoKEFRFv!9;V}1)RB}y%{&D)!7f+?`=jblMb%qs-D>lXpxS+jx+7T_ zgE@L?2RZ*(BAQ`!)EPEGO=PU60`D!VgY~G_?=Wg7uA|QWE~;biUc7o(7$dPgs(cjc zsAi$+twl|AKl->t&J)q4_!2cxhV>rSCY`gl*`da$t!|2%Ks(eI?p0L#A*iz+h1#Ks zsD-^_(<@Nr8*F+Px;nE%M07UiQD^fls)OHA4W6Lt<>+JTg`mo#P`9`=mcwM!k@Q7f zLKoHVI@CmVp^oY(s=v#9*ndTCkr9s%Py>edH4S4?1C_JZL{0D&)KPUs-QrnT9_OKU z<~Vu=KwZ*XsEOP|UEb%Yas2wZrea7xQz6EhgsM;jb#{$V9rZw+;b7E+r=cdY4Rz+< zViZ2XWDI-NaY|uhjK+}|gNsr9?RAOhz5EO{^XsU~cNZhjtH1f76N!~b*T*Crhg!)N z)Bqo&w)i?0#XDFU15?dJD`RoeJy7LSQRBJmi1-rOV+%e(U8-wXA8*<6xB=!U63~zQ zDyR->+jJ{bKOIq9-5ve$HPme%i8{)+Q4?K+EYNk*h-ixsp;rDC>g;Y~F?@>ZFk+y& z{UtD-bU7@Cov;MX!ZNrU)$RuBZE{{SJ6s5>kgR~Zq=PX?@Bb_!x>UI`!aGU+7L%2H5A*&H?DRE)*fQ3EbV^|u$bb4QeBeCMJq_y)a6-$Z}> z8P(Arr~&>#T|VEzW=kVc6G}#XXzHWtcflH%iV3(5eefdc=&qoSAQN3>WD(KK@1r^l z7-Bjsf;x)wSOM#yZtWXb7^kBKPQy4%$I5u!=I0w~>XpJ?w|EG zj6nPqbq5}zUMK%yCLM=LS4T~#Giss(t>aM>oQqoNaSXy!s0m#`O*mkqH>H3%lU&jEPYMqCg$O_bvZo&q* z6E)5wmxyku??^MlDAbIrV{ROYd2teItLI}dZa@vV57qHW)Ib+d?J`mAZlfmj6m`^I zqs*nug<7DSNJQ^#TT};~Q9F@}YB&KyaRzGO_iTC_>Mc2fI=UOk*W1ZLO|04L=C$sM zn#f30{uI;%7oz9=Ut=pAKyBq&)a&&(>h*~jZ5q@@l{Z7ZP7^Q$SD?;z8|K5)sD)&r z2Ko(E?=kA={KuH`V2_-C6cKH08O)FMP#twb&3G_|;&_{$hx!1mMqSDir~z-GZuLFX zgmS%Mz8i63d#9k`CU@JG~)|3K}?W7JUuj5l{8 z33V5$q3Sh7ZE-tPKmF13iAA-ah1$V27>2uT`t*3-e>J>DhB~~1TH$llt&W{wjvxW` zUROt*X&qF%<`{uJQ3H=dU0N44vDv7jT!QLvvvn8hF72Pd{;S|N8Cu~z)aA?fmiZJ{ z!qgnB6m^T!CYphEqb8D$TGdf9oZRvc}j(mVIc)*&8n(%Yf7W+>#AD|f20ur$()eq5-DX?99d&2YZTd9!A$=KjcPhM1 zdv@DNA)*eOTRWi!?u+Vp2o}UysI5;!?bI<;yR)b>y@Fc#kEpxhHN$-K!_kLyQJXG~ znm_`2{{CN;h&~t%u^LW9eJJ*0Mf?f%*OI)P(z^?!<6R!9!R9pQ8pW zH_Ozkg*w{Cv+VodlMHn<0`=jThWc`)q0aOo`r%E~K(|pHK0qD83tJxWj(HnGP!leQ zY9D9QRZu(D5Op-I-(mk%u{RkSU>K^w7}OTdwE1gL4L4vs?m`WmfjW{OQ7g(Z+oZ!W zl5`b}!wxoo0!EWwiMsTMTp~KNOSZy2EJixd9J2$-sPbOuk1lG$Gf_LR)VdCJ%XgtB z@;T~*bPKi8Cm4->b4`8;R6VyQ5p8`t)QVG4NAQ--e-G8chp12VVVnO2YQUSQf&N8( zCxYjhj!U6-AO*EUJyGQoQT;DN#&w-NL^SYe)Gfbm(|@667%<;7h{2qsYh!L~jGB0R z)K(6#PC!j;0czlFsQTwn{biuus=FRJ|6B{q>l25*6jZe7>X?^w6V%=4f`Ql@wc;VD z`cqJMW+rMP?_pWofr)qnRX=c{SwJ-AC0z>jId`fN(F|K*9_)@<*(aF&Lk$O`wrV=6 z!Rqw^fqFfCmzovFq57+b>ZdD);s{i`X{do$quT9piIgI81@+VHf2alp zm)V)3CQuXAacfk=fvEbkP+PhVwdEh7F6Bj={u=exJU}hz8P>+Y<>u4wHYE~EhKuTO zy)8I`YVZ)F(R&4xz~WdD`(Qa-hC0hLSP-vZ5Z=N3_z!AAdEPVi@}urpG_o+)DMv(? zqycKCZBTchtFK3MZ@`BID| zorc=Eqo@hoLeIbdJtCqRdcSWjUpQ*T30MQ`pnidvfZCzS)>Wtu(@_(7X=or;<<$tAXmTH5S3%sH2>i=9-l)AwyfY0yWc*Q3IYp-Gz&&Bg#aTXQ4WLW)1kj z)Q><77>6paj#_b3)WSNW+7CiaV1jEaEJAJZS}cqkP%}M_dOL2QR{lFiVvcoYfT9>p zx-4pd);8T2wV-LJc55&S_oDj0g1W@+JtC@@f4!M`66*D-k1;q1)xlg;!}VAUkD=QA zh~fAgHQ}%g<}a<~QLo=v)JoG(cPAY+k;_PX*SSwbABcdB=KT#ubr_E7Fd5rpOZ39^ zsJpTWHL+bbeHwLSmrz@ti5mDf)Xuy>)eqiejpRJ*q&<2%cVXn?I)4iBIjWT95{ z$ddre%!6;B=W?JrUXGsc0crxr(GSm}ekNS9dhIfIr;;@lwFAqo>8MM66>H(2SRCCl zyUhgJpnmb_gZjXXwk}4^csFW=2T?0IfpPdfYDauNG7AXDMA9Wt3+aGGaR93ROjLh6 z(DVN9Cz6MZ%cucvqBmxtcHk~*fM=+!%=59i)rBxG>C&i)S4Y)rfoj(W^)?Jc-JOq7 z1Am9U_zULI`+tXsI(~+#=)1>sl!W?#)U$TRDx`;@2Hu38FPil-YD@n>tu$n>If5#v zJJk_WaU81On=04)|AdHMudscl<3!Y3Pzx(ydt|GeS*VWJVHlo8)%zax+C9cPSSa1B zvgyH*co*v7NG9P3e?tbw(0#C zLi#j%UQg7-Zd(7uP}0v)uUp=O=ItqrB}f-L$o?zRlnl*q6lx$BwetC>hTBjRO~-tA z!Fm(*L+US7`;bHY8irA*i4R7Vk4Cj$gqrAPRKL4iBD!>kP&54*tK(BFjpYxUv+aSJ z*c8;QUWi5TYt$A$z-aV4Vm`ekFqm{p)Q{C%Y>CUr}HK-Zxzyf#zwY8b3 zj{ZPR@P9Tx_^9~+6+?B@!P+0ANsqx&xC}Mman#Dsqju^FvOw3lNkq3g@R+&n$yk$g ze=LXVu$~%VVJvXm>{xk>BHazA<9Lk3|4_F(@>BD(q7Lfqn2wsz7SspoD;%x&-}#K$ z!x+?u;XHaiNT@Tsi5fTy!_oJI*@-A?GU~QBKTV*l<+4rM7%079xELJ%9iI zfrz&DG3tzRo-{L!L~UJTRC!y}g!-c;pC6X=d{jPqy*xl-0Cx z?zbNP{f9q~QZS#;k8pt!r_FrgwILyo0W4~&Fr&;yfWDd{E~Wl>Jqe4JsSzV zsFz4t6zXBU&M?9mFV26La(Et7SkP8bI+OTF8ZA(Q=Ud_#*qiV=Wlyj(R>lnc0gDl; z5U)qwvZ&{Tbs~9s9vhr??vLMt*q!Yza!iC-gRKW`FW zN8)QjL*lvUY!7~p6K$o>unc+nX3Ql_A}pp{&u#Mi5?&+S1^>(8dH;w|_y^%Qnd@xj zSlmxK-lp}Yeom-Mo}Qvui?X5k8eu2#It1P9R6+vrH1hTJ8%lVO(3`w>QO}oz=p4M5 zOO>Fao)ElF*ygn)xpKZGDV2RR>??#ODLHN2|dZv^W>%WE6E#A-X!uyU;@G2MB)@-v~94K%m#!%$=gY2VDn3>0ckJ7 zAA}O5v!4m1o00gHP{d~T!)dgQ#_p6iB;K6(4&q;-K8ZY9KmQ96nZ*ctUJ!mK=o6Iv ztf%aKLSZ^-L^w};IE5GRE7F@WFQGqqF{rPOp5+FoI(d4w;8hcKKJ>`=uM+vpRv1E@ z-yWQHo~Q0HJRy?a0$pn6Q|%pXAIf40-sBY_T(D(id7g{>S-{5Mqs;xA#8g$ZnYnQn>4k)r#CKpW zIxb6m5AlrzJ)_AxfyGHzvw6zTL0rEl>6u3eCY|r4@+8{5O8Nn1HL^d@<;dJghQF=o zLp+RlCBkUp1@Ld`^u;Nd6ZM=XUem_sU}e&JY7oyN-olpkBi_xHeM@;q@_P}+=)Zec zAX1pZMugQAb|z$!HxN4!^t?s-8ey32qz6_debc5>tl`%8X>)}zmGA|5F9=hJ|ASwk zo*~2o6N#*#qay@83km0l|AM2aP!daHd-7iQ{M68mxkvbuP=egrlzu|^mGD18_VWwz z7|MMJdPZPnLSyoK*gWNLBL0lLd`j^2FgRb6|EaC#OI}Ip{7%sL&HxI$ZN&C%9dZEEP#;xR3{!v;uAs#TW1{J zCw25YY zgSKl(d!wHB$)AHC+wxY#-?G24c>d<2N|mTQov@cM(l#7N10Nf&rb;}U32%{i*5H0+5;$%Yh)1CUuNWVeG_t}}&jpUD|Ji?|w!19FJw+2NtyMYW zJ1cF0*iCq98!G*raFNQ#ZKt})w delta 15891 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\n" "Language-Team: C \n" @@ -83,7 +83,7 @@ msgstr "Datei zum Anhängen auswählen" msgid "File comment" msgstr "Datei-Kommentar" -#: InvenTree/models.py:68 templates/js/stock.html:662 +#: InvenTree/models.py:68 templates/js/stock.html:669 msgid "User" msgstr "Benutzer" @@ -303,9 +303,10 @@ msgstr "Eltern-Bau, dem dieser Bau zugewiesen ist" #: order/templates/order/purchase_order_detail.html:145 #: order/templates/order/receive_parts.html:19 part/models.py:240 #: part/templates/part/part_app_base.html:7 -#: part/templates/part/set_category.html:13 templates/js/bom.html:135 -#: templates/js/build.html:41 templates/js/company.html:109 -#: templates/js/part.html:120 templates/js/stock.html:422 +#: part/templates/part/set_category.html:13 templates/js/barcode.html:336 +#: templates/js/bom.html:135 templates/js/build.html:41 +#: templates/js/company.html:109 templates/js/part.html:120 +#: templates/js/stock.html:424 msgid "Part" msgstr "Teil" @@ -341,7 +342,7 @@ msgstr "Bau-Anzahl" msgid "Number of parts to build" msgstr "Anzahl der zu bauenden Teile" -#: build/models.py:128 part/templates/part/part_base.html:141 +#: build/models.py:128 part/templates/part/part_base.html:139 msgid "Build Status" msgstr "Bau-Status" @@ -360,7 +361,7 @@ msgstr "Chargennummer für diese Bau-Ausgabe" #: build/models.py:155 build/templates/build/detail.html:55 #: company/templates/company/supplier_part_base.html:60 #: company/templates/company/supplier_part_detail.html:24 -#: part/templates/part/detail.html:74 part/templates/part/part_base.html:88 +#: part/templates/part/detail.html:74 part/templates/part/part_base.html:86 #: stock/models.py:368 stock/templates/stock/item_base.html:230 msgid "External Link" msgstr "Externer Link" @@ -369,13 +370,13 @@ msgstr "Externer Link" msgid "Link to external URL" msgstr "Link zu einer externen URL" -#: build/models.py:160 build/templates/build/tabs.html:14 company/models.py:302 +#: build/models.py:160 build/templates/build/tabs.html:14 company/models.py:307 #: company/templates/company/tabs.html:33 order/templates/order/po_tabs.html:15 #: order/templates/order/purchase_order_detail.html:200 -#: order/templates/order/so_tabs.html:23 part/templates/part/tabs.html:73 +#: order/templates/order/so_tabs.html:23 part/templates/part/tabs.html:64 #: stock/models.py:436 stock/models.py:1265 stock/templates/stock/tabs.html:26 -#: templates/js/bom.html:229 templates/js/stock.html:113 -#: templates/js/stock.html:506 +#: templates/js/barcode.html:391 templates/js/bom.html:229 +#: templates/js/stock.html:113 templates/js/stock.html:513 msgid "Notes" msgstr "Notizen" @@ -442,7 +443,7 @@ msgstr "Neues Lagerobjekt" #: build/templates/build/allocate.html:161 #: order/templates/order/sales_order_detail.html:68 #: order/templates/order/sales_order_detail.html:150 stock/models.py:362 -#: stock/templates/stock/item_base.html:189 +#: stock/templates/stock/item_base.html:146 msgid "Serial Number" msgstr "Seriennummer" @@ -459,16 +460,18 @@ msgstr "Seriennummer" #: part/templates/part/allocation.html:49 #: stock/templates/stock/item_base.html:26 #: stock/templates/stock/item_base.html:32 -#: stock/templates/stock/item_base.html:195 -#: stock/templates/stock/stock_adjust.html:18 templates/js/bom.html:172 -#: templates/js/build.html:52 templates/js/stock.html:653 +#: stock/templates/stock/item_base.html:152 +#: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.html:338 +#: templates/js/bom.html:172 templates/js/build.html:52 +#: templates/js/stock.html:660 msgid "Quantity" msgstr "Anzahl" #: build/templates/build/allocate.html:177 #: build/templates/build/auto_allocate.html:20 -#: stock/templates/stock/item_base.html:171 -#: stock/templates/stock/stock_adjust.html:17 templates/js/stock.html:493 +#: stock/templates/stock/item_base.html:184 +#: stock/templates/stock/stock_adjust.html:17 templates/js/barcode.html:337 +#: templates/js/stock.html:495 msgid "Location" msgstr "Standort" @@ -494,7 +497,7 @@ msgstr "Keine BOM-Einträge gefunden" #: templates/js/bom.html:157 templates/js/company.html:60 #: templates/js/order.html:157 templates/js/order.html:230 #: templates/js/part.html:176 templates/js/part.html:355 -#: templates/js/stock.html:443 templates/js/stock.html:634 +#: templates/js/stock.html:445 templates/js/stock.html:641 msgid "Description" msgstr "Beschreibung" @@ -504,8 +507,8 @@ msgstr "Beschreibung" msgid "Reference" msgstr "Referenz" -#: build/templates/build/allocate.html:338 part/models.py:1260 -#: templates/js/part.html:359 templates/js/table_filters.html:63 +#: build/templates/build/allocate.html:338 part/models.py:1269 +#: templates/js/part.html:359 templates/js/table_filters.html:90 msgid "Required" msgstr "benötigt" @@ -569,9 +572,9 @@ msgstr "Bau-Status" #: build/templates/build/build_base.html:80 #: build/templates/build/detail.html:42 #: order/templates/order/receive_parts.html:24 -#: stock/templates/stock/item_base.html:262 templates/js/build.html:57 -#: templates/js/order.html:162 templates/js/order.html:235 -#: templates/js/stock.html:480 +#: stock/templates/stock/item_base.html:262 templates/js/barcode.html:42 +#: templates/js/build.html:57 templates/js/order.html:162 +#: templates/js/order.html:235 templates/js/stock.html:482 msgid "Status" msgstr "Status" @@ -581,7 +584,7 @@ msgstr "Status" #: order/templates/order/sales_order_notes.html:10 #: order/templates/order/sales_order_ship.html:25 #: part/templates/part/allocation.html:27 -#: stock/templates/stock/item_base.html:159 templates/js/order.html:209 +#: stock/templates/stock/item_base.html:172 templates/js/order.html:209 msgid "Sales Order" msgstr "Bestellung" @@ -650,7 +653,7 @@ msgid "Stock can be taken from any available location." msgstr "Bestand kann jedem verfügbaren Lagerort entnommen werden." #: build/templates/build/detail.html:48 -#: stock/templates/stock/item_base.html:202 templates/js/stock.html:488 +#: stock/templates/stock/item_base.html:202 templates/js/stock.html:490 msgid "Batch" msgstr "Los" @@ -875,83 +878,117 @@ msgstr "Währung bearbeiten" msgid "Delete Currency" msgstr "Währung entfernen" -#: company/models.py:83 +#: company/models.py:83 company/models.py:84 msgid "Company name" msgstr "Firmenname" -#: company/models.py:85 +#: company/models.py:86 +#, fuzzy +#| msgid "Part description" +msgid "Company description" +msgstr "Beschreibung des Teils" + +#: company/models.py:86 msgid "Description of the company" msgstr "Firmenbeschreibung" -#: company/models.py:87 +#: company/models.py:88 company/templates/company/company_base.html:48 +#: templates/js/company.html:65 +msgid "Website" +msgstr "Website" + +#: company/models.py:88 msgid "Company website URL" msgstr "Firmenwebsite" -#: company/models.py:90 +#: company/models.py:91 company/templates/company/company_base.html:55 +msgid "Address" +msgstr "Adresse" + +#: company/models.py:92 msgid "Company address" msgstr "Firmenadresse" -#: company/models.py:93 +#: company/models.py:95 +#, fuzzy +#| msgid "Contact phone number" +msgid "Phone number" +msgstr "Kontakt-Tel." + +#: company/models.py:96 msgid "Contact phone number" msgstr "Kontakt-Tel." -#: company/models.py:95 +#: company/models.py:98 company/templates/company/company_base.html:69 +msgid "Email" +msgstr "Email" + +#: company/models.py:98 msgid "Contact email address" msgstr "Kontakt-Email" -#: company/models.py:98 +#: company/models.py:101 company/templates/company/company_base.html:76 +msgid "Contact" +msgstr "Kontakt" + +#: company/models.py:102 msgid "Point of contact" msgstr "Anlaufstelle" -#: company/models.py:100 +#: company/models.py:104 msgid "Link to external company information" msgstr "Link auf externe Firmeninformation" -#: company/models.py:112 +#: company/models.py:116 msgid "Do you sell items to this company?" msgstr "Verkaufen Sie Teile an diese Firma?" -#: company/models.py:114 +#: company/models.py:118 msgid "Do you purchase items from this company?" msgstr "Kaufen Sie Teile von dieser Firma?" -#: company/models.py:116 +#: company/models.py:120 msgid "Does this company manufacture parts?" msgstr "Produziert diese Firma Teile?" -#: company/models.py:276 +#: company/models.py:276 stock/models.py:322 +#: stock/templates/stock/item_base.html:138 +msgid "Base Part" +msgstr "Basisteil" + +#: company/models.py:281 msgid "Select part" msgstr "Teil auswählen" -#: company/models.py:282 +#: company/models.py:287 msgid "Select supplier" msgstr "Zulieferer auswählen" -#: company/models.py:285 +#: company/models.py:290 msgid "Supplier stock keeping unit" msgstr "Stock Keeping Units (SKU) des Zulieferers" -#: company/models.py:292 +#: company/models.py:297 msgid "Select manufacturer" msgstr "Hersteller auswählen" -#: company/models.py:296 +#: company/models.py:301 msgid "Manufacturer part number" msgstr "Hersteller-Teilenummer" -#: company/models.py:298 +#: company/models.py:303 msgid "URL for external supplier part link" msgstr "Teil-URL des Zulieferers" -#: company/models.py:300 +#: company/models.py:305 msgid "Supplier part description" msgstr "Zuliefererbeschreibung des Teils" -#: company/models.py:304 +#: company/models.py:309 msgid "Minimum charge (e.g. stocking fee)" msgstr "Mindestpreis" -#: company/models.py:306 +#: company/models.py:311 msgid "Part packaging" msgstr "Teile-Packaging" @@ -972,26 +1009,10 @@ msgstr "Firma" msgid "Company Details" msgstr "Firmendetails" -#: company/templates/company/company_base.html:48 templates/js/company.html:65 -msgid "Website" -msgstr "Website" - -#: company/templates/company/company_base.html:55 -msgid "Address" -msgstr "Adresse" - #: company/templates/company/company_base.html:62 msgid "Phone" msgstr "Telefon" -#: company/templates/company/company_base.html:69 -msgid "Email" -msgstr "Email" - -#: company/templates/company/company_base.html:76 -msgid "Contact" -msgstr "Kontakt" - #: company/templates/company/detail.html:16 #: company/templates/company/supplier_part_base.html:76 #: company/templates/company/supplier_part_detail.html:30 @@ -1011,7 +1032,7 @@ msgstr "Zulieferer" #: company/templates/company/detail.html:26 order/models.py:314 #: order/templates/order/sales_order_base.html:73 stock/models.py:357 -#: stock/models.py:358 stock/templates/stock/item_base.html:146 +#: stock/models.py:358 stock/templates/stock/item_base.html:159 #: templates/js/company.html:44 templates/js/order.html:217 msgid "Customer" msgstr "Kunde" @@ -1022,7 +1043,7 @@ msgstr "Zulieferer-Teile" #: company/templates/company/detail_part.html:13 #: order/templates/order/purchase_order_detail.html:67 -#: part/templates/part/stock.html:82 part/templates/part/supplier.html:12 +#: part/templates/part/stock.html:81 part/templates/part/supplier.html:12 msgid "New Supplier Part" msgstr "Neues Zulieferer-Teil" @@ -1036,7 +1057,7 @@ msgid "Delete Parts" msgstr "Teile löschen" #: company/templates/company/detail_part.html:43 -#: part/templates/part/stock.html:76 +#: part/templates/part/stock.html:75 msgid "New Part" msgstr "Neues Teil" @@ -1068,7 +1089,7 @@ msgstr "Zuliefererbestand" #: company/templates/company/detail_stock.html:34 #: company/templates/company/supplier_part_stock.html:33 -#: part/templates/part/stock.html:54 templates/stock_table.html:5 +#: part/templates/part/stock.html:53 templates/stock_table.html:5 msgid "Export" msgstr "Exportieren" @@ -1209,12 +1230,12 @@ msgstr "Zuliefererbestand" #: company/templates/company/supplier_part_stock.html:56 #: order/templates/order/purchase_order_detail.html:38 #: order/templates/order/purchase_order_detail.html:118 -#: part/templates/part/stock.html:91 +#: part/templates/part/stock.html:90 msgid "New Location" msgstr "Neuer Standort" #: company/templates/company/supplier_part_stock.html:57 -#: part/templates/part/stock.html:92 +#: part/templates/part/stock.html:91 msgid "Create New Location" msgstr "Neuen Standort anlegen" @@ -1225,7 +1246,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:203 -#: templates/js/stock.html:451 templates/navbar.html:11 +#: templates/js/stock.html:453 templates/navbar.html:11 msgid "Stock" msgstr "Lagerbestand" @@ -1305,7 +1326,7 @@ msgstr "Firma gelöscht" msgid "Edit Supplier Part" msgstr "Zuliefererteil bearbeiten" -#: company/views.py:265 part/templates/part/stock.html:83 +#: company/views.py:265 part/templates/part/stock.html:82 msgid "Create new Supplier Part" msgstr "Neues Zuliefererteil anlegen" @@ -1544,7 +1565,7 @@ msgid "Purchase Order Attachments" msgstr "Bestellanhänge" #: order/templates/order/po_tabs.html:8 order/templates/order/so_tabs.html:16 -#: part/templates/part/tabs.html:70 stock/templates/stock/tabs.html:32 +#: part/templates/part/tabs.html:61 stock/templates/stock/tabs.html:32 msgid "Attachments" msgstr "Anhänge" @@ -1560,7 +1581,7 @@ msgstr "Bestellpositionen" #: order/templates/order/purchase_order_detail.html:39 #: order/templates/order/purchase_order_detail.html:119 -#: stock/templates/stock/location.html:17 +#: stock/templates/stock/location.html:16 msgid "Create new stock location" msgstr "Neuen Lagerort anlegen" @@ -1599,7 +1620,7 @@ msgid "Select parts to receive against this order" msgstr "" #: order/templates/order/receive_parts.html:21 -#: part/templates/part/part_base.html:131 templates/js/part.html:219 +#: part/templates/part/part_base.html:129 templates/js/part.html:219 msgid "On Order" msgstr "bestellt" @@ -1996,13 +2017,13 @@ msgstr "Bemerkungen - unterstüzt Markdown-Formatierung" msgid "Stored BOM checksum" msgstr "Prüfsumme der Stückliste gespeichert" -#: part/models.py:1212 +#: part/models.py:1221 #, 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:1229 +#: part/models.py:1238 #, fuzzy #| msgid "" #| "A stock item with this serial number already exists for template part " @@ -2012,117 +2033,117 @@ msgstr "" "Ein Teil mit dieser Seriennummer existiert bereits für die Teilevorlage " "{part}" -#: part/models.py:1248 templates/js/part.html:350 templates/js/stock.html:89 +#: part/models.py:1257 templates/js/part.html:350 templates/js/stock.html:89 #, fuzzy #| msgid "Instance Name" msgid "Test Name" msgstr "Instanzname" -#: part/models.py:1249 +#: part/models.py:1258 #, fuzzy #| msgid "Serial number for this item" msgid "Enter a name for the test" msgstr "Seriennummer für dieses Teil" -#: part/models.py:1254 +#: part/models.py:1263 #, fuzzy #| msgid "Description" msgid "Test Description" msgstr "Beschreibung" -#: part/models.py:1255 +#: part/models.py:1264 #, fuzzy #| msgid "Brief description of the build" msgid "Enter description for this test" msgstr "Kurze Beschreibung des Baus" -#: part/models.py:1261 +#: part/models.py:1270 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:1266 templates/js/part.html:367 +#: part/models.py:1275 templates/js/part.html:367 #, fuzzy #| msgid "Required Parts" msgid "Requires Value" msgstr "benötigte Teile" -#: part/models.py:1267 +#: part/models.py:1276 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:1272 templates/js/part.html:374 +#: part/models.py:1281 templates/js/part.html:374 #, fuzzy #| msgid "Delete Attachment" msgid "Requires Attachment" msgstr "Anhang löschen" -#: part/models.py:1273 +#: part/models.py:1282 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:1306 +#: part/models.py:1315 msgid "Parameter template name must be unique" msgstr "Vorlagen-Name des Parameters muss eindeutig sein" -#: part/models.py:1311 +#: part/models.py:1320 msgid "Parameter Name" msgstr "Name des Parameters" -#: part/models.py:1313 +#: part/models.py:1322 msgid "Parameter Units" msgstr "Parameter Einheit" -#: part/models.py:1339 +#: part/models.py:1348 msgid "Parent Part" msgstr "Ausgangsteil" -#: part/models.py:1341 +#: part/models.py:1350 msgid "Parameter Template" msgstr "Parameter Vorlage" -#: part/models.py:1343 +#: part/models.py:1352 msgid "Parameter Value" msgstr "Parameter Wert" -#: part/models.py:1372 +#: part/models.py:1381 msgid "Select parent part" msgstr "Ausgangsteil auswählen" -#: part/models.py:1380 +#: part/models.py:1389 msgid "Select part to be used in BOM" msgstr "Teil für die Nutzung in der Stückliste auswählen" -#: part/models.py:1386 +#: part/models.py:1395 msgid "BOM quantity for this BOM item" msgstr "Stücklisten-Anzahl für dieses Stücklisten-Teil" -#: part/models.py:1389 +#: part/models.py:1398 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "Geschätzter Ausschuss (absolut oder prozentual)" -#: part/models.py:1392 +#: part/models.py:1401 msgid "BOM item reference" msgstr "Referenz des Objekts auf der Stückliste" -#: part/models.py:1395 +#: part/models.py:1404 msgid "BOM item notes" msgstr "Notizen zum Stücklisten-Objekt" -#: part/models.py:1397 +#: part/models.py:1406 msgid "BOM line checksum" msgstr "Prüfsumme der Stückliste" -#: part/models.py:1461 stock/models.py:233 +#: part/models.py:1470 stock/models.py:233 #, 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:1470 +#: part/models.py:1479 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:1477 +#: part/models.py:1486 #, 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)" @@ -2144,12 +2165,12 @@ msgstr "Bestellung" #: stock/templates/stock/item_base.html:58 #: stock/templates/stock/item_base.html:224 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.html:106 -#: templates/js/stock.html:623 +#: templates/js/stock.html:630 msgid "Stock Item" msgstr "Lagerobjekt" #: part/templates/part/allocation.html:20 -#: stock/templates/stock/item_base.html:165 +#: stock/templates/stock/item_base.html:178 msgid "Build Order" msgstr "Bauauftrag" @@ -2230,7 +2251,7 @@ msgstr "Teile (inklusive Unter-Kategorien)" msgid "Part Details" msgstr "Teile-Details" -#: part/templates/part/detail.html:25 part/templates/part/part_base.html:81 +#: part/templates/part/detail.html:25 part/templates/part/part_base.html:79 msgid "IPN" msgstr "IPN (Interne Produktnummer)" @@ -2290,7 +2311,7 @@ msgid "Part is not a virtual part" msgstr "Teil ist nicht virtuell" #: part/templates/part/detail.html:139 stock/forms.py:194 -#: templates/js/table_filters.html:122 +#: templates/js/table_filters.html:149 msgid "Template" msgstr "Vorlage" @@ -2306,7 +2327,7 @@ msgstr "Teil kann keine Vorlage sein wenn es Variante eines anderen Teils ist" msgid "Part is not a template part" msgstr "Teil ist nicht virtuell" -#: part/templates/part/detail.html:148 templates/js/table_filters.html:134 +#: part/templates/part/detail.html:148 templates/js/table_filters.html:161 msgid "Assembly" msgstr "Baugruppe" @@ -2318,7 +2339,7 @@ msgstr "Teil kann aus anderen Teilen angefertigt werden" msgid "Part cannot be assembled from other parts" msgstr "Teil kann nicht aus anderen Teilen angefertigt werden" -#: part/templates/part/detail.html:157 templates/js/table_filters.html:138 +#: part/templates/part/detail.html:157 templates/js/table_filters.html:165 msgid "Component" msgstr "Komponente" @@ -2330,7 +2351,7 @@ msgstr "Teil kann in Baugruppen benutzt werden" msgid "Part cannot be used in assemblies" msgstr "Teil kann nicht in Baugruppen benutzt werden" -#: part/templates/part/detail.html:166 templates/js/table_filters.html:150 +#: part/templates/part/detail.html:166 templates/js/table_filters.html:177 msgid "Trackable" msgstr "nachverfolgbar" @@ -2350,7 +2371,7 @@ msgstr "Kaufbar" msgid "Part can be purchased from external suppliers" msgstr "Teil kann von externen Zulieferern gekauft werden" -#: part/templates/part/detail.html:184 templates/js/table_filters.html:146 +#: part/templates/part/detail.html:184 templates/js/table_filters.html:173 msgid "Salable" msgstr "Verkäuflich" @@ -2362,7 +2383,7 @@ msgstr "Teil kann an Kunden verkauft werden" msgid "Part cannot be sold to customers" msgstr "Teil kann nicht an Kunden verkauft werden" -#: part/templates/part/detail.html:193 templates/js/table_filters.html:117 +#: part/templates/part/detail.html:193 templates/js/table_filters.html:144 msgid "Active" msgstr "Aktiv" @@ -2438,35 +2459,81 @@ msgstr "Dieses Teil ist eine Variante von" msgid "Inactive" msgstr "Inaktiv" -#: part/templates/part/part_base.html:41 +#: part/templates/part/part_base.html:39 msgid "Star this part" msgstr "Teil favorisieren" +#: part/templates/part/part_base.html:44 +#: stock/templates/stock/item_base.html:78 +#: stock/templates/stock/location.html:22 +#, fuzzy +#| msgid "Source Location" +msgid "Barcode actions" +msgstr "Quell-Standort" + +#: part/templates/part/part_base.html:46 +#: stock/templates/stock/item_base.html:80 +#: stock/templates/stock/location.html:24 +#, fuzzy +#| msgid "Part QR Code" +msgid "Show QR Code" +msgstr "Teil-QR-Code" + #: part/templates/part/part_base.html:47 +#: stock/templates/stock/item_base.html:81 +#: stock/templates/stock/location.html:25 +msgid "Print Label" +msgstr "" + +#: part/templates/part/part_base.html:51 msgid "Show pricing information" msgstr "Kosteninformationen ansehen" -#: part/templates/part/part_base.html:104 +#: part/templates/part/part_base.html:64 +#, fuzzy +#| msgid "Source Location" +msgid "Part actions" +msgstr "Quell-Standort" + +#: part/templates/part/part_base.html:66 +#, fuzzy +#| msgid "Duplicate Part" +msgid "Duplicate part" +msgstr "Teil duplizieren" + +#: part/templates/part/part_base.html:67 +#, fuzzy +#| msgid "Edit Template" +msgid "Edit part" +msgstr "Vorlage bearbeiten" + +#: part/templates/part/part_base.html:69 +#, fuzzy +#| msgid "Delete Parts" +msgid "Delete part" +msgstr "Teile löschen" + +#: part/templates/part/part_base.html:102 msgid "Available Stock" msgstr "Verfügbarer Lagerbestand" -#: part/templates/part/part_base.html:110 +#: part/templates/part/part_base.html:108 templates/js/table_filters.html:37 msgid "In Stock" msgstr "Auf Lager" -#: part/templates/part/part_base.html:117 +#: part/templates/part/part_base.html:115 msgid "Allocated to Build Orders" msgstr "Zu Bauaufträgen zugeordnet" -#: part/templates/part/part_base.html:124 +#: part/templates/part/part_base.html:122 msgid "Allocated to Sales Orders" msgstr "Zu Aufträgen zugeordnet" -#: part/templates/part/part_base.html:146 +#: part/templates/part/part_base.html:144 msgid "Can Build" msgstr "Herstellbar?" -#: part/templates/part/part_base.html:152 +#: part/templates/part/part_base.html:150 msgid "Underway" msgstr "unterwegs" @@ -2510,7 +2577,7 @@ msgstr "Teil entfernen" msgid "Part Stock" msgstr "Teilbestand" -#: part/templates/part/stock.html:77 +#: part/templates/part/stock.html:76 msgid "Create New Part" msgstr "Neues Teil anlegen" @@ -2563,11 +2630,7 @@ msgstr "Stückliste" msgid "Used In" msgstr "Benutzt in" -#: part/templates/part/tabs.html:57 stock/templates/stock/tabs.html:6 -msgid "Tracking" -msgstr "Tracking" - -#: part/templates/part/tabs.html:64 stock/templates/stock/item_base.html:268 +#: part/templates/part/tabs.html:55 stock/templates/stock/item_base.html:268 msgid "Tests" msgstr "" @@ -2846,10 +2909,6 @@ msgstr "Teil kann nicht zu sich selbst gehören" msgid "Parent Stock Item" msgstr "Eltern-Lagerobjekt" -#: stock/models.py:322 stock/templates/stock/item_base.html:138 -msgid "Base Part" -msgstr "Basisteil" - #: stock/models.py:323 msgid "Base part" msgstr "Basis-Teil" @@ -3009,7 +3068,7 @@ msgstr "Name des Teils" msgid "Result" msgstr "Suchergebnisse" -#: stock/models.py:1247 templates/js/table_filters.html:53 +#: stock/models.py:1247 templates/js/table_filters.html:80 msgid "Test result" msgstr "" @@ -3078,24 +3137,8 @@ msgstr "" "Dieses Lagerobjekt wird automatisch gelöscht wenn der Lagerbestand " "aufgebraucht ist." -#: stock/templates/stock/item_base.html:78 -#, fuzzy -#| msgid "Source Location" -msgid "Barcode actions" -msgstr "Quell-Standort" - -#: stock/templates/stock/item_base.html:80 -#, fuzzy -#| msgid "Part QR Code" -msgid "Show QR Code" -msgstr "Teil-QR-Code" - -#: stock/templates/stock/item_base.html:81 -msgid "Print Label" -msgstr "" - -#: stock/templates/stock/item_base.html:83 templates/js/barcode.html:263 -#: templates/js/barcode.html:268 +#: stock/templates/stock/item_base.html:83 templates/js/barcode.html:283 +#: templates/js/barcode.html:288 msgid "Unlink Barcode" msgstr "" @@ -3109,7 +3152,8 @@ msgstr "" msgid "Stock adjustment actions" msgstr "Bestands-Anpassung bestätigen" -#: stock/templates/stock/item_base.html:95 templates/stock_table.html:14 +#: stock/templates/stock/item_base.html:95 +#: stock/templates/stock/location.html:33 templates/stock_table.html:14 msgid "Count stock" msgstr "Bestand zählen" @@ -3128,6 +3172,7 @@ msgid "Transfer stock" msgstr "Bestand bestellen" #: stock/templates/stock/item_base.html:105 +#: stock/templates/stock/location.html:30 #, fuzzy #| msgid "Stock Locations" msgid "Stock actions" @@ -3177,17 +3222,17 @@ msgstr "" msgid "Stock Item Details" msgstr "Lagerbestands-Details" -#: stock/templates/stock/item_base.html:153 +#: stock/templates/stock/item_base.html:166 msgid "Belongs To" msgstr "Gehört zu" -#: stock/templates/stock/item_base.html:175 +#: stock/templates/stock/item_base.html:188 #, fuzzy #| msgid "No stock location set" msgid "No location set" msgstr "Kein Lagerort gesetzt" -#: stock/templates/stock/item_base.html:182 +#: stock/templates/stock/item_base.html:195 msgid "Unique Identifier" msgstr "Eindeutiger Bezeichner" @@ -3215,6 +3260,12 @@ msgstr "Kind-Lagerobjekte" msgid "This stock item does not have any child items" msgstr "Dieses Lagerobjekt hat keine Kinder" +#: stock/templates/stock/item_delete.html:9 +#, fuzzy +#| msgid "Are you sure you want to delete this attachment?" +msgid "Are you sure you want to delete this stock item?" +msgstr "Sind Sie sicher, dass Sie diesen Anhang löschen wollen?" + #: stock/templates/stock/item_tests.html:10 stock/templates/stock/tabs.html:13 msgid "Test Data" msgstr "" @@ -3237,49 +3288,67 @@ msgstr "" msgid "All stock items" msgstr "Alle Lagerobjekte" -#: stock/templates/stock/location.html:22 -msgid "Count stock items" -msgstr "Lagerobjekte zählen" - -#: stock/templates/stock/location.html:25 -msgid "Edit stock location" -msgstr "Lagerort bearbeiten" - -#: stock/templates/stock/location.html:28 -msgid "Delete stock location" -msgstr "Lagerort löschen" +#: stock/templates/stock/location.html:26 +#, fuzzy +#| msgid "Child Stock Items" +msgid "Check-in Items" +msgstr "Kind-Lagerobjekte" #: stock/templates/stock/location.html:37 +#, fuzzy +#| msgid "Location Description" +msgid "Location actions" +msgstr "Standort-Beschreibung" + +#: stock/templates/stock/location.html:39 +#, fuzzy +#| msgid "Edit stock location" +msgid "Edit location" +msgstr "Lagerort bearbeiten" + +#: stock/templates/stock/location.html:40 +#, fuzzy +#| msgid "Delete stock location" +msgid "Delete location" +msgstr "Lagerort löschen" + +#: stock/templates/stock/location.html:48 msgid "Location Details" msgstr "Standort-Details" -#: stock/templates/stock/location.html:42 +#: stock/templates/stock/location.html:53 msgid "Location Path" msgstr "Standord-Pfad" -#: stock/templates/stock/location.html:47 +#: stock/templates/stock/location.html:58 msgid "Location Description" msgstr "Standort-Beschreibung" -#: stock/templates/stock/location.html:52 +#: stock/templates/stock/location.html:63 msgid "Sublocations" msgstr "Sub-Standorte" -#: stock/templates/stock/location.html:57 -#: stock/templates/stock/location.html:72 templates/stats.html:21 +#: stock/templates/stock/location.html:68 +#: stock/templates/stock/location.html:83 templates/stats.html:21 #: templates/stats.html:30 msgid "Stock Items" msgstr "Lagerobjekte" -#: stock/templates/stock/location.html:62 +#: stock/templates/stock/location.html:73 msgid "Stock Details" msgstr "Objekt-Details" -#: stock/templates/stock/location.html:67 +#: stock/templates/stock/location.html:78 #: templates/InvenTree/search_stock_location.html:6 templates/stats.html:25 msgid "Stock Locations" msgstr "Lagerobjekt-Standorte" +#: stock/templates/stock/location_delete.html:7 +#, fuzzy +#| msgid "Are you sure you want to delete this attachment?" +msgid "Are you sure you want to delete this stock location?" +msgstr "Sind Sie sicher, dass Sie diesen Anhang löschen wollen?" + #: stock/templates/stock/stockitem_convert.html:7 stock/views.py:934 #, fuzzy #| msgid "Count Stock Items" @@ -3300,6 +3369,10 @@ msgstr "" msgid "This action cannot be easily undone" msgstr "" +#: stock/templates/stock/tabs.html:6 +msgid "Tracking" +msgstr "Tracking" + #: stock/templates/stock/tabs.html:21 msgid "Builds" msgstr "Baue" @@ -3603,49 +3676,109 @@ msgstr "" msgid "Delete attachment" msgstr "Anhang löschen" -#: templates/js/barcode.html:28 +#: templates/js/barcode.html:8 #, fuzzy #| msgid "No barcode data provided" msgid "Scan barcode data here using wedge scanner" msgstr "Keine Strichcodedaten bereitgestellt" -#: templates/js/barcode.html:34 +#: templates/js/barcode.html:12 #, fuzzy #| msgid "Source Location" msgid "Barcode" msgstr "Quell-Standort" -#: templates/js/barcode.html:42 +#: templates/js/barcode.html:20 #, fuzzy #| msgid "No barcode data provided" msgid "Enter barcode data" msgstr "Keine Strichcodedaten bereitgestellt" -#: templates/js/barcode.html:140 +#: templates/js/barcode.html:42 +msgid "Invalid server response" +msgstr "" + +#: templates/js/barcode.html:143 #, fuzzy #| msgid "No barcode data provided" msgid "Scan barcode data below" msgstr "Keine Strichcodedaten bereitgestellt" -#: templates/js/barcode.html:195 templates/js/barcode.html:243 +#: templates/js/barcode.html:217 templates/js/barcode.html:263 #, fuzzy #| msgid "Unknown barcode format" msgid "Unknown response from server" msgstr "Unbekanntes Strichcode-Format" -#: templates/js/barcode.html:198 templates/js/barcode.html:247 -msgid "Invalid server response" -msgstr "" +#: templates/js/barcode.html:239 +#, fuzzy +#| msgid "Parent Stock Item" +msgid "Link Barcode to Stock Item" +msgstr "Eltern-Lagerobjekt" -#: templates/js/barcode.html:265 +#: templates/js/barcode.html:285 msgid "" "This will remove the association between this stock item and the barcode" msgstr "" -#: templates/js/barcode.html:271 +#: templates/js/barcode.html:291 msgid "Unlink" msgstr "" +#: templates/js/barcode.html:350 +#, fuzzy +#| msgid "Remove stock" +msgid "Remove stock item" +msgstr "Bestand entfernen" + +#: templates/js/barcode.html:397 +#, fuzzy +#| msgid "Entry notes" +msgid "Enter notes" +msgstr "Eintrags-Notizen" + +#: templates/js/barcode.html:399 +msgid "Enter optional notes for stock transfer" +msgstr "" + +#: templates/js/barcode.html:404 +#, fuzzy +#| msgid "Include stock items in sub locations" +msgid "Check Stock Items into Location" +msgstr "Lagerobjekte in untergeordneten Lagerorten einschließen" + +#: templates/js/barcode.html:408 +msgid "Check In" +msgstr "" + +#: templates/js/barcode.html:466 +msgid "Server error" +msgstr "" + +#: templates/js/barcode.html:485 +#, fuzzy +#| msgid "Stock Item Details" +msgid "Stock Item already scanned" +msgstr "Lagerbestands-Details" + +#: templates/js/barcode.html:489 +#, fuzzy +#| msgid "Include stock items in sub locations" +msgid "Stock Item already in this location" +msgstr "Lagerobjekte in untergeordneten Lagerorten einschließen" + +#: templates/js/barcode.html:496 +#, fuzzy +#| msgid "Added stock to {n} items" +msgid "Added stock item" +msgstr "Vorrat zu {n} Lagerobjekten hinzugefügt" + +#: templates/js/barcode.html:503 +#, fuzzy +#| msgid "Create new Stock Item" +msgid "Barcode does not match Stock Item" +msgstr "Neues Lagerobjekt hinzufügen" + #: templates/js/bom.html:143 msgid "Open subassembly" msgstr "Unterbaugruppe öffnen" @@ -3706,7 +3839,7 @@ msgstr "Link" msgid "No purchase orders found" msgstr "Keine Bestellungen gefunden" -#: templates/js/order.html:170 templates/js/stock.html:605 +#: templates/js/order.html:170 templates/js/stock.html:612 msgid "Date" msgstr "Datum" @@ -3718,7 +3851,7 @@ msgstr "Keine Aufträge gefunden" msgid "Shipment Date" msgstr "Versanddatum" -#: templates/js/part.html:106 templates/js/stock.html:403 +#: templates/js/part.html:106 templates/js/stock.html:405 msgid "Select" msgstr "Auswählen" @@ -3734,7 +3867,7 @@ msgstr "Verkäufliches Teil" msgid "No category" msgstr "Keine Kategorie" -#: templates/js/part.html:214 templates/js/table_filters.html:130 +#: templates/js/part.html:214 templates/js/table_filters.html:157 msgid "Low stock" msgstr "Bestand niedrig" @@ -3806,119 +3939,135 @@ msgstr "Keine Ergebnisse gefunden" msgid "Test Date" msgstr "Versanddatum" -#: templates/js/stock.html:258 +#: templates/js/stock.html:260 msgid "No stock items matching query" msgstr "Keine zur Anfrage passenden Lagerobjekte" -#: templates/js/stock.html:355 templates/js/stock.html:370 +#: templates/js/stock.html:357 templates/js/stock.html:372 #, fuzzy #| msgid "Include sublocations" msgid "Undefined location" msgstr "Unterlagerorte einschließen" -#: templates/js/stock.html:467 +#: templates/js/stock.html:469 msgid "StockItem has been allocated" msgstr "Lagerobjekt wurde zugewiesen" -#: templates/js/stock.html:472 +#: templates/js/stock.html:474 msgid "StockItem is lost" msgstr "Lagerobjekt verloren" -#: templates/js/stock.html:500 +#: templates/js/stock.html:503 +#, fuzzy +#| msgid "Item assigned to customer?" +msgid "Shipped to customer" +msgstr "Ist dieses Objekt einem Kunden zugeteilt?" + +#: templates/js/stock.html:506 msgid "No stock location set" msgstr "Kein Lagerort gesetzt" -#: templates/js/stock.html:671 +#: templates/js/stock.html:678 msgid "No user information" msgstr "Keine Benutzerinformation" -#: templates/js/table_filters.html:19 -msgid "Include sublocations" -msgstr "Unterlagerorte einschließen" +#: templates/js/table_filters.html:19 templates/js/table_filters.html:62 +#, fuzzy +#| msgid "Serialize Stock" +msgid "Is Serialized" +msgstr "Lagerbestand erfassen" -#: templates/js/table_filters.html:20 -msgid "Include stock in sublocations" -msgstr "Bestand in Unterlagerorten einschließen" - -#: templates/js/table_filters.html:24 -msgid "Active parts" -msgstr "Aktive Teile" - -#: templates/js/table_filters.html:25 -msgid "Show stock for active parts" -msgstr "Bestand aktiver Teile anzeigen" - -#: templates/js/table_filters.html:29 templates/js/table_filters.html:30 -msgid "Stock status" -msgstr "Bestandsstatus" - -#: templates/js/table_filters.html:34 -msgid "Is allocated" -msgstr "Ist zugeordnet" - -#: templates/js/table_filters.html:35 -msgid "Item has been alloacted" -msgstr "Position wurde zugeordnet" - -#: templates/js/table_filters.html:38 +#: templates/js/table_filters.html:22 templates/js/table_filters.html:65 #, fuzzy #| msgid "Serial Number" msgid "Serial number GTE" msgstr "Seriennummer" -#: templates/js/table_filters.html:39 +#: templates/js/table_filters.html:23 templates/js/table_filters.html:66 #, fuzzy #| msgid "Serial number for this item" msgid "Serial number greater than or equal to" msgstr "Seriennummer für dieses Teil" -#: templates/js/table_filters.html:42 +#: templates/js/table_filters.html:26 templates/js/table_filters.html:69 #, fuzzy #| msgid "Serial Number" msgid "Serial number LTE" msgstr "Seriennummer" -#: templates/js/table_filters.html:43 +#: templates/js/table_filters.html:27 templates/js/table_filters.html:70 #, fuzzy #| msgid "Serial numbers already exist: " msgid "Serial number less than or equal to" msgstr "Seriennummern existieren bereits:" -#: templates/js/table_filters.html:72 +#: templates/js/table_filters.html:38 +msgid "Show items which are in stock" +msgstr "" + +#: templates/js/table_filters.html:42 +msgid "Include sublocations" +msgstr "Unterlagerorte einschließen" + +#: templates/js/table_filters.html:43 +msgid "Include stock in sublocations" +msgstr "Bestand in Unterlagerorten einschließen" + +#: templates/js/table_filters.html:47 +msgid "Active parts" +msgstr "Aktive Teile" + +#: templates/js/table_filters.html:48 +msgid "Show stock for active parts" +msgstr "Bestand aktiver Teile anzeigen" + +#: templates/js/table_filters.html:52 templates/js/table_filters.html:53 +msgid "Stock status" +msgstr "Bestandsstatus" + +#: templates/js/table_filters.html:57 +msgid "Is allocated" +msgstr "Ist zugeordnet" + +#: templates/js/table_filters.html:58 +msgid "Item has been alloacted" +msgstr "Position wurde zugeordnet" + +#: templates/js/table_filters.html:99 msgid "Build status" msgstr "Bau-Status" -#: templates/js/table_filters.html:84 templates/js/table_filters.html:97 +#: templates/js/table_filters.html:111 templates/js/table_filters.html:124 msgid "Order status" msgstr "Bestellstatus" -#: templates/js/table_filters.html:89 templates/js/table_filters.html:102 +#: templates/js/table_filters.html:116 templates/js/table_filters.html:129 #, fuzzy #| msgid "Cascading" msgid "Outstanding" msgstr "Kaskadierend" -#: templates/js/table_filters.html:112 +#: templates/js/table_filters.html:139 msgid "Include subcategories" msgstr "Unterkategorien einschließen" -#: templates/js/table_filters.html:113 +#: templates/js/table_filters.html:140 msgid "Include parts in subcategories" msgstr "Teile in Unterkategorien einschließen" -#: templates/js/table_filters.html:118 +#: templates/js/table_filters.html:145 msgid "Show active parts" msgstr "Aktive Teile anzeigen" -#: templates/js/table_filters.html:126 +#: templates/js/table_filters.html:153 msgid "Stock available" msgstr "Bestand verfügbar" -#: templates/js/table_filters.html:142 +#: templates/js/table_filters.html:169 msgid "Starred" msgstr "Favorit" -#: templates/js/table_filters.html:154 +#: templates/js/table_filters.html:181 msgid "Purchasable" msgstr "Käuflich" @@ -3974,6 +4123,9 @@ msgstr "Bestand bestellen" msgid "Delete Stock" msgstr "Bestand löschen" +#~ msgid "Count stock items" +#~ msgstr "Lagerobjekte zählen" + #~ msgid "Barcode successfully decoded" #~ msgstr "Strichcode erfolgreich dekodiert" diff --git a/InvenTree/locale/en/LC_MESSAGES/django.po b/InvenTree/locale/en/LC_MESSAGES/django.po index c539fbcae5..972a9ee6af 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-06-12 00:43+0000\n" +"POT-Creation-Date: 2020-07-30 10:24+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -78,7 +78,7 @@ msgstr "" msgid "File comment" msgstr "" -#: InvenTree/models.py:68 templates/js/stock.html:662 +#: InvenTree/models.py:68 templates/js/stock.html:669 msgid "User" msgstr "" @@ -286,9 +286,10 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:145 #: order/templates/order/receive_parts.html:19 part/models.py:240 #: part/templates/part/part_app_base.html:7 -#: part/templates/part/set_category.html:13 templates/js/bom.html:135 -#: templates/js/build.html:41 templates/js/company.html:109 -#: templates/js/part.html:120 templates/js/stock.html:422 +#: part/templates/part/set_category.html:13 templates/js/barcode.html:336 +#: templates/js/bom.html:135 templates/js/build.html:41 +#: templates/js/company.html:109 templates/js/part.html:120 +#: templates/js/stock.html:424 msgid "Part" msgstr "" @@ -322,7 +323,7 @@ msgstr "" msgid "Number of parts to build" msgstr "" -#: build/models.py:128 part/templates/part/part_base.html:141 +#: build/models.py:128 part/templates/part/part_base.html:139 msgid "Build Status" msgstr "" @@ -341,7 +342,7 @@ msgstr "" #: build/models.py:155 build/templates/build/detail.html:55 #: company/templates/company/supplier_part_base.html:60 #: company/templates/company/supplier_part_detail.html:24 -#: part/templates/part/detail.html:74 part/templates/part/part_base.html:88 +#: part/templates/part/detail.html:74 part/templates/part/part_base.html:86 #: stock/models.py:368 stock/templates/stock/item_base.html:230 msgid "External Link" msgstr "" @@ -350,13 +351,13 @@ msgstr "" msgid "Link to external URL" msgstr "" -#: build/models.py:160 build/templates/build/tabs.html:14 company/models.py:302 +#: build/models.py:160 build/templates/build/tabs.html:14 company/models.py:307 #: company/templates/company/tabs.html:33 order/templates/order/po_tabs.html:15 #: order/templates/order/purchase_order_detail.html:200 -#: order/templates/order/so_tabs.html:23 part/templates/part/tabs.html:73 +#: order/templates/order/so_tabs.html:23 part/templates/part/tabs.html:64 #: stock/models.py:436 stock/models.py:1265 stock/templates/stock/tabs.html:26 -#: templates/js/bom.html:229 templates/js/stock.html:113 -#: templates/js/stock.html:506 +#: templates/js/barcode.html:391 templates/js/bom.html:229 +#: templates/js/stock.html:113 templates/js/stock.html:513 msgid "Notes" msgstr "" @@ -422,7 +423,7 @@ msgstr "" #: build/templates/build/allocate.html:161 #: order/templates/order/sales_order_detail.html:68 #: order/templates/order/sales_order_detail.html:150 stock/models.py:362 -#: stock/templates/stock/item_base.html:189 +#: stock/templates/stock/item_base.html:146 msgid "Serial Number" msgstr "" @@ -439,16 +440,18 @@ msgstr "" #: part/templates/part/allocation.html:49 #: stock/templates/stock/item_base.html:26 #: stock/templates/stock/item_base.html:32 -#: stock/templates/stock/item_base.html:195 -#: stock/templates/stock/stock_adjust.html:18 templates/js/bom.html:172 -#: templates/js/build.html:52 templates/js/stock.html:653 +#: stock/templates/stock/item_base.html:152 +#: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.html:338 +#: templates/js/bom.html:172 templates/js/build.html:52 +#: templates/js/stock.html:660 msgid "Quantity" msgstr "" #: build/templates/build/allocate.html:177 #: build/templates/build/auto_allocate.html:20 -#: stock/templates/stock/item_base.html:171 -#: stock/templates/stock/stock_adjust.html:17 templates/js/stock.html:493 +#: stock/templates/stock/item_base.html:184 +#: stock/templates/stock/stock_adjust.html:17 templates/js/barcode.html:337 +#: templates/js/stock.html:495 msgid "Location" msgstr "" @@ -474,7 +477,7 @@ msgstr "" #: templates/js/bom.html:157 templates/js/company.html:60 #: templates/js/order.html:157 templates/js/order.html:230 #: templates/js/part.html:176 templates/js/part.html:355 -#: templates/js/stock.html:443 templates/js/stock.html:634 +#: templates/js/stock.html:445 templates/js/stock.html:641 msgid "Description" msgstr "" @@ -484,8 +487,8 @@ msgstr "" msgid "Reference" msgstr "" -#: build/templates/build/allocate.html:338 part/models.py:1260 -#: templates/js/part.html:359 templates/js/table_filters.html:63 +#: build/templates/build/allocate.html:338 part/models.py:1269 +#: templates/js/part.html:359 templates/js/table_filters.html:90 msgid "Required" msgstr "" @@ -548,9 +551,9 @@ msgstr "" #: build/templates/build/build_base.html:80 #: build/templates/build/detail.html:42 #: order/templates/order/receive_parts.html:24 -#: stock/templates/stock/item_base.html:262 templates/js/build.html:57 -#: templates/js/order.html:162 templates/js/order.html:235 -#: templates/js/stock.html:480 +#: stock/templates/stock/item_base.html:262 templates/js/barcode.html:42 +#: templates/js/build.html:57 templates/js/order.html:162 +#: templates/js/order.html:235 templates/js/stock.html:482 msgid "Status" msgstr "" @@ -560,7 +563,7 @@ msgstr "" #: order/templates/order/sales_order_notes.html:10 #: order/templates/order/sales_order_ship.html:25 #: part/templates/part/allocation.html:27 -#: stock/templates/stock/item_base.html:159 templates/js/order.html:209 +#: stock/templates/stock/item_base.html:172 templates/js/order.html:209 msgid "Sales Order" msgstr "" @@ -627,7 +630,7 @@ msgid "Stock can be taken from any available location." msgstr "" #: build/templates/build/detail.html:48 -#: stock/templates/stock/item_base.html:202 templates/js/stock.html:488 +#: stock/templates/stock/item_base.html:202 templates/js/stock.html:490 msgid "Batch" msgstr "" @@ -847,83 +850,113 @@ msgstr "" msgid "Delete Currency" msgstr "" -#: company/models.py:83 +#: company/models.py:83 company/models.py:84 msgid "Company name" msgstr "" -#: company/models.py:85 +#: company/models.py:86 +msgid "Company description" +msgstr "" + +#: company/models.py:86 msgid "Description of the company" msgstr "" -#: company/models.py:87 +#: company/models.py:88 company/templates/company/company_base.html:48 +#: templates/js/company.html:65 +msgid "Website" +msgstr "" + +#: company/models.py:88 msgid "Company website URL" msgstr "" -#: company/models.py:90 +#: company/models.py:91 company/templates/company/company_base.html:55 +msgid "Address" +msgstr "" + +#: company/models.py:92 msgid "Company address" msgstr "" -#: company/models.py:93 +#: company/models.py:95 +msgid "Phone number" +msgstr "" + +#: company/models.py:96 msgid "Contact phone number" msgstr "" -#: company/models.py:95 -msgid "Contact email address" +#: company/models.py:98 company/templates/company/company_base.html:69 +msgid "Email" msgstr "" #: company/models.py:98 +msgid "Contact email address" +msgstr "" + +#: company/models.py:101 company/templates/company/company_base.html:76 +msgid "Contact" +msgstr "" + +#: company/models.py:102 msgid "Point of contact" msgstr "" -#: company/models.py:100 +#: company/models.py:104 msgid "Link to external company information" msgstr "" -#: company/models.py:112 +#: company/models.py:116 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:114 +#: company/models.py:118 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:116 +#: company/models.py:120 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:276 +#: company/models.py:276 stock/models.py:322 +#: stock/templates/stock/item_base.html:138 +msgid "Base Part" +msgstr "" + +#: company/models.py:281 msgid "Select part" msgstr "" -#: company/models.py:282 +#: company/models.py:287 msgid "Select supplier" msgstr "" -#: company/models.py:285 +#: company/models.py:290 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:292 +#: company/models.py:297 msgid "Select manufacturer" msgstr "" -#: company/models.py:296 +#: company/models.py:301 msgid "Manufacturer part number" msgstr "" -#: company/models.py:298 +#: company/models.py:303 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:300 +#: company/models.py:305 msgid "Supplier part description" msgstr "" -#: company/models.py:304 +#: company/models.py:309 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:306 +#: company/models.py:311 msgid "Part packaging" msgstr "" @@ -942,26 +975,10 @@ msgstr "" msgid "Company Details" msgstr "" -#: company/templates/company/company_base.html:48 templates/js/company.html:65 -msgid "Website" -msgstr "" - -#: company/templates/company/company_base.html:55 -msgid "Address" -msgstr "" - #: company/templates/company/company_base.html:62 msgid "Phone" msgstr "" -#: company/templates/company/company_base.html:69 -msgid "Email" -msgstr "" - -#: company/templates/company/company_base.html:76 -msgid "Contact" -msgstr "" - #: company/templates/company/detail.html:16 #: company/templates/company/supplier_part_base.html:76 #: company/templates/company/supplier_part_detail.html:30 @@ -981,7 +998,7 @@ msgstr "" #: company/templates/company/detail.html:26 order/models.py:314 #: order/templates/order/sales_order_base.html:73 stock/models.py:357 -#: stock/models.py:358 stock/templates/stock/item_base.html:146 +#: stock/models.py:358 stock/templates/stock/item_base.html:159 #: templates/js/company.html:44 templates/js/order.html:217 msgid "Customer" msgstr "" @@ -992,7 +1009,7 @@ msgstr "" #: company/templates/company/detail_part.html:13 #: order/templates/order/purchase_order_detail.html:67 -#: part/templates/part/stock.html:82 part/templates/part/supplier.html:12 +#: part/templates/part/stock.html:81 part/templates/part/supplier.html:12 msgid "New Supplier Part" msgstr "" @@ -1006,7 +1023,7 @@ msgid "Delete Parts" msgstr "" #: company/templates/company/detail_part.html:43 -#: part/templates/part/stock.html:76 +#: part/templates/part/stock.html:75 msgid "New Part" msgstr "" @@ -1038,7 +1055,7 @@ msgstr "" #: company/templates/company/detail_stock.html:34 #: company/templates/company/supplier_part_stock.html:33 -#: part/templates/part/stock.html:54 templates/stock_table.html:5 +#: part/templates/part/stock.html:53 templates/stock_table.html:5 msgid "Export" msgstr "" @@ -1178,12 +1195,12 @@ msgstr "" #: company/templates/company/supplier_part_stock.html:56 #: order/templates/order/purchase_order_detail.html:38 #: order/templates/order/purchase_order_detail.html:118 -#: part/templates/part/stock.html:91 +#: part/templates/part/stock.html:90 msgid "New Location" msgstr "" #: company/templates/company/supplier_part_stock.html:57 -#: part/templates/part/stock.html:92 +#: part/templates/part/stock.html:91 msgid "Create New Location" msgstr "" @@ -1194,7 +1211,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:203 -#: templates/js/stock.html:451 templates/navbar.html:11 +#: templates/js/stock.html:453 templates/navbar.html:11 msgid "Stock" msgstr "" @@ -1274,7 +1291,7 @@ msgstr "" msgid "Edit Supplier Part" msgstr "" -#: company/views.py:265 part/templates/part/stock.html:83 +#: company/views.py:265 part/templates/part/stock.html:82 msgid "Create new Supplier Part" msgstr "" @@ -1508,7 +1525,7 @@ msgid "Purchase Order Attachments" msgstr "" #: order/templates/order/po_tabs.html:8 order/templates/order/so_tabs.html:16 -#: part/templates/part/tabs.html:70 stock/templates/stock/tabs.html:32 +#: part/templates/part/tabs.html:61 stock/templates/stock/tabs.html:32 msgid "Attachments" msgstr "" @@ -1524,7 +1541,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:39 #: order/templates/order/purchase_order_detail.html:119 -#: stock/templates/stock/location.html:17 +#: stock/templates/stock/location.html:16 msgid "Create new stock location" msgstr "" @@ -1563,7 +1580,7 @@ msgid "Select parts to receive against this order" msgstr "" #: order/templates/order/receive_parts.html:21 -#: part/templates/part/part_base.html:131 templates/js/part.html:219 +#: part/templates/part/part_base.html:129 templates/js/part.html:219 msgid "On Order" msgstr "" @@ -1952,111 +1969,111 @@ msgstr "" msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1212 +#: part/models.py:1221 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:1229 +#: part/models.py:1238 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:1248 templates/js/part.html:350 templates/js/stock.html:89 +#: part/models.py:1257 templates/js/part.html:350 templates/js/stock.html:89 msgid "Test Name" msgstr "" -#: part/models.py:1249 +#: part/models.py:1258 msgid "Enter a name for the test" msgstr "" -#: part/models.py:1254 +#: part/models.py:1263 msgid "Test Description" msgstr "" -#: part/models.py:1255 +#: part/models.py:1264 msgid "Enter description for this test" msgstr "" -#: part/models.py:1261 +#: part/models.py:1270 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:1266 templates/js/part.html:367 +#: part/models.py:1275 templates/js/part.html:367 msgid "Requires Value" msgstr "" -#: part/models.py:1267 +#: part/models.py:1276 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:1272 templates/js/part.html:374 +#: part/models.py:1281 templates/js/part.html:374 msgid "Requires Attachment" msgstr "" -#: part/models.py:1273 +#: part/models.py:1282 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:1306 +#: part/models.py:1315 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:1311 +#: part/models.py:1320 msgid "Parameter Name" msgstr "" -#: part/models.py:1313 +#: part/models.py:1322 msgid "Parameter Units" msgstr "" -#: part/models.py:1339 +#: part/models.py:1348 msgid "Parent Part" msgstr "" -#: part/models.py:1341 +#: part/models.py:1350 msgid "Parameter Template" msgstr "" -#: part/models.py:1343 +#: part/models.py:1352 msgid "Parameter Value" msgstr "" -#: part/models.py:1372 +#: part/models.py:1381 msgid "Select parent part" msgstr "" -#: part/models.py:1380 +#: part/models.py:1389 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:1386 +#: part/models.py:1395 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:1389 +#: part/models.py:1398 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:1392 +#: part/models.py:1401 msgid "BOM item reference" msgstr "" -#: part/models.py:1395 +#: part/models.py:1404 msgid "BOM item notes" msgstr "" -#: part/models.py:1397 +#: part/models.py:1406 msgid "BOM line checksum" msgstr "" -#: part/models.py:1461 stock/models.py:233 +#: part/models.py:1470 stock/models.py:233 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:1470 +#: part/models.py:1479 msgid "Part cannot be added to its own Bill of Materials" msgstr "" -#: part/models.py:1477 +#: part/models.py:1486 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" @@ -2078,12 +2095,12 @@ msgstr "" #: stock/templates/stock/item_base.html:58 #: stock/templates/stock/item_base.html:224 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.html:106 -#: templates/js/stock.html:623 +#: templates/js/stock.html:630 msgid "Stock Item" msgstr "" #: part/templates/part/allocation.html:20 -#: stock/templates/stock/item_base.html:165 +#: stock/templates/stock/item_base.html:178 msgid "Build Order" msgstr "" @@ -2164,7 +2181,7 @@ msgstr "" msgid "Part Details" msgstr "" -#: part/templates/part/detail.html:25 part/templates/part/part_base.html:81 +#: part/templates/part/detail.html:25 part/templates/part/part_base.html:79 msgid "IPN" msgstr "" @@ -2222,7 +2239,7 @@ msgid "Part is not a virtual part" msgstr "" #: part/templates/part/detail.html:139 stock/forms.py:194 -#: templates/js/table_filters.html:122 +#: templates/js/table_filters.html:149 msgid "Template" msgstr "" @@ -2234,7 +2251,7 @@ msgstr "" msgid "Part is not a template part" msgstr "" -#: part/templates/part/detail.html:148 templates/js/table_filters.html:134 +#: part/templates/part/detail.html:148 templates/js/table_filters.html:161 msgid "Assembly" msgstr "" @@ -2246,7 +2263,7 @@ msgstr "" msgid "Part cannot be assembled from other parts" msgstr "" -#: part/templates/part/detail.html:157 templates/js/table_filters.html:138 +#: part/templates/part/detail.html:157 templates/js/table_filters.html:165 msgid "Component" msgstr "" @@ -2258,7 +2275,7 @@ msgstr "" msgid "Part cannot be used in assemblies" msgstr "" -#: part/templates/part/detail.html:166 templates/js/table_filters.html:150 +#: part/templates/part/detail.html:166 templates/js/table_filters.html:177 msgid "Trackable" msgstr "" @@ -2278,7 +2295,7 @@ msgstr "" msgid "Part can be purchased from external suppliers" msgstr "" -#: part/templates/part/detail.html:184 templates/js/table_filters.html:146 +#: part/templates/part/detail.html:184 templates/js/table_filters.html:173 msgid "Salable" msgstr "" @@ -2290,7 +2307,7 @@ msgstr "" msgid "Part cannot be sold to customers" msgstr "" -#: part/templates/part/detail.html:193 templates/js/table_filters.html:117 +#: part/templates/part/detail.html:193 templates/js/table_filters.html:144 msgid "Active" msgstr "" @@ -2360,35 +2377,69 @@ msgstr "" msgid "Inactive" msgstr "" -#: part/templates/part/part_base.html:41 +#: part/templates/part/part_base.html:39 msgid "Star this part" msgstr "" +#: part/templates/part/part_base.html:44 +#: stock/templates/stock/item_base.html:78 +#: stock/templates/stock/location.html:22 +msgid "Barcode actions" +msgstr "" + +#: part/templates/part/part_base.html:46 +#: stock/templates/stock/item_base.html:80 +#: stock/templates/stock/location.html:24 +msgid "Show QR Code" +msgstr "" + #: part/templates/part/part_base.html:47 +#: stock/templates/stock/item_base.html:81 +#: stock/templates/stock/location.html:25 +msgid "Print Label" +msgstr "" + +#: part/templates/part/part_base.html:51 msgid "Show pricing information" msgstr "" -#: part/templates/part/part_base.html:104 +#: part/templates/part/part_base.html:64 +msgid "Part actions" +msgstr "" + +#: part/templates/part/part_base.html:66 +msgid "Duplicate part" +msgstr "" + +#: part/templates/part/part_base.html:67 +msgid "Edit part" +msgstr "" + +#: part/templates/part/part_base.html:69 +msgid "Delete part" +msgstr "" + +#: part/templates/part/part_base.html:102 msgid "Available Stock" msgstr "" -#: part/templates/part/part_base.html:110 +#: part/templates/part/part_base.html:108 templates/js/table_filters.html:37 msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:117 +#: part/templates/part/part_base.html:115 msgid "Allocated to Build Orders" msgstr "" -#: part/templates/part/part_base.html:124 +#: part/templates/part/part_base.html:122 msgid "Allocated to Sales Orders" msgstr "" -#: part/templates/part/part_base.html:146 +#: part/templates/part/part_base.html:144 msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:152 +#: part/templates/part/part_base.html:150 msgid "Underway" msgstr "" @@ -2428,7 +2479,7 @@ msgstr "" msgid "Part Stock" msgstr "" -#: part/templates/part/stock.html:77 +#: part/templates/part/stock.html:76 msgid "Create New Part" msgstr "" @@ -2473,11 +2524,7 @@ msgstr "" msgid "Used In" msgstr "" -#: part/templates/part/tabs.html:57 stock/templates/stock/tabs.html:6 -msgid "Tracking" -msgstr "" - -#: part/templates/part/tabs.html:64 stock/templates/stock/item_base.html:268 +#: part/templates/part/tabs.html:55 stock/templates/stock/item_base.html:268 msgid "Tests" msgstr "" @@ -2739,10 +2786,6 @@ msgstr "" msgid "Parent Stock Item" msgstr "" -#: stock/models.py:322 stock/templates/stock/item_base.html:138 -msgid "Base Part" -msgstr "" - #: stock/models.py:323 msgid "Base part" msgstr "" @@ -2890,7 +2933,7 @@ msgstr "" msgid "Result" msgstr "" -#: stock/models.py:1247 templates/js/table_filters.html:53 +#: stock/models.py:1247 templates/js/table_filters.html:80 msgid "Test result" msgstr "" @@ -2945,20 +2988,8 @@ msgid "" "This stock item will be automatically deleted when all stock is depleted." msgstr "" -#: stock/templates/stock/item_base.html:78 -msgid "Barcode actions" -msgstr "" - -#: stock/templates/stock/item_base.html:80 -msgid "Show QR Code" -msgstr "" - -#: stock/templates/stock/item_base.html:81 -msgid "Print Label" -msgstr "" - -#: stock/templates/stock/item_base.html:83 templates/js/barcode.html:263 -#: templates/js/barcode.html:268 +#: stock/templates/stock/item_base.html:83 templates/js/barcode.html:283 +#: templates/js/barcode.html:288 msgid "Unlink Barcode" msgstr "" @@ -2970,7 +3001,8 @@ msgstr "" msgid "Stock adjustment actions" msgstr "" -#: stock/templates/stock/item_base.html:95 templates/stock_table.html:14 +#: stock/templates/stock/item_base.html:95 +#: stock/templates/stock/location.html:33 templates/stock_table.html:14 msgid "Count stock" msgstr "" @@ -2987,6 +3019,7 @@ msgid "Transfer stock" msgstr "" #: stock/templates/stock/item_base.html:105 +#: stock/templates/stock/location.html:30 msgid "Stock actions" msgstr "" @@ -3022,15 +3055,15 @@ msgstr "" msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:153 +#: stock/templates/stock/item_base.html:166 msgid "Belongs To" msgstr "" -#: stock/templates/stock/item_base.html:175 +#: stock/templates/stock/item_base.html:188 msgid "No location set" msgstr "" -#: stock/templates/stock/item_base.html:182 +#: stock/templates/stock/item_base.html:195 msgid "Unique Identifier" msgstr "" @@ -3058,6 +3091,10 @@ msgstr "" msgid "This stock item does not have any child items" msgstr "" +#: stock/templates/stock/item_delete.html:9 +msgid "Are you sure you want to delete this stock item?" +msgstr "" + #: stock/templates/stock/item_tests.html:10 stock/templates/stock/tabs.html:13 msgid "Test Data" msgstr "" @@ -3078,49 +3115,57 @@ msgstr "" msgid "All stock items" msgstr "" -#: stock/templates/stock/location.html:22 -msgid "Count stock items" -msgstr "" - -#: stock/templates/stock/location.html:25 -msgid "Edit stock location" -msgstr "" - -#: stock/templates/stock/location.html:28 -msgid "Delete stock location" +#: stock/templates/stock/location.html:26 +msgid "Check-in Items" msgstr "" #: stock/templates/stock/location.html:37 +msgid "Location actions" +msgstr "" + +#: stock/templates/stock/location.html:39 +msgid "Edit location" +msgstr "" + +#: stock/templates/stock/location.html:40 +msgid "Delete location" +msgstr "" + +#: stock/templates/stock/location.html:48 msgid "Location Details" msgstr "" -#: stock/templates/stock/location.html:42 +#: stock/templates/stock/location.html:53 msgid "Location Path" msgstr "" -#: stock/templates/stock/location.html:47 +#: stock/templates/stock/location.html:58 msgid "Location Description" msgstr "" -#: stock/templates/stock/location.html:52 +#: stock/templates/stock/location.html:63 msgid "Sublocations" msgstr "" -#: stock/templates/stock/location.html:57 -#: stock/templates/stock/location.html:72 templates/stats.html:21 +#: stock/templates/stock/location.html:68 +#: stock/templates/stock/location.html:83 templates/stats.html:21 #: templates/stats.html:30 msgid "Stock Items" msgstr "" -#: stock/templates/stock/location.html:62 +#: stock/templates/stock/location.html:73 msgid "Stock Details" msgstr "" -#: stock/templates/stock/location.html:67 +#: stock/templates/stock/location.html:78 #: templates/InvenTree/search_stock_location.html:6 templates/stats.html:25 msgid "Stock Locations" msgstr "" +#: stock/templates/stock/location_delete.html:7 +msgid "Are you sure you want to delete this stock location?" +msgstr "" + #: stock/templates/stock/stockitem_convert.html:7 stock/views.py:934 msgid "Convert Stock Item" msgstr "" @@ -3137,6 +3182,10 @@ msgstr "" msgid "This action cannot be easily undone" msgstr "" +#: stock/templates/stock/tabs.html:6 +msgid "Tracking" +msgstr "" + #: stock/templates/stock/tabs.html:21 msgid "Builds" msgstr "" @@ -3416,39 +3465,83 @@ msgstr "" msgid "Delete attachment" msgstr "" -#: templates/js/barcode.html:28 +#: templates/js/barcode.html:8 msgid "Scan barcode data here using wedge scanner" msgstr "" -#: templates/js/barcode.html:34 +#: templates/js/barcode.html:12 msgid "Barcode" msgstr "" -#: templates/js/barcode.html:42 +#: templates/js/barcode.html:20 msgid "Enter barcode data" msgstr "" -#: templates/js/barcode.html:140 -msgid "Scan barcode data below" -msgstr "" - -#: templates/js/barcode.html:195 templates/js/barcode.html:243 -msgid "Unknown response from server" -msgstr "" - -#: templates/js/barcode.html:198 templates/js/barcode.html:247 +#: templates/js/barcode.html:42 msgid "Invalid server response" msgstr "" -#: templates/js/barcode.html:265 +#: templates/js/barcode.html:143 +msgid "Scan barcode data below" +msgstr "" + +#: templates/js/barcode.html:217 templates/js/barcode.html:263 +msgid "Unknown response from server" +msgstr "" + +#: templates/js/barcode.html:239 +msgid "Link Barcode to Stock Item" +msgstr "" + +#: templates/js/barcode.html:285 msgid "" "This will remove the association between this stock item and the barcode" msgstr "" -#: templates/js/barcode.html:271 +#: templates/js/barcode.html:291 msgid "Unlink" msgstr "" +#: templates/js/barcode.html:350 +msgid "Remove stock item" +msgstr "" + +#: templates/js/barcode.html:397 +msgid "Enter notes" +msgstr "" + +#: templates/js/barcode.html:399 +msgid "Enter optional notes for stock transfer" +msgstr "" + +#: templates/js/barcode.html:404 +msgid "Check Stock Items into Location" +msgstr "" + +#: templates/js/barcode.html:408 +msgid "Check In" +msgstr "" + +#: templates/js/barcode.html:466 +msgid "Server error" +msgstr "" + +#: templates/js/barcode.html:485 +msgid "Stock Item already scanned" +msgstr "" + +#: templates/js/barcode.html:489 +msgid "Stock Item already in this location" +msgstr "" + +#: templates/js/barcode.html:496 +msgid "Added stock item" +msgstr "" + +#: templates/js/barcode.html:503 +msgid "Barcode does not match Stock Item" +msgstr "" + #: templates/js/bom.html:143 msgid "Open subassembly" msgstr "" @@ -3509,7 +3602,7 @@ msgstr "" msgid "No purchase orders found" msgstr "" -#: templates/js/order.html:170 templates/js/stock.html:605 +#: templates/js/order.html:170 templates/js/stock.html:612 msgid "Date" msgstr "" @@ -3521,7 +3614,7 @@ msgstr "" msgid "Shipment Date" msgstr "" -#: templates/js/part.html:106 templates/js/stock.html:403 +#: templates/js/part.html:106 templates/js/stock.html:405 msgid "Select" msgstr "" @@ -3537,7 +3630,7 @@ msgstr "" msgid "No category" msgstr "" -#: templates/js/part.html:214 templates/js/table_filters.html:130 +#: templates/js/part.html:214 templates/js/table_filters.html:157 msgid "Low stock" msgstr "" @@ -3597,107 +3690,119 @@ msgstr "" msgid "Test Date" msgstr "" -#: templates/js/stock.html:258 +#: templates/js/stock.html:260 msgid "No stock items matching query" msgstr "" -#: templates/js/stock.html:355 templates/js/stock.html:370 +#: templates/js/stock.html:357 templates/js/stock.html:372 msgid "Undefined location" msgstr "" -#: templates/js/stock.html:467 +#: templates/js/stock.html:469 msgid "StockItem has been allocated" msgstr "" -#: templates/js/stock.html:472 +#: templates/js/stock.html:474 msgid "StockItem is lost" msgstr "" -#: templates/js/stock.html:500 +#: templates/js/stock.html:503 +msgid "Shipped to customer" +msgstr "" + +#: templates/js/stock.html:506 msgid "No stock location set" msgstr "" -#: templates/js/stock.html:671 +#: templates/js/stock.html:678 msgid "No user information" msgstr "" -#: templates/js/table_filters.html:19 -msgid "Include sublocations" +#: templates/js/table_filters.html:19 templates/js/table_filters.html:62 +msgid "Is Serialized" msgstr "" -#: templates/js/table_filters.html:20 -msgid "Include stock in sublocations" -msgstr "" - -#: templates/js/table_filters.html:24 -msgid "Active parts" -msgstr "" - -#: templates/js/table_filters.html:25 -msgid "Show stock for active parts" -msgstr "" - -#: templates/js/table_filters.html:29 templates/js/table_filters.html:30 -msgid "Stock status" -msgstr "" - -#: templates/js/table_filters.html:34 -msgid "Is allocated" -msgstr "" - -#: templates/js/table_filters.html:35 -msgid "Item has been alloacted" -msgstr "" - -#: templates/js/table_filters.html:38 +#: templates/js/table_filters.html:22 templates/js/table_filters.html:65 msgid "Serial number GTE" msgstr "" -#: templates/js/table_filters.html:39 +#: templates/js/table_filters.html:23 templates/js/table_filters.html:66 msgid "Serial number greater than or equal to" msgstr "" -#: templates/js/table_filters.html:42 +#: templates/js/table_filters.html:26 templates/js/table_filters.html:69 msgid "Serial number LTE" msgstr "" -#: templates/js/table_filters.html:43 +#: templates/js/table_filters.html:27 templates/js/table_filters.html:70 msgid "Serial number less than or equal to" msgstr "" -#: templates/js/table_filters.html:72 +#: templates/js/table_filters.html:38 +msgid "Show items which are in stock" +msgstr "" + +#: templates/js/table_filters.html:42 +msgid "Include sublocations" +msgstr "" + +#: templates/js/table_filters.html:43 +msgid "Include stock in sublocations" +msgstr "" + +#: templates/js/table_filters.html:47 +msgid "Active parts" +msgstr "" + +#: templates/js/table_filters.html:48 +msgid "Show stock for active parts" +msgstr "" + +#: templates/js/table_filters.html:52 templates/js/table_filters.html:53 +msgid "Stock status" +msgstr "" + +#: templates/js/table_filters.html:57 +msgid "Is allocated" +msgstr "" + +#: templates/js/table_filters.html:58 +msgid "Item has been alloacted" +msgstr "" + +#: templates/js/table_filters.html:99 msgid "Build status" msgstr "" -#: templates/js/table_filters.html:84 templates/js/table_filters.html:97 +#: templates/js/table_filters.html:111 templates/js/table_filters.html:124 msgid "Order status" msgstr "" -#: templates/js/table_filters.html:89 templates/js/table_filters.html:102 +#: templates/js/table_filters.html:116 templates/js/table_filters.html:129 msgid "Outstanding" msgstr "" -#: templates/js/table_filters.html:112 +#: templates/js/table_filters.html:139 msgid "Include subcategories" msgstr "" -#: templates/js/table_filters.html:113 +#: templates/js/table_filters.html:140 msgid "Include parts in subcategories" msgstr "" -#: templates/js/table_filters.html:118 +#: templates/js/table_filters.html:145 msgid "Show active parts" msgstr "" -#: templates/js/table_filters.html:126 +#: templates/js/table_filters.html:153 msgid "Stock available" msgstr "" -#: templates/js/table_filters.html:142 +#: templates/js/table_filters.html:169 msgid "Starred" msgstr "" -#: templates/js/table_filters.html:154 +#: templates/js/table_filters.html:181 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/es/LC_MESSAGES/django.po b/InvenTree/locale/es/LC_MESSAGES/django.po index c539fbcae5..972a9ee6af 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-06-12 00:43+0000\n" +"POT-Creation-Date: 2020-07-30 10:24+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -78,7 +78,7 @@ msgstr "" msgid "File comment" msgstr "" -#: InvenTree/models.py:68 templates/js/stock.html:662 +#: InvenTree/models.py:68 templates/js/stock.html:669 msgid "User" msgstr "" @@ -286,9 +286,10 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:145 #: order/templates/order/receive_parts.html:19 part/models.py:240 #: part/templates/part/part_app_base.html:7 -#: part/templates/part/set_category.html:13 templates/js/bom.html:135 -#: templates/js/build.html:41 templates/js/company.html:109 -#: templates/js/part.html:120 templates/js/stock.html:422 +#: part/templates/part/set_category.html:13 templates/js/barcode.html:336 +#: templates/js/bom.html:135 templates/js/build.html:41 +#: templates/js/company.html:109 templates/js/part.html:120 +#: templates/js/stock.html:424 msgid "Part" msgstr "" @@ -322,7 +323,7 @@ msgstr "" msgid "Number of parts to build" msgstr "" -#: build/models.py:128 part/templates/part/part_base.html:141 +#: build/models.py:128 part/templates/part/part_base.html:139 msgid "Build Status" msgstr "" @@ -341,7 +342,7 @@ msgstr "" #: build/models.py:155 build/templates/build/detail.html:55 #: company/templates/company/supplier_part_base.html:60 #: company/templates/company/supplier_part_detail.html:24 -#: part/templates/part/detail.html:74 part/templates/part/part_base.html:88 +#: part/templates/part/detail.html:74 part/templates/part/part_base.html:86 #: stock/models.py:368 stock/templates/stock/item_base.html:230 msgid "External Link" msgstr "" @@ -350,13 +351,13 @@ msgstr "" msgid "Link to external URL" msgstr "" -#: build/models.py:160 build/templates/build/tabs.html:14 company/models.py:302 +#: build/models.py:160 build/templates/build/tabs.html:14 company/models.py:307 #: company/templates/company/tabs.html:33 order/templates/order/po_tabs.html:15 #: order/templates/order/purchase_order_detail.html:200 -#: order/templates/order/so_tabs.html:23 part/templates/part/tabs.html:73 +#: order/templates/order/so_tabs.html:23 part/templates/part/tabs.html:64 #: stock/models.py:436 stock/models.py:1265 stock/templates/stock/tabs.html:26 -#: templates/js/bom.html:229 templates/js/stock.html:113 -#: templates/js/stock.html:506 +#: templates/js/barcode.html:391 templates/js/bom.html:229 +#: templates/js/stock.html:113 templates/js/stock.html:513 msgid "Notes" msgstr "" @@ -422,7 +423,7 @@ msgstr "" #: build/templates/build/allocate.html:161 #: order/templates/order/sales_order_detail.html:68 #: order/templates/order/sales_order_detail.html:150 stock/models.py:362 -#: stock/templates/stock/item_base.html:189 +#: stock/templates/stock/item_base.html:146 msgid "Serial Number" msgstr "" @@ -439,16 +440,18 @@ msgstr "" #: part/templates/part/allocation.html:49 #: stock/templates/stock/item_base.html:26 #: stock/templates/stock/item_base.html:32 -#: stock/templates/stock/item_base.html:195 -#: stock/templates/stock/stock_adjust.html:18 templates/js/bom.html:172 -#: templates/js/build.html:52 templates/js/stock.html:653 +#: stock/templates/stock/item_base.html:152 +#: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.html:338 +#: templates/js/bom.html:172 templates/js/build.html:52 +#: templates/js/stock.html:660 msgid "Quantity" msgstr "" #: build/templates/build/allocate.html:177 #: build/templates/build/auto_allocate.html:20 -#: stock/templates/stock/item_base.html:171 -#: stock/templates/stock/stock_adjust.html:17 templates/js/stock.html:493 +#: stock/templates/stock/item_base.html:184 +#: stock/templates/stock/stock_adjust.html:17 templates/js/barcode.html:337 +#: templates/js/stock.html:495 msgid "Location" msgstr "" @@ -474,7 +477,7 @@ msgstr "" #: templates/js/bom.html:157 templates/js/company.html:60 #: templates/js/order.html:157 templates/js/order.html:230 #: templates/js/part.html:176 templates/js/part.html:355 -#: templates/js/stock.html:443 templates/js/stock.html:634 +#: templates/js/stock.html:445 templates/js/stock.html:641 msgid "Description" msgstr "" @@ -484,8 +487,8 @@ msgstr "" msgid "Reference" msgstr "" -#: build/templates/build/allocate.html:338 part/models.py:1260 -#: templates/js/part.html:359 templates/js/table_filters.html:63 +#: build/templates/build/allocate.html:338 part/models.py:1269 +#: templates/js/part.html:359 templates/js/table_filters.html:90 msgid "Required" msgstr "" @@ -548,9 +551,9 @@ msgstr "" #: build/templates/build/build_base.html:80 #: build/templates/build/detail.html:42 #: order/templates/order/receive_parts.html:24 -#: stock/templates/stock/item_base.html:262 templates/js/build.html:57 -#: templates/js/order.html:162 templates/js/order.html:235 -#: templates/js/stock.html:480 +#: stock/templates/stock/item_base.html:262 templates/js/barcode.html:42 +#: templates/js/build.html:57 templates/js/order.html:162 +#: templates/js/order.html:235 templates/js/stock.html:482 msgid "Status" msgstr "" @@ -560,7 +563,7 @@ msgstr "" #: order/templates/order/sales_order_notes.html:10 #: order/templates/order/sales_order_ship.html:25 #: part/templates/part/allocation.html:27 -#: stock/templates/stock/item_base.html:159 templates/js/order.html:209 +#: stock/templates/stock/item_base.html:172 templates/js/order.html:209 msgid "Sales Order" msgstr "" @@ -627,7 +630,7 @@ msgid "Stock can be taken from any available location." msgstr "" #: build/templates/build/detail.html:48 -#: stock/templates/stock/item_base.html:202 templates/js/stock.html:488 +#: stock/templates/stock/item_base.html:202 templates/js/stock.html:490 msgid "Batch" msgstr "" @@ -847,83 +850,113 @@ msgstr "" msgid "Delete Currency" msgstr "" -#: company/models.py:83 +#: company/models.py:83 company/models.py:84 msgid "Company name" msgstr "" -#: company/models.py:85 +#: company/models.py:86 +msgid "Company description" +msgstr "" + +#: company/models.py:86 msgid "Description of the company" msgstr "" -#: company/models.py:87 +#: company/models.py:88 company/templates/company/company_base.html:48 +#: templates/js/company.html:65 +msgid "Website" +msgstr "" + +#: company/models.py:88 msgid "Company website URL" msgstr "" -#: company/models.py:90 +#: company/models.py:91 company/templates/company/company_base.html:55 +msgid "Address" +msgstr "" + +#: company/models.py:92 msgid "Company address" msgstr "" -#: company/models.py:93 +#: company/models.py:95 +msgid "Phone number" +msgstr "" + +#: company/models.py:96 msgid "Contact phone number" msgstr "" -#: company/models.py:95 -msgid "Contact email address" +#: company/models.py:98 company/templates/company/company_base.html:69 +msgid "Email" msgstr "" #: company/models.py:98 +msgid "Contact email address" +msgstr "" + +#: company/models.py:101 company/templates/company/company_base.html:76 +msgid "Contact" +msgstr "" + +#: company/models.py:102 msgid "Point of contact" msgstr "" -#: company/models.py:100 +#: company/models.py:104 msgid "Link to external company information" msgstr "" -#: company/models.py:112 +#: company/models.py:116 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:114 +#: company/models.py:118 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:116 +#: company/models.py:120 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:276 +#: company/models.py:276 stock/models.py:322 +#: stock/templates/stock/item_base.html:138 +msgid "Base Part" +msgstr "" + +#: company/models.py:281 msgid "Select part" msgstr "" -#: company/models.py:282 +#: company/models.py:287 msgid "Select supplier" msgstr "" -#: company/models.py:285 +#: company/models.py:290 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:292 +#: company/models.py:297 msgid "Select manufacturer" msgstr "" -#: company/models.py:296 +#: company/models.py:301 msgid "Manufacturer part number" msgstr "" -#: company/models.py:298 +#: company/models.py:303 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:300 +#: company/models.py:305 msgid "Supplier part description" msgstr "" -#: company/models.py:304 +#: company/models.py:309 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:306 +#: company/models.py:311 msgid "Part packaging" msgstr "" @@ -942,26 +975,10 @@ msgstr "" msgid "Company Details" msgstr "" -#: company/templates/company/company_base.html:48 templates/js/company.html:65 -msgid "Website" -msgstr "" - -#: company/templates/company/company_base.html:55 -msgid "Address" -msgstr "" - #: company/templates/company/company_base.html:62 msgid "Phone" msgstr "" -#: company/templates/company/company_base.html:69 -msgid "Email" -msgstr "" - -#: company/templates/company/company_base.html:76 -msgid "Contact" -msgstr "" - #: company/templates/company/detail.html:16 #: company/templates/company/supplier_part_base.html:76 #: company/templates/company/supplier_part_detail.html:30 @@ -981,7 +998,7 @@ msgstr "" #: company/templates/company/detail.html:26 order/models.py:314 #: order/templates/order/sales_order_base.html:73 stock/models.py:357 -#: stock/models.py:358 stock/templates/stock/item_base.html:146 +#: stock/models.py:358 stock/templates/stock/item_base.html:159 #: templates/js/company.html:44 templates/js/order.html:217 msgid "Customer" msgstr "" @@ -992,7 +1009,7 @@ msgstr "" #: company/templates/company/detail_part.html:13 #: order/templates/order/purchase_order_detail.html:67 -#: part/templates/part/stock.html:82 part/templates/part/supplier.html:12 +#: part/templates/part/stock.html:81 part/templates/part/supplier.html:12 msgid "New Supplier Part" msgstr "" @@ -1006,7 +1023,7 @@ msgid "Delete Parts" msgstr "" #: company/templates/company/detail_part.html:43 -#: part/templates/part/stock.html:76 +#: part/templates/part/stock.html:75 msgid "New Part" msgstr "" @@ -1038,7 +1055,7 @@ msgstr "" #: company/templates/company/detail_stock.html:34 #: company/templates/company/supplier_part_stock.html:33 -#: part/templates/part/stock.html:54 templates/stock_table.html:5 +#: part/templates/part/stock.html:53 templates/stock_table.html:5 msgid "Export" msgstr "" @@ -1178,12 +1195,12 @@ msgstr "" #: company/templates/company/supplier_part_stock.html:56 #: order/templates/order/purchase_order_detail.html:38 #: order/templates/order/purchase_order_detail.html:118 -#: part/templates/part/stock.html:91 +#: part/templates/part/stock.html:90 msgid "New Location" msgstr "" #: company/templates/company/supplier_part_stock.html:57 -#: part/templates/part/stock.html:92 +#: part/templates/part/stock.html:91 msgid "Create New Location" msgstr "" @@ -1194,7 +1211,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:203 -#: templates/js/stock.html:451 templates/navbar.html:11 +#: templates/js/stock.html:453 templates/navbar.html:11 msgid "Stock" msgstr "" @@ -1274,7 +1291,7 @@ msgstr "" msgid "Edit Supplier Part" msgstr "" -#: company/views.py:265 part/templates/part/stock.html:83 +#: company/views.py:265 part/templates/part/stock.html:82 msgid "Create new Supplier Part" msgstr "" @@ -1508,7 +1525,7 @@ msgid "Purchase Order Attachments" msgstr "" #: order/templates/order/po_tabs.html:8 order/templates/order/so_tabs.html:16 -#: part/templates/part/tabs.html:70 stock/templates/stock/tabs.html:32 +#: part/templates/part/tabs.html:61 stock/templates/stock/tabs.html:32 msgid "Attachments" msgstr "" @@ -1524,7 +1541,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:39 #: order/templates/order/purchase_order_detail.html:119 -#: stock/templates/stock/location.html:17 +#: stock/templates/stock/location.html:16 msgid "Create new stock location" msgstr "" @@ -1563,7 +1580,7 @@ msgid "Select parts to receive against this order" msgstr "" #: order/templates/order/receive_parts.html:21 -#: part/templates/part/part_base.html:131 templates/js/part.html:219 +#: part/templates/part/part_base.html:129 templates/js/part.html:219 msgid "On Order" msgstr "" @@ -1952,111 +1969,111 @@ msgstr "" msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1212 +#: part/models.py:1221 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:1229 +#: part/models.py:1238 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:1248 templates/js/part.html:350 templates/js/stock.html:89 +#: part/models.py:1257 templates/js/part.html:350 templates/js/stock.html:89 msgid "Test Name" msgstr "" -#: part/models.py:1249 +#: part/models.py:1258 msgid "Enter a name for the test" msgstr "" -#: part/models.py:1254 +#: part/models.py:1263 msgid "Test Description" msgstr "" -#: part/models.py:1255 +#: part/models.py:1264 msgid "Enter description for this test" msgstr "" -#: part/models.py:1261 +#: part/models.py:1270 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:1266 templates/js/part.html:367 +#: part/models.py:1275 templates/js/part.html:367 msgid "Requires Value" msgstr "" -#: part/models.py:1267 +#: part/models.py:1276 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:1272 templates/js/part.html:374 +#: part/models.py:1281 templates/js/part.html:374 msgid "Requires Attachment" msgstr "" -#: part/models.py:1273 +#: part/models.py:1282 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:1306 +#: part/models.py:1315 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:1311 +#: part/models.py:1320 msgid "Parameter Name" msgstr "" -#: part/models.py:1313 +#: part/models.py:1322 msgid "Parameter Units" msgstr "" -#: part/models.py:1339 +#: part/models.py:1348 msgid "Parent Part" msgstr "" -#: part/models.py:1341 +#: part/models.py:1350 msgid "Parameter Template" msgstr "" -#: part/models.py:1343 +#: part/models.py:1352 msgid "Parameter Value" msgstr "" -#: part/models.py:1372 +#: part/models.py:1381 msgid "Select parent part" msgstr "" -#: part/models.py:1380 +#: part/models.py:1389 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:1386 +#: part/models.py:1395 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:1389 +#: part/models.py:1398 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:1392 +#: part/models.py:1401 msgid "BOM item reference" msgstr "" -#: part/models.py:1395 +#: part/models.py:1404 msgid "BOM item notes" msgstr "" -#: part/models.py:1397 +#: part/models.py:1406 msgid "BOM line checksum" msgstr "" -#: part/models.py:1461 stock/models.py:233 +#: part/models.py:1470 stock/models.py:233 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:1470 +#: part/models.py:1479 msgid "Part cannot be added to its own Bill of Materials" msgstr "" -#: part/models.py:1477 +#: part/models.py:1486 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" @@ -2078,12 +2095,12 @@ msgstr "" #: stock/templates/stock/item_base.html:58 #: stock/templates/stock/item_base.html:224 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.html:106 -#: templates/js/stock.html:623 +#: templates/js/stock.html:630 msgid "Stock Item" msgstr "" #: part/templates/part/allocation.html:20 -#: stock/templates/stock/item_base.html:165 +#: stock/templates/stock/item_base.html:178 msgid "Build Order" msgstr "" @@ -2164,7 +2181,7 @@ msgstr "" msgid "Part Details" msgstr "" -#: part/templates/part/detail.html:25 part/templates/part/part_base.html:81 +#: part/templates/part/detail.html:25 part/templates/part/part_base.html:79 msgid "IPN" msgstr "" @@ -2222,7 +2239,7 @@ msgid "Part is not a virtual part" msgstr "" #: part/templates/part/detail.html:139 stock/forms.py:194 -#: templates/js/table_filters.html:122 +#: templates/js/table_filters.html:149 msgid "Template" msgstr "" @@ -2234,7 +2251,7 @@ msgstr "" msgid "Part is not a template part" msgstr "" -#: part/templates/part/detail.html:148 templates/js/table_filters.html:134 +#: part/templates/part/detail.html:148 templates/js/table_filters.html:161 msgid "Assembly" msgstr "" @@ -2246,7 +2263,7 @@ msgstr "" msgid "Part cannot be assembled from other parts" msgstr "" -#: part/templates/part/detail.html:157 templates/js/table_filters.html:138 +#: part/templates/part/detail.html:157 templates/js/table_filters.html:165 msgid "Component" msgstr "" @@ -2258,7 +2275,7 @@ msgstr "" msgid "Part cannot be used in assemblies" msgstr "" -#: part/templates/part/detail.html:166 templates/js/table_filters.html:150 +#: part/templates/part/detail.html:166 templates/js/table_filters.html:177 msgid "Trackable" msgstr "" @@ -2278,7 +2295,7 @@ msgstr "" msgid "Part can be purchased from external suppliers" msgstr "" -#: part/templates/part/detail.html:184 templates/js/table_filters.html:146 +#: part/templates/part/detail.html:184 templates/js/table_filters.html:173 msgid "Salable" msgstr "" @@ -2290,7 +2307,7 @@ msgstr "" msgid "Part cannot be sold to customers" msgstr "" -#: part/templates/part/detail.html:193 templates/js/table_filters.html:117 +#: part/templates/part/detail.html:193 templates/js/table_filters.html:144 msgid "Active" msgstr "" @@ -2360,35 +2377,69 @@ msgstr "" msgid "Inactive" msgstr "" -#: part/templates/part/part_base.html:41 +#: part/templates/part/part_base.html:39 msgid "Star this part" msgstr "" +#: part/templates/part/part_base.html:44 +#: stock/templates/stock/item_base.html:78 +#: stock/templates/stock/location.html:22 +msgid "Barcode actions" +msgstr "" + +#: part/templates/part/part_base.html:46 +#: stock/templates/stock/item_base.html:80 +#: stock/templates/stock/location.html:24 +msgid "Show QR Code" +msgstr "" + #: part/templates/part/part_base.html:47 +#: stock/templates/stock/item_base.html:81 +#: stock/templates/stock/location.html:25 +msgid "Print Label" +msgstr "" + +#: part/templates/part/part_base.html:51 msgid "Show pricing information" msgstr "" -#: part/templates/part/part_base.html:104 +#: part/templates/part/part_base.html:64 +msgid "Part actions" +msgstr "" + +#: part/templates/part/part_base.html:66 +msgid "Duplicate part" +msgstr "" + +#: part/templates/part/part_base.html:67 +msgid "Edit part" +msgstr "" + +#: part/templates/part/part_base.html:69 +msgid "Delete part" +msgstr "" + +#: part/templates/part/part_base.html:102 msgid "Available Stock" msgstr "" -#: part/templates/part/part_base.html:110 +#: part/templates/part/part_base.html:108 templates/js/table_filters.html:37 msgid "In Stock" msgstr "" -#: part/templates/part/part_base.html:117 +#: part/templates/part/part_base.html:115 msgid "Allocated to Build Orders" msgstr "" -#: part/templates/part/part_base.html:124 +#: part/templates/part/part_base.html:122 msgid "Allocated to Sales Orders" msgstr "" -#: part/templates/part/part_base.html:146 +#: part/templates/part/part_base.html:144 msgid "Can Build" msgstr "" -#: part/templates/part/part_base.html:152 +#: part/templates/part/part_base.html:150 msgid "Underway" msgstr "" @@ -2428,7 +2479,7 @@ msgstr "" msgid "Part Stock" msgstr "" -#: part/templates/part/stock.html:77 +#: part/templates/part/stock.html:76 msgid "Create New Part" msgstr "" @@ -2473,11 +2524,7 @@ msgstr "" msgid "Used In" msgstr "" -#: part/templates/part/tabs.html:57 stock/templates/stock/tabs.html:6 -msgid "Tracking" -msgstr "" - -#: part/templates/part/tabs.html:64 stock/templates/stock/item_base.html:268 +#: part/templates/part/tabs.html:55 stock/templates/stock/item_base.html:268 msgid "Tests" msgstr "" @@ -2739,10 +2786,6 @@ msgstr "" msgid "Parent Stock Item" msgstr "" -#: stock/models.py:322 stock/templates/stock/item_base.html:138 -msgid "Base Part" -msgstr "" - #: stock/models.py:323 msgid "Base part" msgstr "" @@ -2890,7 +2933,7 @@ msgstr "" msgid "Result" msgstr "" -#: stock/models.py:1247 templates/js/table_filters.html:53 +#: stock/models.py:1247 templates/js/table_filters.html:80 msgid "Test result" msgstr "" @@ -2945,20 +2988,8 @@ msgid "" "This stock item will be automatically deleted when all stock is depleted." msgstr "" -#: stock/templates/stock/item_base.html:78 -msgid "Barcode actions" -msgstr "" - -#: stock/templates/stock/item_base.html:80 -msgid "Show QR Code" -msgstr "" - -#: stock/templates/stock/item_base.html:81 -msgid "Print Label" -msgstr "" - -#: stock/templates/stock/item_base.html:83 templates/js/barcode.html:263 -#: templates/js/barcode.html:268 +#: stock/templates/stock/item_base.html:83 templates/js/barcode.html:283 +#: templates/js/barcode.html:288 msgid "Unlink Barcode" msgstr "" @@ -2970,7 +3001,8 @@ msgstr "" msgid "Stock adjustment actions" msgstr "" -#: stock/templates/stock/item_base.html:95 templates/stock_table.html:14 +#: stock/templates/stock/item_base.html:95 +#: stock/templates/stock/location.html:33 templates/stock_table.html:14 msgid "Count stock" msgstr "" @@ -2987,6 +3019,7 @@ msgid "Transfer stock" msgstr "" #: stock/templates/stock/item_base.html:105 +#: stock/templates/stock/location.html:30 msgid "Stock actions" msgstr "" @@ -3022,15 +3055,15 @@ msgstr "" msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:153 +#: stock/templates/stock/item_base.html:166 msgid "Belongs To" msgstr "" -#: stock/templates/stock/item_base.html:175 +#: stock/templates/stock/item_base.html:188 msgid "No location set" msgstr "" -#: stock/templates/stock/item_base.html:182 +#: stock/templates/stock/item_base.html:195 msgid "Unique Identifier" msgstr "" @@ -3058,6 +3091,10 @@ msgstr "" msgid "This stock item does not have any child items" msgstr "" +#: stock/templates/stock/item_delete.html:9 +msgid "Are you sure you want to delete this stock item?" +msgstr "" + #: stock/templates/stock/item_tests.html:10 stock/templates/stock/tabs.html:13 msgid "Test Data" msgstr "" @@ -3078,49 +3115,57 @@ msgstr "" msgid "All stock items" msgstr "" -#: stock/templates/stock/location.html:22 -msgid "Count stock items" -msgstr "" - -#: stock/templates/stock/location.html:25 -msgid "Edit stock location" -msgstr "" - -#: stock/templates/stock/location.html:28 -msgid "Delete stock location" +#: stock/templates/stock/location.html:26 +msgid "Check-in Items" msgstr "" #: stock/templates/stock/location.html:37 +msgid "Location actions" +msgstr "" + +#: stock/templates/stock/location.html:39 +msgid "Edit location" +msgstr "" + +#: stock/templates/stock/location.html:40 +msgid "Delete location" +msgstr "" + +#: stock/templates/stock/location.html:48 msgid "Location Details" msgstr "" -#: stock/templates/stock/location.html:42 +#: stock/templates/stock/location.html:53 msgid "Location Path" msgstr "" -#: stock/templates/stock/location.html:47 +#: stock/templates/stock/location.html:58 msgid "Location Description" msgstr "" -#: stock/templates/stock/location.html:52 +#: stock/templates/stock/location.html:63 msgid "Sublocations" msgstr "" -#: stock/templates/stock/location.html:57 -#: stock/templates/stock/location.html:72 templates/stats.html:21 +#: stock/templates/stock/location.html:68 +#: stock/templates/stock/location.html:83 templates/stats.html:21 #: templates/stats.html:30 msgid "Stock Items" msgstr "" -#: stock/templates/stock/location.html:62 +#: stock/templates/stock/location.html:73 msgid "Stock Details" msgstr "" -#: stock/templates/stock/location.html:67 +#: stock/templates/stock/location.html:78 #: templates/InvenTree/search_stock_location.html:6 templates/stats.html:25 msgid "Stock Locations" msgstr "" +#: stock/templates/stock/location_delete.html:7 +msgid "Are you sure you want to delete this stock location?" +msgstr "" + #: stock/templates/stock/stockitem_convert.html:7 stock/views.py:934 msgid "Convert Stock Item" msgstr "" @@ -3137,6 +3182,10 @@ msgstr "" msgid "This action cannot be easily undone" msgstr "" +#: stock/templates/stock/tabs.html:6 +msgid "Tracking" +msgstr "" + #: stock/templates/stock/tabs.html:21 msgid "Builds" msgstr "" @@ -3416,39 +3465,83 @@ msgstr "" msgid "Delete attachment" msgstr "" -#: templates/js/barcode.html:28 +#: templates/js/barcode.html:8 msgid "Scan barcode data here using wedge scanner" msgstr "" -#: templates/js/barcode.html:34 +#: templates/js/barcode.html:12 msgid "Barcode" msgstr "" -#: templates/js/barcode.html:42 +#: templates/js/barcode.html:20 msgid "Enter barcode data" msgstr "" -#: templates/js/barcode.html:140 -msgid "Scan barcode data below" -msgstr "" - -#: templates/js/barcode.html:195 templates/js/barcode.html:243 -msgid "Unknown response from server" -msgstr "" - -#: templates/js/barcode.html:198 templates/js/barcode.html:247 +#: templates/js/barcode.html:42 msgid "Invalid server response" msgstr "" -#: templates/js/barcode.html:265 +#: templates/js/barcode.html:143 +msgid "Scan barcode data below" +msgstr "" + +#: templates/js/barcode.html:217 templates/js/barcode.html:263 +msgid "Unknown response from server" +msgstr "" + +#: templates/js/barcode.html:239 +msgid "Link Barcode to Stock Item" +msgstr "" + +#: templates/js/barcode.html:285 msgid "" "This will remove the association between this stock item and the barcode" msgstr "" -#: templates/js/barcode.html:271 +#: templates/js/barcode.html:291 msgid "Unlink" msgstr "" +#: templates/js/barcode.html:350 +msgid "Remove stock item" +msgstr "" + +#: templates/js/barcode.html:397 +msgid "Enter notes" +msgstr "" + +#: templates/js/barcode.html:399 +msgid "Enter optional notes for stock transfer" +msgstr "" + +#: templates/js/barcode.html:404 +msgid "Check Stock Items into Location" +msgstr "" + +#: templates/js/barcode.html:408 +msgid "Check In" +msgstr "" + +#: templates/js/barcode.html:466 +msgid "Server error" +msgstr "" + +#: templates/js/barcode.html:485 +msgid "Stock Item already scanned" +msgstr "" + +#: templates/js/barcode.html:489 +msgid "Stock Item already in this location" +msgstr "" + +#: templates/js/barcode.html:496 +msgid "Added stock item" +msgstr "" + +#: templates/js/barcode.html:503 +msgid "Barcode does not match Stock Item" +msgstr "" + #: templates/js/bom.html:143 msgid "Open subassembly" msgstr "" @@ -3509,7 +3602,7 @@ msgstr "" msgid "No purchase orders found" msgstr "" -#: templates/js/order.html:170 templates/js/stock.html:605 +#: templates/js/order.html:170 templates/js/stock.html:612 msgid "Date" msgstr "" @@ -3521,7 +3614,7 @@ msgstr "" msgid "Shipment Date" msgstr "" -#: templates/js/part.html:106 templates/js/stock.html:403 +#: templates/js/part.html:106 templates/js/stock.html:405 msgid "Select" msgstr "" @@ -3537,7 +3630,7 @@ msgstr "" msgid "No category" msgstr "" -#: templates/js/part.html:214 templates/js/table_filters.html:130 +#: templates/js/part.html:214 templates/js/table_filters.html:157 msgid "Low stock" msgstr "" @@ -3597,107 +3690,119 @@ msgstr "" msgid "Test Date" msgstr "" -#: templates/js/stock.html:258 +#: templates/js/stock.html:260 msgid "No stock items matching query" msgstr "" -#: templates/js/stock.html:355 templates/js/stock.html:370 +#: templates/js/stock.html:357 templates/js/stock.html:372 msgid "Undefined location" msgstr "" -#: templates/js/stock.html:467 +#: templates/js/stock.html:469 msgid "StockItem has been allocated" msgstr "" -#: templates/js/stock.html:472 +#: templates/js/stock.html:474 msgid "StockItem is lost" msgstr "" -#: templates/js/stock.html:500 +#: templates/js/stock.html:503 +msgid "Shipped to customer" +msgstr "" + +#: templates/js/stock.html:506 msgid "No stock location set" msgstr "" -#: templates/js/stock.html:671 +#: templates/js/stock.html:678 msgid "No user information" msgstr "" -#: templates/js/table_filters.html:19 -msgid "Include sublocations" +#: templates/js/table_filters.html:19 templates/js/table_filters.html:62 +msgid "Is Serialized" msgstr "" -#: templates/js/table_filters.html:20 -msgid "Include stock in sublocations" -msgstr "" - -#: templates/js/table_filters.html:24 -msgid "Active parts" -msgstr "" - -#: templates/js/table_filters.html:25 -msgid "Show stock for active parts" -msgstr "" - -#: templates/js/table_filters.html:29 templates/js/table_filters.html:30 -msgid "Stock status" -msgstr "" - -#: templates/js/table_filters.html:34 -msgid "Is allocated" -msgstr "" - -#: templates/js/table_filters.html:35 -msgid "Item has been alloacted" -msgstr "" - -#: templates/js/table_filters.html:38 +#: templates/js/table_filters.html:22 templates/js/table_filters.html:65 msgid "Serial number GTE" msgstr "" -#: templates/js/table_filters.html:39 +#: templates/js/table_filters.html:23 templates/js/table_filters.html:66 msgid "Serial number greater than or equal to" msgstr "" -#: templates/js/table_filters.html:42 +#: templates/js/table_filters.html:26 templates/js/table_filters.html:69 msgid "Serial number LTE" msgstr "" -#: templates/js/table_filters.html:43 +#: templates/js/table_filters.html:27 templates/js/table_filters.html:70 msgid "Serial number less than or equal to" msgstr "" -#: templates/js/table_filters.html:72 +#: templates/js/table_filters.html:38 +msgid "Show items which are in stock" +msgstr "" + +#: templates/js/table_filters.html:42 +msgid "Include sublocations" +msgstr "" + +#: templates/js/table_filters.html:43 +msgid "Include stock in sublocations" +msgstr "" + +#: templates/js/table_filters.html:47 +msgid "Active parts" +msgstr "" + +#: templates/js/table_filters.html:48 +msgid "Show stock for active parts" +msgstr "" + +#: templates/js/table_filters.html:52 templates/js/table_filters.html:53 +msgid "Stock status" +msgstr "" + +#: templates/js/table_filters.html:57 +msgid "Is allocated" +msgstr "" + +#: templates/js/table_filters.html:58 +msgid "Item has been alloacted" +msgstr "" + +#: templates/js/table_filters.html:99 msgid "Build status" msgstr "" -#: templates/js/table_filters.html:84 templates/js/table_filters.html:97 +#: templates/js/table_filters.html:111 templates/js/table_filters.html:124 msgid "Order status" msgstr "" -#: templates/js/table_filters.html:89 templates/js/table_filters.html:102 +#: templates/js/table_filters.html:116 templates/js/table_filters.html:129 msgid "Outstanding" msgstr "" -#: templates/js/table_filters.html:112 +#: templates/js/table_filters.html:139 msgid "Include subcategories" msgstr "" -#: templates/js/table_filters.html:113 +#: templates/js/table_filters.html:140 msgid "Include parts in subcategories" msgstr "" -#: templates/js/table_filters.html:118 +#: templates/js/table_filters.html:145 msgid "Show active parts" msgstr "" -#: templates/js/table_filters.html:126 +#: templates/js/table_filters.html:153 msgid "Stock available" msgstr "" -#: templates/js/table_filters.html:142 +#: templates/js/table_filters.html:169 msgid "Starred" msgstr "" -#: templates/js/table_filters.html:154 +#: templates/js/table_filters.html:181 msgid "Purchasable" msgstr "" From 10691b3d032a821c6a07066687aa83e9df334421 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 30 Jul 2020 21:05:37 +1000 Subject: [PATCH 05/58] Allow creation of a stock item with zero quantity --- InvenTree/stock/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index 49db90d578..672f0a3892 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -1239,8 +1239,8 @@ class StockItemCreate(AjaxCreateView): valid = False form.errors['quantity'] = [_('Invalid quantity')] - if quantity <= 0: - form.errors['quantity'] = [_('Quantity must be greater than zero')] + if quantity < 0: + form.errors['quantity'] = [_('Quantity cannot be less than zero')] valid = False if part is None: From 481eeb83383561fc586f2e4b65f19c0b4d564c8a Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 3 Aug 2020 19:36:41 +1000 Subject: [PATCH 06/58] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 76b9cf12f0..362f1bd074 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ wheel>=0.34.2 # Wheel Django==3.0.7 # Django package -pillow==6.2.2 # Image manipulation +pillow==7.1.0 # Image manipulation djangorestframework==3.10.3 # DRF framework django-dbbackup==3.3.0 # Database backup / restore functionality django-cors-headers==3.2.0 # CORS headers extension for DRF From 3a266cf32296c32df82990da337e68bb4c9f5830 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 4 Aug 2020 11:10:24 +1000 Subject: [PATCH 07/58] Allow default_keywords to be null --- InvenTree/part/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 550645cb68..01768b4bb3 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -65,7 +65,7 @@ class PartCategory(InvenTreeTree): help_text=_('Default location for parts in this category') ) - default_keywords = models.CharField(blank=True, max_length=250, help_text=_('Default keywords for parts in this category')) + default_keywords = models.CharField(null=True, blank=True, max_length=250, help_text=_('Default keywords for parts in this category')) def get_absolute_url(self): return reverse('category-detail', kwargs={'pk': self.id}) From 0f199556df6bd498f01cccdce6316b733c876acc Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 4 Aug 2020 11:21:27 +1000 Subject: [PATCH 08/58] Add migration file --- .../part/migrations/0046_auto_20200804_0107.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 InvenTree/part/migrations/0046_auto_20200804_0107.py diff --git a/InvenTree/part/migrations/0046_auto_20200804_0107.py b/InvenTree/part/migrations/0046_auto_20200804_0107.py new file mode 100644 index 0000000000..5a0952c1e4 --- /dev/null +++ b/InvenTree/part/migrations/0046_auto_20200804_0107.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.7 on 2020-08-04 01:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('part', '0045_auto_20200605_0932'), + ] + + operations = [ + migrations.AlterField( + model_name='partcategory', + name='default_keywords', + field=models.CharField(blank=True, help_text='Default keywords for parts in this category', max_length=250, null=True), + ), + ] From 7b332d93ee8bc5f1d7c9cfeb1c25a89cb4ccc58a Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 8 Aug 2020 08:48:27 +1000 Subject: [PATCH 09/58] Rearrange button layouts --- .../stock/templates/stock/item_base.html | 21 ++++++++++++------- InvenTree/templates/js/stock.html | 8 +------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index a35b5f0346..8a57c8bdaf 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -86,30 +86,35 @@ InvenTree | {% trans "Stock Item" %} - {{ item }} {% endif %} - {% if item.in_stock %} - {% endif %} From a2c3c1086cea8515bc6cd9976531b5a73aba99bb Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 8 Aug 2020 09:31:57 +1000 Subject: [PATCH 16/58] Catch unhandled javascript errors --- InvenTree/stock/templates/stock/item_base.html | 2 +- InvenTree/templates/status_codes.html | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index 9b0b182848..ce055d65c5 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -161,7 +161,7 @@ InvenTree | {% trans "Stock Item" %} - {{ item }} {% trans "Customer" %} - {{ item.customer.name }} + {{ item.customer.name }} {% endif %} {% if item.belongs_to %} diff --git a/InvenTree/templates/status_codes.html b/InvenTree/templates/status_codes.html index 029252a842..f032f97309 100644 --- a/InvenTree/templates/status_codes.html +++ b/InvenTree/templates/status_codes.html @@ -18,14 +18,18 @@ function {{ label }}StatusDisplay(key) { key = String(key); - var value = {{ label }}Codes[key].value; + var value = null; + var label = null; + + if (key in {{ label }}Codes) { + value = {{ label }}Codes[key].value; + label = {{ label }}Codes[key].label; + } if (value == null || value.length == 0) { value = key; + label = ''; } - // Select the label color - var label = {{ label }}Codes[key].label ?? ''; - return `${value}`; } From 8d9cfd3678f722c2454a801a08c86da21d49acf6 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 8 Aug 2020 09:44:21 +1000 Subject: [PATCH 17/58] Migration file for StockStatus codes --- .../migrations/0048_auto_20200807_2344.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 InvenTree/stock/migrations/0048_auto_20200807_2344.py diff --git a/InvenTree/stock/migrations/0048_auto_20200807_2344.py b/InvenTree/stock/migrations/0048_auto_20200807_2344.py new file mode 100644 index 0000000000..b859344bb0 --- /dev/null +++ b/InvenTree/stock/migrations/0048_auto_20200807_2344.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.7 on 2020-08-07 23:44 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0047_auto_20200605_0932'), + ] + + operations = [ + migrations.AlterField( + model_name='stockitem', + name='status', + field=models.PositiveIntegerField(choices=[(10, 'OK'), (50, 'Attention needed'), (55, 'Damaged'), (60, 'Destroyed'), (70, 'Lost'), (65, 'Rejected'), (85, 'Returned')], default=10, validators=[django.core.validators.MinValueValidator(0)]), + ), + ] From eac53c836c89bc6bfaed57a89a3b2a7684b4582a Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 8 Aug 2020 09:52:14 +1000 Subject: [PATCH 18/58] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a66e3c10ff..1ada93e6b9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Build Status](https://travis-ci.org/inventree/InvenTree.svg?branch=master)](https://travis-ci.org/inventree/InvenTree) [![Documentation Status](https://readthedocs.org/projects/inventree/badge/?version=latest)](https://inventree.readthedocs.io/en/latest/?badge=latest) [![Coverage Status](https://coveralls.io/repos/github/inventree/InvenTree/badge.svg)](https://coveralls.io/github/inventree/InvenTree) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Build Status](https://travis-ci.org/inventree/InvenTree.svg?branch=master)](https://travis-ci.org/inventree/InvenTree) [![Coverage Status](https://coveralls.io/repos/github/inventree/InvenTree/badge.svg)](https://coveralls.io/github/inventree/InvenTree) InvenTree @@ -15,7 +15,7 @@ Refer to the [getting started guide](https://inventree.github.io/docs/start/inst ## Documentation -For InvenTree documentation, refer to the [InvenTre documentation website](https://inventree.github.io). +For InvenTree documentation, refer to the [InvenTree documentation website](https://inventree.github.io). ## Integration From ad977d4d26df8e9d8cacd35585113735f2fa13d2 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 8 Aug 2020 16:54:09 +1000 Subject: [PATCH 19/58] Add default ordering for Company model - Now will sort by "name" in choice fields, etc --- InvenTree/company/models.py | 3 +++ InvenTree/part/models.py | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index 2179897263..7c059782fb 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -79,6 +79,9 @@ class Company(models.Model): is_manufacturer: boolean value, is this company a manufacturer """ + class Meta: + ordering = ['name',] + name = models.CharField(max_length=100, blank=False, unique=True, help_text=_('Company name'), verbose_name=_('Company name')) diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 01768b4bb3..6ec3f2cfea 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -71,8 +71,8 @@ class PartCategory(InvenTreeTree): return reverse('category-detail', kwargs={'pk': self.id}) class Meta: - verbose_name = "Part Category" - verbose_name_plural = "Part Categories" + verbose_name = _("Part Category") + verbose_name_plural = _("Part Categories") def get_parts(self, cascade=True): """ Return a queryset for all parts under this category. @@ -239,6 +239,7 @@ class Part(MPTTModel): class Meta: verbose_name = _("Part") verbose_name_plural = _("Parts") + ordering = ['name',] class MPTTMeta: # For legacy reasons the 'variant_of' field is used to indicate the MPTT parent @@ -1490,7 +1491,7 @@ class BomItem(models.Model): pass class Meta: - verbose_name = "BOM Item" + verbose_name = _("BOM Item") # Prevent duplication of parent/child rows unique_together = ('part', 'sub_part') From a7ee3230350fe724520d0d0f683d14ec2c9f11b5 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 8 Aug 2020 16:59:48 +1000 Subject: [PATCH 20/58] PEP fix --- InvenTree/company/models.py | 2 +- InvenTree/part/models.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index 7c059782fb..a06ddd94bf 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -80,7 +80,7 @@ class Company(models.Model): """ class Meta: - ordering = ['name',] + ordering = ['name', ] name = models.CharField(max_length=100, blank=False, unique=True, help_text=_('Company name'), diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 6ec3f2cfea..308808fbdd 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -239,7 +239,7 @@ class Part(MPTTModel): class Meta: verbose_name = _("Part") verbose_name_plural = _("Parts") - ordering = ['name',] + ordering = ['name', ] class MPTTMeta: # For legacy reasons the 'variant_of' field is used to indicate the MPTT parent From 732405f738789638ee01ff8f95853b53277bb81b Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 8 Aug 2020 17:01:29 +1000 Subject: [PATCH 21/58] Cannot edit quantity for serialized stock when adjusting --- InvenTree/stock/templates/stock/stock_adjust.html | 1 + 1 file changed, 1 insertion(+) diff --git a/InvenTree/stock/templates/stock/stock_adjust.html b/InvenTree/stock/templates/stock/stock_adjust.html index a72407f735..8385fb5039 100644 --- a/InvenTree/stock/templates/stock/stock_adjust.html +++ b/InvenTree/stock/templates/stock/stock_adjust.html @@ -32,6 +32,7 @@ {% if item.error %}
    {{ item.error }} From 402301e165e7a4a5911994547513383609cdc503 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 8 Aug 2020 17:06:22 +1000 Subject: [PATCH 22/58] Add ability to filter stock items by "depleted" status --- InvenTree/stock/api.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index 018b588c1f..023b0c6c4e 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -539,10 +539,21 @@ class StockList(generics.ListCreateAPIView): active = str2bool(active) queryset = queryset.filter(part__active=active) + # Filter by 'depleted' status + depleted = params.get('depleted', None) + + if depleted is not None: + depleted = str2bool(depleted) + + if depleted: + queryset = queryset.filter(quantity__lte=0) + else: + queryset = queryset.exclude(quantity__lte=0) + # Filter by internal part number IPN = params.get('IPN', None) - if IPN: + if IPN is not None: queryset = queryset.filter(part__IPN=IPN) # Does the client wish to filter by the Part ID? From 099f56e7798db12a45907ac286bdb959d400f854 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 8 Aug 2020 17:08:18 +1000 Subject: [PATCH 23/58] Add "depleted" table filter --- InvenTree/templates/js/table_filters.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/InvenTree/templates/js/table_filters.html b/InvenTree/templates/js/table_filters.html index e2138ef6b3..affb97c1c5 100644 --- a/InvenTree/templates/js/table_filters.html +++ b/InvenTree/templates/js/table_filters.html @@ -47,6 +47,11 @@ function getAvailableTableFilters(tableKey) { title: '{% trans "Active parts" %}', description: '{% trans "Show stock for active parts" %}', }, + depleted: { + type: 'bool', + title: '{% trans "Depleted" %}', + description: '{% trans "Show stock items which are depleted" %}', + }, status: { options: stockCodes, title: '{% trans "Stock status" %}', From 96a3f2920df03252ed54d611498ab4d8f6065915 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 8 Aug 2020 17:09:22 +1000 Subject: [PATCH 24/58] Stock table filters now arranged in alphabetical order --- InvenTree/templates/js/table_filters.html | 32 +++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/InvenTree/templates/js/table_filters.html b/InvenTree/templates/js/table_filters.html index affb97c1c5..aef430bf36 100644 --- a/InvenTree/templates/js/table_filters.html +++ b/InvenTree/templates/js/table_filters.html @@ -32,35 +32,30 @@ function getAvailableTableFilters(tableKey) { // Filters for the "Stock" table if (tableKey == 'stock') { return { - in_stock: { + active: { type: 'bool', - title: '{% trans "In Stock" %}', - description: '{% trans "Show items which are in stock" %}', + title: '{% trans "Active parts" %}', + description: '{% trans "Show stock for active parts" %}', + }, + allocated: { + type: 'bool', + title: '{% trans "Is allocated" %}', + description: '{% trans "Item has been alloacted" %}', }, cascade: { type: 'bool', title: '{% trans "Include sublocations" %}', description: '{% trans "Include stock in sublocations" %}', }, - active: { - type: 'bool', - title: '{% trans "Active parts" %}', - description: '{% trans "Show stock for active parts" %}', - }, depleted: { type: 'bool', title: '{% trans "Depleted" %}', description: '{% trans "Show stock items which are depleted" %}', }, - status: { - options: stockCodes, - title: '{% trans "Stock status" %}', - description: '{% trans "Stock status" %}', - }, - allocated: { + in_stock: { type: 'bool', - title: '{% trans "Is allocated" %}', - description: '{% trans "Item has been alloacted" %}', + title: '{% trans "In Stock" %}', + description: '{% trans "Show items which are in stock" %}', }, serialized: { type: 'bool', @@ -74,6 +69,11 @@ function getAvailableTableFilters(tableKey) { title: "{% trans "Serial number LTE" %}", description: "{% trans "Serial number less than or equal to" %}", }, + status: { + options: stockCodes, + title: '{% trans "Stock status" %}', + description: '{% trans "Stock status" %}', + }, }; } From bc3fda71a436dac7129d5f739f4ab0d31bcea627 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 8 Aug 2020 17:11:50 +1000 Subject: [PATCH 25/58] Display "depleted" label next to depleted stock --- InvenTree/templates/js/stock.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/InvenTree/templates/js/stock.html b/InvenTree/templates/js/stock.html index adaf07b4f6..f06615f2f5 100644 --- a/InvenTree/templates/js/stock.html +++ b/InvenTree/templates/js/stock.html @@ -468,6 +468,10 @@ function loadStockTable(table, options) { html += ``; } + if (row.quantity <= 0) { + html += `{% trans "Depleted" %}`; + } + return html; } }, From ad116813696cba9e2de486d903bdc1f05ce6288b Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 8 Aug 2020 17:15:08 +1000 Subject: [PATCH 26/58] Custom filter tag for company stock listing --- InvenTree/company/templates/company/detail_stock.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/InvenTree/company/templates/company/detail_stock.html b/InvenTree/company/templates/company/detail_stock.html index c33179d454..e994d5834b 100644 --- a/InvenTree/company/templates/company/detail_stock.html +++ b/InvenTree/company/templates/company/detail_stock.html @@ -26,7 +26,8 @@ }, buttons: [ '#stock-options', - ] + ], + filterKey: "companystock", }); $("#stock-export").click(function() { From 19c036f50abdc887eef25e569dd0664da9502c7c Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 8 Aug 2020 17:16:04 +1000 Subject: [PATCH 27/58] Add migration files --- .../migrations/0023_auto_20200808_0715.py | 17 +++++++++++++++++ .../part/migrations/0047_auto_20200808_0715.py | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 InvenTree/company/migrations/0023_auto_20200808_0715.py create mode 100644 InvenTree/part/migrations/0047_auto_20200808_0715.py diff --git a/InvenTree/company/migrations/0023_auto_20200808_0715.py b/InvenTree/company/migrations/0023_auto_20200808_0715.py new file mode 100644 index 0000000000..22097e8e2b --- /dev/null +++ b/InvenTree/company/migrations/0023_auto_20200808_0715.py @@ -0,0 +1,17 @@ +# Generated by Django 3.0.7 on 2020-08-08 07:15 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('company', '0022_auto_20200613_1045'), + ] + + operations = [ + migrations.AlterModelOptions( + name='company', + options={'ordering': ['name']}, + ), + ] diff --git a/InvenTree/part/migrations/0047_auto_20200808_0715.py b/InvenTree/part/migrations/0047_auto_20200808_0715.py new file mode 100644 index 0000000000..4fc3d5a7d9 --- /dev/null +++ b/InvenTree/part/migrations/0047_auto_20200808_0715.py @@ -0,0 +1,17 @@ +# Generated by Django 3.0.7 on 2020-08-08 07:15 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('part', '0046_auto_20200804_0107'), + ] + + operations = [ + migrations.AlterModelOptions( + name='part', + options={'ordering': ['name'], 'verbose_name': 'Part', 'verbose_name_plural': 'Parts'}, + ), + ] From 502702b3bc0e538d5ff5a57e0d0f20efb74cf1ca Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 9 Aug 2020 21:04:41 +1000 Subject: [PATCH 28/58] Add some more visual tags to the stock list --- InvenTree/templates/js/stock.html | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/InvenTree/templates/js/stock.html b/InvenTree/templates/js/stock.html index f06615f2f5..11cf6a94e3 100644 --- a/InvenTree/templates/js/stock.html +++ b/InvenTree/templates/js/stock.html @@ -1,4 +1,5 @@ {% load i18n %} +{% load status_codes %} /* Stock API functions * Requires api.js to be loaded first @@ -460,12 +461,26 @@ function loadStockTable(table, options) { var html = renderLink(val, `/stock/item/${row.pk}/`); if (row.allocated) { - html += ``; + html += ``; } + if (row.customer) { + html += ``; + } else if (row.build_order) { + html += ``; + } else if (row.sales_order) { + html += ``; + } + + // Special stock status codes + + // 65 = "REJECTED" + if (row.status == 65) { + html += ``; + } // 70 = "LOST" - if (row.status == 70) { - html += ``; + else if (row.status == 70) { + html += ``; } if (row.quantity <= 0) { From 0da9e0f8341575975123fef6c0ca196a8d574c02 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 9 Aug 2020 21:10:21 +1000 Subject: [PATCH 29/58] Add "sent_to_customer" filter --- InvenTree/stock/api.py | 11 +++++++++++ InvenTree/templates/js/table_filters.html | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index 023b0c6c4e..b291a2cb5c 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -477,6 +477,17 @@ class StockList(generics.ListCreateAPIView): if customer: queryset = queryset.filter(customer=customer) + # Filter if items have been sent to a customer (any customer) + sent_to_customer = params.get('sent_to_customer', None) + + if sent_to_customer is not None: + sent_to_customer = str2bool(sent_to_customer) + + if sent_to_customer: + queryset = queryset.exclude(customer=None) + else: + queryset = queryset.filter(customer=None) + # Filter by "serialized" status? serialized = params.get('serialized', None) diff --git a/InvenTree/templates/js/table_filters.html b/InvenTree/templates/js/table_filters.html index aef430bf36..9050edba6f 100644 --- a/InvenTree/templates/js/table_filters.html +++ b/InvenTree/templates/js/table_filters.html @@ -57,6 +57,11 @@ function getAvailableTableFilters(tableKey) { title: '{% trans "In Stock" %}', description: '{% trans "Show items which are in stock" %}', }, + sent_to_customer: { + type: 'bool', + title: '{% trans "Sent to customer" %}', + description: '{% trans "Show items which have been assigned to a customer" %}', + }, serialized: { type: 'bool', title: '{% trans "Is Serialized" %}', From 3336eb9f45ad20e4247a36d2b4323c4b1000a3d6 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 9 Aug 2020 21:12:49 +1000 Subject: [PATCH 30/58] Default stock list behaviour is to only show in_stock items --- InvenTree/stock/api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index b291a2cb5c..a10262ce9c 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -518,7 +518,8 @@ class StockList(generics.ListCreateAPIView): if serial_number_lte is not None: queryset = queryset.filter(serial__lte=serial_number_lte) - in_stock = params.get('in_stock', None) + # Filter by "in_stock" status (default behaviour is "True") + in_stock = params.get('in_stock', True) if in_stock is not None: in_stock = str2bool(in_stock) From cebba6909c7271b8e7524a032441f3e4d16eb48a Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 9 Aug 2020 21:21:12 +1000 Subject: [PATCH 31/58] Revert thing --- InvenTree/stock/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index a10262ce9c..7284f8d5cd 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -518,8 +518,8 @@ class StockList(generics.ListCreateAPIView): if serial_number_lte is not None: queryset = queryset.filter(serial__lte=serial_number_lte) - # Filter by "in_stock" status (default behaviour is "True") - in_stock = params.get('in_stock', True) + # Filter by "in_stock" status + in_stock = params.get('in_stock', None) if in_stock is not None: in_stock = str2bool(in_stock) From b8b3a933ab1abe3a60db7aede337971836a45889 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 15 Aug 2020 19:48:42 +1000 Subject: [PATCH 32/58] Add django-debug-toolbar plugin - Must be running in DEBUG mode - Must set debug_toolbar to True in config file --- InvenTree/InvenTree/settings.py | 14 +++++++++++++- InvenTree/InvenTree/urls.py | 8 ++++++++ InvenTree/config_template.yaml | 6 ++++++ requirements.txt | 3 ++- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index e5b14314b5..6d68136fb2 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -172,9 +172,16 @@ MIDDLEWARE = [ 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'InvenTree.middleware.AuthRequiredMiddleware', + + 'InvenTree.middleware.AuthRequiredMiddleware' ] +# If the debug toolbar is enabled, add the modules +if DEBUG and CONFIG.get('debug_toolbar', False): + print("Running with DEBUG_TOOLBAR enabled") + INSTALLED_APPS.append('debug_toolbar') + MIDDLEWARE.append('debug_toolbar.middleware.DebugToolbarMiddleware') + if CONFIG.get('log_queries', False): MIDDLEWARE.append('InvenTree.middleware.QueryCountMiddleware') @@ -377,3 +384,8 @@ DBBACKUP_STORAGE = 'django.core.files.storage.FileSystemStorage' DBBACKUP_STORAGE_OPTIONS = { 'location': CONFIG.get('backup_dir', tempfile.gettempdir()), } + +# Internal IP addresses allowed to see the debug toolbar +INTERNAL_IPS = [ + '127.0.0.1', +] \ No newline at end of file diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index c2d0d0f48f..d0076714ae 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -6,6 +6,7 @@ Passes URL lookup downstream to each app as required. from django.conf.urls import url, include +from django.urls import path from django.contrib import admin from django.contrib.auth import views as auth_views from qr_code import urls as qr_code_urls @@ -135,5 +136,12 @@ urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) # Media file access urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) +# Debug toolbar access (if in DEBUG mode) +if settings.DEBUG and 'debug_toolbar' in settings.INSTALLED_APPS: + import debug_toolbar + urlpatterns = [ + path('__debug/', include(debug_toolbar.urls)), + ] + urlpatterns + # Send any unknown URLs to the parts page urlpatterns += [url(r'^.*$', RedirectView.as_view(url='/index/', permanent=False), name='index')] diff --git a/InvenTree/config_template.yaml b/InvenTree/config_template.yaml index 5447606337..eef3e8727e 100644 --- a/InvenTree/config_template.yaml +++ b/InvenTree/config_template.yaml @@ -58,8 +58,14 @@ static_root: '../inventree_static' # - git # - ssh +# Set debug_toolbar to True to enable a debugging toolbar for InvenTree +# Note: This will only be displayed if DEBUG mode is enabled, +# and only if InvenTree is accessed from a local IP (127.0.0.1) +debug_toolbar: False + # Logging options # If debug mode is enabled, set log_queries to True to show aggregate database queries in the debug console +# TODO - Remove me! log_queries: False # Backup options diff --git a/requirements.txt b/requirements.txt index f09cc35167..c668612914 100644 --- a/requirements.txt +++ b/requirements.txt @@ -21,4 +21,5 @@ python-coveralls==2.9.1 # Coveralls linking (for Travis) rapidfuzz==0.7.6 # Fuzzy string matching django-stdimage==5.1.1 # Advanced ImageField management django-tex==1.1.7 # LaTeX PDF export -django-weasyprint==1.0.1 # HTML PDF export \ No newline at end of file +django-weasyprint==1.0.1 # HTML PDF export +django-debug-toolbar==2.2 # Debug / profiling toolbar \ No newline at end of file From 2bb669d7de5e9cb4248fc816f3fd12e2e696b5a7 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 15 Aug 2020 19:52:04 +1000 Subject: [PATCH 33/58] Remove defunct "log_queries" option --- InvenTree/InvenTree/middleware.py | 2 ++ InvenTree/InvenTree/settings.py | 3 --- InvenTree/config_template.yaml | 5 ----- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/InvenTree/InvenTree/middleware.py b/InvenTree/InvenTree/middleware.py index 26cbc95bbf..37b9a27c63 100644 --- a/InvenTree/InvenTree/middleware.py +++ b/InvenTree/InvenTree/middleware.py @@ -91,6 +91,8 @@ class QueryCountMiddleware(object): To enable this middleware, set 'log_queries: True' in the local InvenTree config file. Reference: https://www.dabapps.com/blog/logging-sql-queries-django-13/ + + Note: 2020-08-15 - This is no longer used, instead we now rely on the django-debug-toolbar addon """ def __init__(self, get_response): diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 6d68136fb2..7a3ab02433 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -182,9 +182,6 @@ if DEBUG and CONFIG.get('debug_toolbar', False): INSTALLED_APPS.append('debug_toolbar') MIDDLEWARE.append('debug_toolbar.middleware.DebugToolbarMiddleware') -if CONFIG.get('log_queries', False): - MIDDLEWARE.append('InvenTree.middleware.QueryCountMiddleware') - ROOT_URLCONF = 'InvenTree.urls' TEMPLATES = [ diff --git a/InvenTree/config_template.yaml b/InvenTree/config_template.yaml index eef3e8727e..1c776a6f7a 100644 --- a/InvenTree/config_template.yaml +++ b/InvenTree/config_template.yaml @@ -63,11 +63,6 @@ static_root: '../inventree_static' # and only if InvenTree is accessed from a local IP (127.0.0.1) debug_toolbar: False -# Logging options -# If debug mode is enabled, set log_queries to True to show aggregate database queries in the debug console -# TODO - Remove me! -log_queries: False - # Backup options # Set the backup_dir parameter to store backup files in a specific location # If unspecified, the local user's temp directory will be used From 3c4cfc9a1b61a076a527efc87b0efdb86bb4d922 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 15 Aug 2020 19:56:02 +1000 Subject: [PATCH 34/58] Flake fix --- InvenTree/InvenTree/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 7a3ab02433..fb68f65497 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -385,4 +385,4 @@ DBBACKUP_STORAGE_OPTIONS = { # Internal IP addresses allowed to see the debug toolbar INTERNAL_IPS = [ '127.0.0.1', -] \ No newline at end of file +] From 2f77007dbe9abe19b61749731aa9484491e90615 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 15 Aug 2020 21:15:11 +1000 Subject: [PATCH 35/58] Significant query speed improvements to stock list API - Thanks, django-debug-toolbar! - Gah, django DRF is the worst. Enforcing a PrimaryKeyRelatedSerializer seems to really improve speed --- InvenTree/stock/api.py | 7 ++----- InvenTree/stock/serializers.py | 29 ++++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index 7284f8d5cd..4368f654cf 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -338,11 +338,6 @@ class StockList(generics.ListCreateAPIView): queryset = self.filter_queryset(self.get_queryset()) - page = self.paginate_queryset(queryset) - if page is not None: - serializer = self.get_serializer(page, many=True) - return self.get_paginated_response(serializer.data) - serializer = self.get_serializer(queryset, many=True) data = serializer.data @@ -363,6 +358,7 @@ class StockList(generics.ListCreateAPIView): part_ids.add(part) sp = item['supplier_part'] + if sp: supplier_part_ids.add(sp) @@ -434,6 +430,7 @@ class StockList(generics.ListCreateAPIView): def get_queryset(self, *args, **kwargs): queryset = super().get_queryset(*args, **kwargs) + queryset = StockItemSerializer.prefetch_queryset(queryset) queryset = StockItemSerializer.annotate_queryset(queryset) diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py index 07fdd7952e..bed3f8f7c1 100644 --- a/InvenTree/stock/serializers.py +++ b/InvenTree/stock/serializers.py @@ -99,15 +99,34 @@ class StockItemSerializer(InvenTreeModelSerializer): return queryset + belongs_to = serializers.PrimaryKeyRelatedField(read_only=True) + + build_order = serializers.PrimaryKeyRelatedField(read_only=True) + + customer = serializers.PrimaryKeyRelatedField(read_only=True) + + location = serializers.PrimaryKeyRelatedField(read_only=True) + + in_stock = serializers.BooleanField(read_only=True) + + sales_order = serializers.PrimaryKeyRelatedField(read_only=True) + status_text = serializers.CharField(source='get_status_display', read_only=True) - part_detail = PartBriefSerializer(source='part', many=False, read_only=True) - location_detail = LocationBriefSerializer(source='location', many=False, read_only=True) + supplier_part = serializers.PrimaryKeyRelatedField(read_only=True) + supplier_part_detail = SupplierPartSerializer(source='supplier_part', many=False, read_only=True) + part = serializers.PrimaryKeyRelatedField(read_only=True) + + part_detail = PartBriefSerializer(source='part', many=False, read_only=True) + + location_detail = LocationBriefSerializer(source='location', many=False, read_only=True) + tracking_items = serializers.IntegerField(source='tracking_info_count', read_only=True, required=False) quantity = serializers.FloatField() + allocated = serializers.FloatField(source='allocation_count', required=False) serial = serializers.IntegerField(required=False) @@ -140,9 +159,9 @@ class StockItemSerializer(InvenTreeModelSerializer): fields = [ 'allocated', 'batch', - 'build_order', 'belongs_to', 'customer', + 'build_order', 'in_stock', 'link', 'location', @@ -155,10 +174,10 @@ class StockItemSerializer(InvenTreeModelSerializer): 'required_tests', 'sales_order', 'serial', - 'supplier_part', - 'supplier_part_detail', 'status', 'status_text', + 'supplier_part', + 'supplier_part_detail', 'tracking_items', 'uid', ] From d34383e842bd1feb0ec01691dcc9bf4cf99626fd Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 15 Aug 2020 21:20:31 +1000 Subject: [PATCH 36/58] Specify serializer type for part category --- InvenTree/part/serializers.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index d460748468..d9c041c252 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -236,6 +236,9 @@ class PartSerializer(InvenTreeModelSerializer): thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True) starred = serializers.SerializerMethodField() + # PrimaryKeyRelated fields (Note: enforcing field type here results in much faster queries, somehow...) + category = serializers.PrimaryKeyRelatedField(queryset=PartCategory.objects.all()) + # TODO - Include annotation for the following fields: # allocated_stock = serializers.FloatField(source='allocation_count', read_only=True) # bom_items = serializers.IntegerField(source='bom_count', read_only=True) From e1a8772af67819a43f739827f4ae67dea43e4b8f Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 15 Aug 2020 21:24:01 +1000 Subject: [PATCH 37/58] Update serializers for SupplierPart --- InvenTree/company/serializers.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/InvenTree/company/serializers.py b/InvenTree/company/serializers.py index 09f2b4dee8..baa618fb28 100644 --- a/InvenTree/company/serializers.py +++ b/InvenTree/company/serializers.py @@ -99,6 +99,10 @@ class SupplierPartSerializer(InvenTreeModelSerializer): if manufacturer_detail is not True: self.fields.pop('manufacturer_detail') + supplier = serializers.PrimaryKeyRelatedField(queryset=Company.objects.filter(is_supplier=True)) + + manufacturer = serializers.PrimaryKeyRelatedField(queryset=Company.objects.filter(is_manufacturer=True)) + class Meta: model = SupplierPart fields = [ From f1373e3bea6502ac8907f8e324dbc4e5ea4b99be Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 15 Aug 2020 21:52:32 +1000 Subject: [PATCH 38/58] Improve speed of BomItem API queries - Including the pricing information takes absolutely ages, takes too long!! --- InvenTree/part/api.py | 19 +++++++++++++++++-- InvenTree/part/serializers.py | 6 ++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index 9db4ef5425..f866a08850 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -603,7 +603,20 @@ class BomList(generics.ListCreateAPIView): """ serializer_class = part_serializers.BomItemSerializer - + + def list(self, request, *args, **kwargs): + + queryset = self.filter_queryset(self.get_queryset()) + + serializer = self.get_serializer(queryset, many=True) + + data = serializer.data + + if request.is_ajax(): + return JsonResponse(data, safe=False) + else: + return Response(data) + def get_serializer(self, *args, **kwargs): # Do we wish to include extra detail? @@ -622,8 +635,10 @@ class BomList(generics.ListCreateAPIView): return self.serializer_class(*args, **kwargs) - def get_queryset(self): + def get_queryset(self, *args, **kwargs): + queryset = BomItem.objects.all() + queryset = self.get_serializer_class().setup_eager_loading(queryset) return queryset diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index d9c041c252..c1ecfb5cce 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -305,8 +305,13 @@ class BomItemSerializer(InvenTreeModelSerializer): price_range = serializers.CharField(read_only=True) quantity = serializers.FloatField() + + part = serializers.PrimaryKeyRelatedField(queryset=Part.objects.filter(assembly=True)) part_detail = PartBriefSerializer(source='part', many=False, read_only=True) + + sub_part = serializers.PrimaryKeyRelatedField(queryset=Part.objects.filter(component=True)) + sub_part_detail = PartBriefSerializer(source='sub_part', many=False, read_only=True) validated = serializers.BooleanField(read_only=True, source='is_line_valid') @@ -331,6 +336,7 @@ class BomItemSerializer(InvenTreeModelSerializer): queryset = queryset.prefetch_related('part') queryset = queryset.prefetch_related('part__category') queryset = queryset.prefetch_related('part__stock_items') + queryset = queryset.prefetch_related('sub_part') queryset = queryset.prefetch_related('sub_part__category') queryset = queryset.prefetch_related('sub_part__stock_items') From b27ecf54d76c44ef4131a2b8bc3c21d7e056de35 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 08:29:36 +1000 Subject: [PATCH 39/58] Allow user to set "depth" of exported multi-level BOM --- InvenTree/part/bom.py | 7 ++++--- InvenTree/part/forms.py | 2 ++ InvenTree/part/views.py | 18 +++++++++++++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/InvenTree/part/bom.py b/InvenTree/part/bom.py index 16a8b0b16d..43c6ea7ca7 100644 --- a/InvenTree/part/bom.py +++ b/InvenTree/part/bom.py @@ -40,7 +40,7 @@ def MakeBomTemplate(fmt): return DownloadFile(data, filename) -def ExportBom(part, fmt='csv', cascade=False): +def ExportBom(part, fmt='csv', cascade=False, max_levels=None): """ Export a BOM (Bill of Materials) for a given part. Args: @@ -67,8 +67,9 @@ def ExportBom(part, fmt='csv', cascade=False): bom_items.append(item) - if item.sub_part.assembly: - add_items(item.sub_part.bom_items.all().order_by('id'), level + 1) + if item.sub_part.assembly: + if max_levels is None or level < max_levels: + add_items(item.sub_part.bom_items.all().order_by('id'), level + 1) if cascade: # Cascading (multi-level) BOM diff --git a/InvenTree/part/forms.py b/InvenTree/part/forms.py index 986749f7b3..dbbced352b 100644 --- a/InvenTree/part/forms.py +++ b/InvenTree/part/forms.py @@ -56,6 +56,8 @@ class BomExportForm(forms.Form): cascading = forms.BooleanField(label=_("Cascading"), required=False, initial=False, help_text=_("Download cascading / multi-level BOM")) + levels = forms.IntegerField(label=_("Levels"), required=True, initial=0, help_text=_("Select maximum number of BOM levels to export (0 = all levels)")) + def get_choices(self): """ BOM export format choices """ diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index eda1db923b..9ae5cc8026 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -1392,10 +1392,22 @@ class BomDownload(AjaxView): cascade = str2bool(request.GET.get('cascade', False)) + levels = request.GET.get('levels', None) + + if levels is not None: + try: + levels = int(levels) + + if levels <= 0: + levels = None + + except ValueError: + levels = None + if not IsValidBOMFormat(export_format): export_format = 'csv' - return ExportBom(part, fmt=export_format, cascade=cascade) + return ExportBom(part, fmt=export_format, cascade=cascade, max_levels=levels) def get_data(self): return { @@ -1419,6 +1431,7 @@ class BomExport(AjaxView): # Extract POSTed form data fmt = request.POST.get('file_format', 'csv').lower() cascade = str2bool(request.POST.get('cascading', False)) + levels = request.POST.get('levels', None) try: part = Part.objects.get(pk=self.kwargs['pk']) @@ -1434,6 +1447,9 @@ class BomExport(AjaxView): url += '?file_format=' + fmt url += '&cascade=' + str(cascade) + if levels: + url += '&levels=' + str(levels) + data = { 'form_valid': part is not None, 'url': url, From 97103207b69631e51366f5198e16df188a12ac03 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 08:34:54 +1000 Subject: [PATCH 40/58] PEP fixes --- InvenTree/part/bom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/part/bom.py b/InvenTree/part/bom.py index 43c6ea7ca7..ab7c9ed658 100644 --- a/InvenTree/part/bom.py +++ b/InvenTree/part/bom.py @@ -67,7 +67,7 @@ def ExportBom(part, fmt='csv', cascade=False, max_levels=None): bom_items.append(item) - if item.sub_part.assembly: + if item.sub_part.assembly: if max_levels is None or level < max_levels: add_items(item.sub_part.bom_items.all().order_by('id'), level + 1) From e5406cae240554f67593d0f56fec0891de7601e9 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 09:05:16 +1000 Subject: [PATCH 41/58] More PEP fixes --- InvenTree/part/bom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/part/bom.py b/InvenTree/part/bom.py index ab7c9ed658..47f6bd082e 100644 --- a/InvenTree/part/bom.py +++ b/InvenTree/part/bom.py @@ -67,7 +67,7 @@ def ExportBom(part, fmt='csv', cascade=False, max_levels=None): bom_items.append(item) - if item.sub_part.assembly: + if item.sub_part.assembly: if max_levels is None or level < max_levels: add_items(item.sub_part.bom_items.all().order_by('id'), level + 1) From dd77cc00b7ea6fdab1136a8a8ce41b26b39b2173 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 09:07:27 +1000 Subject: [PATCH 42/58] Add requirement for "blabel" plugin --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index c668612914..354c7ea316 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ wheel>=0.34.2 # Wheel Django==3.0.7 # Django package pillow==7.1.0 # Image manipulation +blabel==0.1.3 # Simple PDF label printing djangorestframework==3.10.3 # DRF framework django-dbbackup==3.3.0 # Database backup / restore functionality django-cors-headers==3.2.0 # CORS headers extension for DRF From a45902bd4fdaed1db244e65d8341aba7ca3be70e Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 09:28:12 +1000 Subject: [PATCH 43/58] Add "label" app --- InvenTree/InvenTree/helpers.py | 53 ++++++++++++ InvenTree/InvenTree/settings.py | 1 + InvenTree/label/__init__.py | 0 InvenTree/label/admin.py | 3 + InvenTree/label/apps.py | 5 ++ InvenTree/label/migrations/0001_initial.py | 30 +++++++ InvenTree/label/migrations/__init__.py | 0 InvenTree/label/models.py | 93 ++++++++++++++++++++++ InvenTree/label/tests.py | 3 + InvenTree/label/views.py | 3 + Makefile | 4 +- 11 files changed, 193 insertions(+), 2 deletions(-) create mode 100644 InvenTree/label/__init__.py create mode 100644 InvenTree/label/admin.py create mode 100644 InvenTree/label/apps.py create mode 100644 InvenTree/label/migrations/0001_initial.py create mode 100644 InvenTree/label/migrations/__init__.py create mode 100644 InvenTree/label/models.py create mode 100644 InvenTree/label/tests.py create mode 100644 InvenTree/label/views.py diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index 9880662e63..dbd59eecb0 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -383,3 +383,56 @@ def ExtractSerialNumbers(serials, expected_quantity): raise ValidationError([_("Number of unique serial number ({s}) must match quantity ({q})".format(s=len(numbers), q=expected_quantity))]) return numbers + + +def validateFilterString(value): + """ + Validate that a provided filter string looks like a list of comma-separated key=value pairs + + These should nominally match to a valid database filter based on the model being filtered. + + e.g. "category=6, IPN=12" + e.g. "part__name=widget" + + The ReportTemplate class uses the filter string to work out which items a given report applies to. + For example, an acceptance test report template might only apply to stock items with a given IPN, + so the string could be set to: + + filters = "IPN = ACME0001" + + Returns a map of key:value pairs + """ + + # Empty results map + results = {} + + value = str(value).strip() + + if not value or len(value) == 0: + return results + + groups = value.split(',') + + for group in groups: + group = group.strip() + + pair = group.split('=') + + if not len(pair) == 2: + raise ValidationError( + "Invalid group: {g}".format(g=group) + ) + + k, v = pair + + k = k.strip() + v = v.strip() + + if not k or not v: + raise ValidationError( + "Invalid group: {g}".format(g=group) + ) + + results[k] = v + + return results \ No newline at end of file diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index fb68f65497..d3a5ee919d 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -130,6 +130,7 @@ INSTALLED_APPS = [ 'build.apps.BuildConfig', 'common.apps.CommonConfig', 'company.apps.CompanyConfig', + 'label.apps.LabelConfig', 'order.apps.OrderConfig', 'part.apps.PartConfig', 'report.apps.ReportConfig', diff --git a/InvenTree/label/__init__.py b/InvenTree/label/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/InvenTree/label/admin.py b/InvenTree/label/admin.py new file mode 100644 index 0000000000..8c38f3f3da --- /dev/null +++ b/InvenTree/label/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/InvenTree/label/apps.py b/InvenTree/label/apps.py new file mode 100644 index 0000000000..ea4fa152ff --- /dev/null +++ b/InvenTree/label/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class LabelConfig(AppConfig): + name = 'label' diff --git a/InvenTree/label/migrations/0001_initial.py b/InvenTree/label/migrations/0001_initial.py new file mode 100644 index 0000000000..e960bcef67 --- /dev/null +++ b/InvenTree/label/migrations/0001_initial.py @@ -0,0 +1,30 @@ +# Generated by Django 3.0.7 on 2020-08-15 23:27 + +import InvenTree.helpers +import django.core.validators +from django.db import migrations, models +import label.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='StockItemLabel', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(help_text='Label name', max_length=100, unique=True)), + ('description', models.CharField(blank=True, help_text='Label description', max_length=250, null=True)), + ('label', models.FileField(help_text='Label template file', upload_to=label.models.rename_label, validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['html'])])), + ('filters', models.CharField(blank=True, help_text='Query filters (comma-separated list of key=value pairs', max_length=250, validators=[InvenTree.helpers.validateFilterString])), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/InvenTree/label/migrations/__init__.py b/InvenTree/label/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/InvenTree/label/models.py b/InvenTree/label/models.py new file mode 100644 index 0000000000..74c811a633 --- /dev/null +++ b/InvenTree/label/models.py @@ -0,0 +1,93 @@ +""" +Label printing models +""" + +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +import os + +from blabel import LabelWriter + +from django.db import models +from django.core.validators import FileExtensionValidator + +from django.utils.translation import gettext_lazy as _ + +from InvenTree.helpers import validateFilterString + +from stock.models import StockItem + + +def rename_label(instance, filename): + """ Place the label file into the correct subdirectory """ + + filename = os.path.basename(filename) + + return os.path.join('label', 'template', instance.SUBDIR, filename) + + +class LabelTemplate(models.Model): + """ + Base class for generic, filterable labels. + """ + + class Meta: + abstract = True + + # Each class of label files will be stored in a separate subdirectory + SUBDIR = "label" + + name = models.CharField( + unique=True, + blank=False, max_length=100, + help_text=_('Label name'), + ) + + description = models.CharField(max_length=250, help_text=_('Label description'), blank=True, null=True) + + label = models.FileField( + upload_to=rename_label, + blank=False, null=False, + help_text=_('Label template file'), + validators=[FileExtensionValidator(allowed_extensions=['html'])], + ) + + filters = models.CharField( + blank=True, max_length=250, + help_text=_('Query filters (comma-separated list of key=value pairs'), + validators=[validateFilterString] + ) + + def get_record_data(self, items): + + return [] + + def render(self, items, **kwargs): + + records = self.get_record_data(items) + + writer = LabelWriter(self.label.filename) + + writer.write_label(records, 'out.pdf') + + +class StockItemLabel(LabelTemplate): + """ + Template for printing StockItem labels + """ + + SUBDIR = "stockitem" + + def matches_stock_item(self, item): + """ + Test if this label template matches a given StockItem object + """ + + filters = validateFilterString(self.filters) + + items = StockItem.objects.filter(**filters) + + items = items.filter(pk=item.pk) + + return items.exists() diff --git a/InvenTree/label/tests.py b/InvenTree/label/tests.py new file mode 100644 index 0000000000..7ce503c2dd --- /dev/null +++ b/InvenTree/label/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/InvenTree/label/views.py b/InvenTree/label/views.py new file mode 100644 index 0000000000..91ea44a218 --- /dev/null +++ b/InvenTree/label/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/Makefile b/Makefile index 0072e1ad9c..cc3a3043a6 100644 --- a/Makefile +++ b/Makefile @@ -51,12 +51,12 @@ style: # Run unit tests test: cd InvenTree && python3 manage.py check - cd InvenTree && python3 manage.py test barcode build common company order part report stock InvenTree + cd InvenTree && python3 manage.py test barcode build common company label order part report stock InvenTree # Run code coverage coverage: cd InvenTree && python3 manage.py check - coverage run InvenTree/manage.py test barcode build common company order part report stock InvenTree + coverage run InvenTree/manage.py test barcode build common company label order part report stock InvenTree coverage html # Install packages required to generate code docs From aefd70ce490d3a0673b6b82c6efb1dd046bcf46a Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 09:29:45 +1000 Subject: [PATCH 44/58] Add admin interface for StockItemLabel --- InvenTree/label/admin.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/InvenTree/label/admin.py b/InvenTree/label/admin.py index 8c38f3f3da..bc03e122b6 100644 --- a/InvenTree/label/admin.py +++ b/InvenTree/label/admin.py @@ -1,3 +1,14 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + from django.contrib import admin -# Register your models here. +from .models import StockItemLabel + + +class StockItemLabelAdmin(admin.ModelAdmin): + + list_display = ('name', 'description', 'label') + + +admin.site.register(StockItemLabel, StockItemLabelAdmin) From 18b3fd3256fda430d9079b3f6797cbb170710ace Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 10:24:15 +1000 Subject: [PATCH 45/58] Add context data to StockItemLabel model --- InvenTree/label/models.py | 36 +++++++++++++++++++++++++++++++++--- InvenTree/stock/models.py | 7 +++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/InvenTree/label/models.py b/InvenTree/label/models.py index 74c811a633..6da973d85f 100644 --- a/InvenTree/label/models.py +++ b/InvenTree/label/models.py @@ -14,7 +14,7 @@ from django.core.validators import FileExtensionValidator from django.utils.translation import gettext_lazy as _ -from InvenTree.helpers import validateFilterString +from InvenTree.helpers import validateFilterString, normalize from stock.models import StockItem @@ -38,6 +38,10 @@ class LabelTemplate(models.Model): # Each class of label files will be stored in a separate subdirectory SUBDIR = "label" + @property + def template(self): + return self.label.path + name = models.CharField( unique=True, blank=False, max_length=100, @@ -60,6 +64,9 @@ class LabelTemplate(models.Model): ) def get_record_data(self, items): + """ + Return a list of dict objects, one for each item. + """ return [] @@ -67,9 +74,9 @@ class LabelTemplate(models.Model): records = self.get_record_data(items) - writer = LabelWriter(self.label.filename) + writer = LabelWriter(self.template) - writer.write_label(records, 'out.pdf') + writer.write_labels(records, 'out.html') class StockItemLabel(LabelTemplate): @@ -91,3 +98,26 @@ class StockItemLabel(LabelTemplate): items = items.filter(pk=item.pk) return items.exists() + + def get_record_data(self, items): + """ + Generate context data for each provided StockItem + """ + records = [] + + for item in items: + + # Add some basic information + records.append({ + 'item': item, + 'part': item.part, + 'name': item.part.name, + 'ipn': item.part.IPN, + 'quantity': normalize(item.quantity), + 'serial': item.serial, + 'uid': item.uid, + 'pk': item.pk, + 'qr_data': item.format_short_barcode(), + }) + + return records diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index 0a9fc6b8bd..664593e600 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -302,6 +302,13 @@ class StockItem(MPTTModel): } ) + def format_short_barcode(self): + """ + Return a short barcode + """ + + return "stockid={pk}".format(pk=self.pk) + uid = models.CharField(blank=True, max_length=128, help_text=("Unique identifier field")) parent = TreeForeignKey( From 2b1d6c268c35eb2e7b3e6f69fbdf937bbddc9e41 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 10:29:03 +1000 Subject: [PATCH 46/58] Render to an in-memory PDF --- InvenTree/label/models.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/InvenTree/label/models.py b/InvenTree/label/models.py index 6da973d85f..c506d796db 100644 --- a/InvenTree/label/models.py +++ b/InvenTree/label/models.py @@ -6,6 +6,7 @@ Label printing models from __future__ import unicode_literals import os +import io from blabel import LabelWriter @@ -70,13 +71,31 @@ class LabelTemplate(models.Model): return [] - def render(self, items, **kwargs): + def render_to_file(self, filename, items, **kwargs): + """ + Render labels to a PDF file + """ records = self.get_record_data(items) writer = LabelWriter(self.template) - writer.write_labels(records, 'out.html') + writer.write_labels(records, filename) + + def render(self, items, **kwargs): + """ + Render labels to an in-memory PDF object, and return it + """ + + records = self.get_record_data(items) + + writer = LabelWriter(self.template) + + buffer = io.BytesIO() + + writer.write_labels(records, buffer) + + return buffer class StockItemLabel(LabelTemplate): From cdde0f8c433d344c0725af5fe090f6ed99891e23 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 11:12:21 +1000 Subject: [PATCH 47/58] Add URL endpoint for downloading PDF labels --- InvenTree/stock/urls.py | 1 + InvenTree/stock/views.py | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/InvenTree/stock/urls.py b/InvenTree/stock/urls.py index b48795b86e..c886f8ccaa 100644 --- a/InvenTree/stock/urls.py +++ b/InvenTree/stock/urls.py @@ -59,6 +59,7 @@ stock_urls = [ url(r'^item/new/?', views.StockItemCreate.as_view(), name='stock-item-create'), url(r'^item/test-report-download/', views.StockItemTestReportDownload.as_view(), name='stock-item-test-report-download'), + url(r'^item/print-stock-labels/', views.StockItemPrintLabels.as_view(), name='stock-item-print-labels'), # URLs for StockItem attachments url(r'^item/attachment/', include([ diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index 56a3abaaad..5a5cba9126 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -28,6 +28,7 @@ from datetime import datetime from company.models import Company, SupplierPart from part.models import Part from report.models import TestReport +from label.models import StockItemLabel from .models import StockItem, StockLocation, StockItemTracking, StockItemAttachment, StockItemTestResult from .admin import StockItemResource @@ -295,6 +296,44 @@ class StockItemReturnToStock(AjaxUpdateView): return self.renderJsonResponse(request, self.get_form(), data) +class StockItemPrintLabels(AjaxView): + """ + View for printing labels and returning a PDF + + Requires the following arguments to be passed as URL params: + + items: List of valid StockItem pk values + label: Valid pk of a StockItemLabel template + """ + + def get(self, request, *args, **kwargs): + + label = request.GET.get('label', None) + + try: + label = StockItemLabel.objects.get(pk=label) + except (ValueError, StockItemLabel.DoesNotExist): + raise ValidationError({'label': 'Invalid label ID'}) + + item_pks = request.GET.getlist('items[]') + + items = [] + + for pk in item_pks: + try: + item = StockItem.objects.get(pk=pk) + items.append(item) + except (ValueError, StockItem.DoesNotExist): + pass + + if len(items) == 0: + raise ValidationError({'items': 'Must provide valid stockitems'}) + + pdf = label.render(items).getbuffer() + + return DownloadFile(pdf, 'stock_labels.pdf', content_type='application/pdf') + + class StockItemDeleteTestData(AjaxUpdateView): """ View for deleting all test data From 30e24f19d993a15d8ab0b5bc522cd5ced76871dd Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 11:13:17 +1000 Subject: [PATCH 48/58] PEP fixes --- InvenTree/InvenTree/helpers.py | 2 +- InvenTree/label/tests.py | 2 -- InvenTree/label/views.py | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index dbd59eecb0..bf7e9083b5 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -435,4 +435,4 @@ def validateFilterString(value): results[k] = v - return results \ No newline at end of file + return results diff --git a/InvenTree/label/tests.py b/InvenTree/label/tests.py index 7ce503c2dd..a39b155ac3 100644 --- a/InvenTree/label/tests.py +++ b/InvenTree/label/tests.py @@ -1,3 +1 @@ -from django.test import TestCase - # Create your tests here. diff --git a/InvenTree/label/views.py b/InvenTree/label/views.py index 91ea44a218..60f00ef0ef 100644 --- a/InvenTree/label/views.py +++ b/InvenTree/label/views.py @@ -1,3 +1 @@ -from django.shortcuts import render - # Create your views here. From 1807ba4e7b14f788816f9dd03819544cbb363fc4 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 12:10:58 +1000 Subject: [PATCH 49/58] Add form for selecting label template for a StockItem --- InvenTree/label/models.py | 7 +++ InvenTree/stock/forms.py | 31 +++++++++++++ .../stock/templates/stock/item_base.html | 12 +++++ InvenTree/stock/urls.py | 1 + InvenTree/stock/views.py | 44 +++++++++++++++++++ 5 files changed, 95 insertions(+) diff --git a/InvenTree/label/models.py b/InvenTree/label/models.py index c506d796db..6faf966d7e 100644 --- a/InvenTree/label/models.py +++ b/InvenTree/label/models.py @@ -43,6 +43,12 @@ class LabelTemplate(models.Model): def template(self): return self.label.path + def __str__(self): + return "{n} - {d}".format( + n=self.name, + d=self.description + ) + name = models.CharField( unique=True, blank=False, max_length=100, @@ -137,6 +143,7 @@ class StockItemLabel(LabelTemplate): 'uid': item.uid, 'pk': item.pk, 'qr_data': item.format_short_barcode(), + 'tests': item.testResultMap() }) return records diff --git a/InvenTree/stock/forms.py b/InvenTree/stock/forms.py index 06d90e33df..234da6d53b 100644 --- a/InvenTree/stock/forms.py +++ b/InvenTree/stock/forms.py @@ -178,6 +178,37 @@ class SerializeStockForm(HelperForm): ] +class StockItemLabelSelectForm(HelperForm): + """ Form for selecting a label template for a StockItem """ + + label = forms.ChoiceField( + label=_('Label'), + help_text=_('Select test report template') + ) + + class Meta: + model = StockItem + fields = [ + 'label', + ] + + def get_label_choices(self, labels): + + choices = [] + + if len(labels) > 0: + for label in labels: + choices.append((label.pk, label)) + + return choices + + def __init__(self, labels, *args, **kwargs): + + super().__init__(*args, **kwargs) + + self.fields['label'].choices = self.get_label_choices(labels) + + class TestReportFormatForm(HelperForm): """ Form for selection a test report template """ diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index ce055d65c5..a7bc263bbf 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -129,6 +129,9 @@ InvenTree | {% trans "Stock Item" %} - {{ item }} {% endif %} + {% endblock %} @@ -314,6 +317,15 @@ $("#stock-test-report").click(function() { }); {% endif %} +$("#stock-print-label").click(function() { + launchModalForm( + "{% url 'stock-item-label-select' item.id %}", + { + follow: true, + } + ) +}); + $("#stock-duplicate").click(function() { launchModalForm( "{% url 'stock-item-create' %}", diff --git a/InvenTree/stock/urls.py b/InvenTree/stock/urls.py index c886f8ccaa..51067b57de 100644 --- a/InvenTree/stock/urls.py +++ b/InvenTree/stock/urls.py @@ -29,6 +29,7 @@ stock_item_detail_urls = [ url(r'^add_tracking/', views.StockItemTrackingCreate.as_view(), name='stock-tracking-create'), url(r'^test-report-select/', views.StockItemTestReportSelect.as_view(), name='stock-item-test-report-select'), + url(r'^label-select/', views.StockItemSelectLabels.as_view(), name='stock-item-label-select'), url(r'^test/', views.StockItemDetail.as_view(template_name='stock/item_tests.html'), name='stock-item-test-results'), url(r'^children/', views.StockItemDetail.as_view(template_name='stock/item_childs.html'), name='stock-item-children'), diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index 5a5cba9126..1c9b78a3f0 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -296,6 +296,50 @@ class StockItemReturnToStock(AjaxUpdateView): return self.renderJsonResponse(request, self.get_form(), data) +class StockItemSelectLabels(AjaxView): + """ + View for selecting a template for printing labels for one (or more) StockItem objects + """ + + model = StockItem + ajax_form_title = _('Select Label Template') + + def get_form(self): + + item = StockItem.objects.get(pk=self.kwargs['pk']) + + labels = [] + + for label in StockItemLabel.objects.all(): + if label.matches_stock_item(item): + labels.append(label) + + return StockForms.StockItemLabelSelectForm(labels) + + def post(self, request, *args, **kwargs): + + label = request.POST.get('label', None) + + try: + label = StockItemLabel.objects.get(pk=label) + except (ValueError, StockItemLabel.DoesNotExist): + raise ValidationError({'label': _("Select valid label")}) + + stock_item = StockItem.objects.get(pk=self.kwargs['pk']) + + url = reverse('stock-item-print-labels') + + url += '?label={pk}'.format(pk=label.pk) + url += '&items[]={pk}'.format(pk=stock_item.pk) + + data = { + 'form_valid': True, + 'url': url, + } + + return self.renderJsonResponse(request, self.get_form(), data=data) + + class StockItemPrintLabels(AjaxView): """ View for printing labels and returning a PDF From 2f5e3efada4b5f4efda6863c0d1d19b581098f75 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 12:11:22 +1000 Subject: [PATCH 50/58] Update translations --- InvenTree/locale/de/LC_MESSAGES/django.mo | Bin 50558 -> 50288 bytes InvenTree/locale/de/LC_MESSAGES/django.po | 835 +++++++++++++--------- InvenTree/locale/en/LC_MESSAGES/django.po | 777 +++++++++++--------- InvenTree/locale/es/LC_MESSAGES/django.po | 777 +++++++++++--------- 4 files changed, 1357 insertions(+), 1032 deletions(-) diff --git a/InvenTree/locale/de/LC_MESSAGES/django.mo b/InvenTree/locale/de/LC_MESSAGES/django.mo index 766a862f9d50bc0ab1252c60a0bf54afb543b655..758fa8c4cd300c45d252a01eb8f6f23e28b66a87 100644 GIT binary patch delta 15632 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 delta 15920 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\n" "Language-Team: C \n" @@ -83,7 +83,7 @@ msgstr "Datei zum Anhängen auswählen" msgid "File comment" msgstr "Datei-Kommentar" -#: InvenTree/models.py:68 templates/js/stock.html:669 +#: InvenTree/models.py:68 templates/js/stock.html:682 msgid "User" msgstr "Benutzer" @@ -97,24 +97,24 @@ msgstr "Name" msgid "Description (optional)" msgstr "Firmenbeschreibung" -#: InvenTree/settings.py:330 +#: InvenTree/settings.py:335 msgid "English" msgstr "Englisch" -#: InvenTree/settings.py:331 +#: InvenTree/settings.py:336 msgid "German" msgstr "Deutsch" -#: InvenTree/settings.py:332 +#: InvenTree/settings.py:337 msgid "French" msgstr "Französisch" -#: InvenTree/settings.py:333 +#: InvenTree/settings.py:338 msgid "Polish" msgstr "Polnisch" #: InvenTree/status_codes.py:94 InvenTree/status_codes.py:135 -#: InvenTree/status_codes.py:235 +#: InvenTree/status_codes.py:222 msgid "Pending" msgstr "Ausstehend" @@ -122,59 +122,50 @@ msgstr "Ausstehend" msgid "Placed" msgstr "Platziert" -#: InvenTree/status_codes.py:96 InvenTree/status_codes.py:238 +#: InvenTree/status_codes.py:96 InvenTree/status_codes.py:225 msgid "Complete" msgstr "Fertig" #: InvenTree/status_codes.py:97 InvenTree/status_codes.py:137 -#: InvenTree/status_codes.py:237 +#: InvenTree/status_codes.py:224 msgid "Cancelled" msgstr "Storniert" #: InvenTree/status_codes.py:98 InvenTree/status_codes.py:138 -#: InvenTree/status_codes.py:179 +#: InvenTree/status_codes.py:175 msgid "Lost" msgstr "Verloren" #: InvenTree/status_codes.py:99 InvenTree/status_codes.py:139 -#: InvenTree/status_codes.py:181 +#: InvenTree/status_codes.py:177 msgid "Returned" msgstr "Zurückgegeben" -#: InvenTree/status_codes.py:136 InvenTree/status_codes.py:182 -#: order/templates/order/sales_order_base.html:98 +#: InvenTree/status_codes.py:136 order/templates/order/sales_order_base.html:98 msgid "Shipped" msgstr "Versendet" -#: InvenTree/status_codes.py:175 +#: InvenTree/status_codes.py:171 msgid "OK" msgstr "OK" -#: InvenTree/status_codes.py:176 +#: InvenTree/status_codes.py:172 msgid "Attention needed" msgstr "erfordert Eingriff" -#: InvenTree/status_codes.py:177 +#: InvenTree/status_codes.py:173 msgid "Damaged" msgstr "Beschädigt" -#: InvenTree/status_codes.py:178 +#: InvenTree/status_codes.py:174 msgid "Destroyed" msgstr "Zerstört" -#: InvenTree/status_codes.py:180 +#: InvenTree/status_codes.py:176 msgid "Rejected" msgstr "" -#: InvenTree/status_codes.py:183 -msgid "Used for Build" -msgstr "Verwendet für Bau" - -#: InvenTree/status_codes.py:184 -msgid "Installed in Stock Item" -msgstr "In Lagerobjekt installiert" - -#: InvenTree/status_codes.py:236 build/templates/build/allocate.html:349 +#: InvenTree/status_codes.py:223 build/templates/build/allocate.html:349 #: order/templates/order/sales_order_detail.html:220 #: part/templates/part/tabs.html:23 templates/js/build.html:120 msgid "Allocated" @@ -265,7 +256,7 @@ msgstr "Standort-Details" msgid "Serial numbers" msgstr "Seriennummer" -#: build/forms.py:64 stock/forms.py:93 +#: build/forms.py:64 stock/forms.py:105 msgid "Enter unique serial numbers (or leave blank)" msgstr "Eindeutige Seriennummern eingeben (oder leer lassen)" @@ -306,7 +297,7 @@ msgstr "Eltern-Bau, dem dieser Bau zugewiesen ist" #: part/templates/part/set_category.html:13 templates/js/barcode.html:336 #: templates/js/bom.html:135 templates/js/build.html:41 #: templates/js/company.html:109 templates/js/part.html:120 -#: templates/js/stock.html:424 +#: templates/js/stock.html:425 msgid "Part" msgstr "Teil" @@ -350,7 +341,7 @@ msgstr "Bau-Status" msgid "Build status code" msgstr "Bau-Statuscode" -#: build/models.py:136 stock/models.py:374 +#: build/models.py:136 stock/models.py:376 msgid "Batch Code" msgstr "Losnummer" @@ -362,21 +353,21 @@ msgstr "Chargennummer für diese Bau-Ausgabe" #: company/templates/company/supplier_part_base.html:60 #: company/templates/company/supplier_part_detail.html:24 #: part/templates/part/detail.html:74 part/templates/part/part_base.html:86 -#: stock/models.py:368 stock/templates/stock/item_base.html:230 +#: stock/models.py:370 stock/templates/stock/item_base.html:237 msgid "External Link" msgstr "Externer Link" -#: build/models.py:156 stock/models.py:370 +#: build/models.py:156 stock/models.py:372 msgid "Link to external URL" msgstr "Link zu einer externen URL" -#: build/models.py:160 build/templates/build/tabs.html:14 company/models.py:307 +#: build/models.py:160 build/templates/build/tabs.html:14 company/models.py:310 #: company/templates/company/tabs.html:33 order/templates/order/po_tabs.html:15 #: order/templates/order/purchase_order_detail.html:200 #: order/templates/order/so_tabs.html:23 part/templates/part/tabs.html:64 -#: stock/models.py:436 stock/models.py:1265 stock/templates/stock/tabs.html:26 +#: stock/models.py:438 stock/models.py:1287 stock/templates/stock/tabs.html:26 #: templates/js/barcode.html:391 templates/js/bom.html:229 -#: templates/js/stock.html:113 templates/js/stock.html:513 +#: templates/js/stock.html:114 templates/js/stock.html:526 msgid "Notes" msgstr "Notizen" @@ -407,15 +398,15 @@ msgstr "Anzahl muss größer null sein" msgid "Quantity must be 1 for serialized stock" msgstr "Anzahl muss 1 für Objekte mit Seriennummer sein" -#: build/models.py:512 +#: build/models.py:511 msgid "Build to allocate parts" msgstr "Bau starten um Teile zuzuweisen" -#: build/models.py:519 +#: build/models.py:518 msgid "Stock Item to allocate to build" msgstr "Lagerobjekt dem Bau zuweisen" -#: build/models.py:532 +#: build/models.py:531 msgid "Stock quantity to allocate to build" msgstr "Lagerobjekt-Anzahl dem Bau zuweisen" @@ -442,8 +433,8 @@ msgstr "Neues Lagerobjekt" #: build/templates/build/allocate.html:161 #: order/templates/order/sales_order_detail.html:68 -#: order/templates/order/sales_order_detail.html:150 stock/models.py:362 -#: stock/templates/stock/item_base.html:146 +#: order/templates/order/sales_order_detail.html:150 stock/models.py:364 +#: stock/templates/stock/item_base.html:153 msgid "Serial Number" msgstr "Seriennummer" @@ -460,18 +451,18 @@ msgstr "Seriennummer" #: part/templates/part/allocation.html:49 #: stock/templates/stock/item_base.html:26 #: stock/templates/stock/item_base.html:32 -#: stock/templates/stock/item_base.html:152 +#: stock/templates/stock/item_base.html:159 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.html:338 #: templates/js/bom.html:172 templates/js/build.html:52 -#: templates/js/stock.html:660 +#: templates/js/stock.html:673 msgid "Quantity" msgstr "Anzahl" #: build/templates/build/allocate.html:177 #: build/templates/build/auto_allocate.html:20 -#: stock/templates/stock/item_base.html:184 +#: stock/templates/stock/item_base.html:191 #: stock/templates/stock/stock_adjust.html:17 templates/js/barcode.html:337 -#: templates/js/stock.html:495 +#: templates/js/stock.html:508 msgid "Location" msgstr "Standort" @@ -497,7 +488,7 @@ msgstr "Keine BOM-Einträge gefunden" #: templates/js/bom.html:157 templates/js/company.html:60 #: templates/js/order.html:157 templates/js/order.html:230 #: templates/js/part.html:176 templates/js/part.html:355 -#: templates/js/stock.html:445 templates/js/stock.html:641 +#: templates/js/stock.html:440 templates/js/stock.html:654 msgid "Description" msgstr "Beschreibung" @@ -507,8 +498,8 @@ msgstr "Beschreibung" msgid "Reference" msgstr "Referenz" -#: build/templates/build/allocate.html:338 part/models.py:1269 -#: templates/js/part.html:359 templates/js/table_filters.html:90 +#: build/templates/build/allocate.html:338 part/models.py:1270 +#: templates/js/part.html:359 templates/js/table_filters.html:100 msgid "Required" msgstr "benötigt" @@ -552,7 +543,7 @@ msgstr "Keine Lagerobjekt gefunden, die diesem Bau zugewiesen werden können" #: build/templates/build/build_base.html:8 #: build/templates/build/build_base.html:34 #: build/templates/build/complete.html:6 -#: stock/templates/stock/item_base.html:209 templates/js/build.html:33 +#: stock/templates/stock/item_base.html:216 templates/js/build.html:33 #: templates/navbar.html:12 msgid "Build" msgstr "Bau" @@ -572,9 +563,9 @@ msgstr "Bau-Status" #: build/templates/build/build_base.html:80 #: build/templates/build/detail.html:42 #: order/templates/order/receive_parts.html:24 -#: stock/templates/stock/item_base.html:262 templates/js/barcode.html:42 +#: stock/templates/stock/item_base.html:269 templates/js/barcode.html:42 #: templates/js/build.html:57 templates/js/order.html:162 -#: templates/js/order.html:235 templates/js/stock.html:482 +#: templates/js/order.html:235 templates/js/stock.html:495 msgid "Status" msgstr "Status" @@ -584,7 +575,7 @@ msgstr "Status" #: order/templates/order/sales_order_notes.html:10 #: order/templates/order/sales_order_ship.html:25 #: part/templates/part/allocation.html:27 -#: stock/templates/stock/item_base.html:172 templates/js/order.html:209 +#: stock/templates/stock/item_base.html:179 templates/js/order.html:209 msgid "Sales Order" msgstr "Bestellung" @@ -653,7 +644,7 @@ msgid "Stock can be taken from any available location." msgstr "Bestand kann jedem verfügbaren Lagerort entnommen werden." #: build/templates/build/detail.html:48 -#: stock/templates/stock/item_base.html:202 templates/js/stock.html:490 +#: stock/templates/stock/item_base.html:209 templates/js/stock.html:503 msgid "Batch" msgstr "Los" @@ -757,7 +748,7 @@ msgstr "Zuweisung aufheben" msgid "Confirm unallocation of build stock" msgstr "Zuweisungsaufhebung bestätigen" -#: build/views.py:162 stock/views.py:286 +#: build/views.py:162 stock/views.py:404 msgid "Check the confirmation box" msgstr "Bestätigungsbox bestätigen" @@ -765,7 +756,7 @@ msgstr "Bestätigungsbox bestätigen" msgid "Complete Build" msgstr "Bau fertigstellen" -#: build/views.py:201 stock/views.py:1118 stock/views.py:1232 +#: build/views.py:201 stock/views.py:1236 stock/views.py:1350 msgid "Next available serial number is" msgstr "" @@ -783,7 +774,7 @@ msgstr "Baufertigstellung bestätigen" msgid "Invalid location selected" msgstr "Ungültige Ortsauswahl" -#: build/views.py:300 stock/views.py:1268 +#: build/views.py:300 stock/views.py:1386 #, python-brace-format msgid "The following serial numbers already exist: ({sn})" msgstr "Die folgende Seriennummer existiert bereits: ({sn})" @@ -878,117 +869,117 @@ msgstr "Währung bearbeiten" msgid "Delete Currency" msgstr "Währung entfernen" -#: company/models.py:83 company/models.py:84 +#: company/models.py:86 company/models.py:87 msgid "Company name" msgstr "Firmenname" -#: company/models.py:86 +#: company/models.py:89 #, fuzzy #| msgid "Part description" msgid "Company description" msgstr "Beschreibung des Teils" -#: company/models.py:86 +#: company/models.py:89 msgid "Description of the company" msgstr "Firmenbeschreibung" -#: company/models.py:88 company/templates/company/company_base.html:48 +#: company/models.py:91 company/templates/company/company_base.html:48 #: templates/js/company.html:65 msgid "Website" msgstr "Website" -#: company/models.py:88 +#: company/models.py:91 msgid "Company website URL" msgstr "Firmenwebsite" -#: company/models.py:91 company/templates/company/company_base.html:55 +#: company/models.py:94 company/templates/company/company_base.html:55 msgid "Address" msgstr "Adresse" -#: company/models.py:92 +#: company/models.py:95 msgid "Company address" msgstr "Firmenadresse" -#: company/models.py:95 +#: company/models.py:98 #, fuzzy #| msgid "Contact phone number" msgid "Phone number" msgstr "Kontakt-Tel." -#: company/models.py:96 +#: company/models.py:99 msgid "Contact phone number" msgstr "Kontakt-Tel." -#: company/models.py:98 company/templates/company/company_base.html:69 +#: company/models.py:101 company/templates/company/company_base.html:69 msgid "Email" msgstr "Email" -#: company/models.py:98 +#: company/models.py:101 msgid "Contact email address" msgstr "Kontakt-Email" -#: company/models.py:101 company/templates/company/company_base.html:76 +#: company/models.py:104 company/templates/company/company_base.html:76 msgid "Contact" msgstr "Kontakt" -#: company/models.py:102 +#: company/models.py:105 msgid "Point of contact" msgstr "Anlaufstelle" -#: company/models.py:104 +#: company/models.py:107 msgid "Link to external company information" msgstr "Link auf externe Firmeninformation" -#: company/models.py:116 +#: company/models.py:119 msgid "Do you sell items to this company?" msgstr "Verkaufen Sie Teile an diese Firma?" -#: company/models.py:118 +#: company/models.py:121 msgid "Do you purchase items from this company?" msgstr "Kaufen Sie Teile von dieser Firma?" -#: company/models.py:120 +#: company/models.py:123 msgid "Does this company manufacture parts?" msgstr "Produziert diese Firma Teile?" -#: company/models.py:276 stock/models.py:322 -#: stock/templates/stock/item_base.html:138 +#: company/models.py:279 stock/models.py:324 +#: stock/templates/stock/item_base.html:145 msgid "Base Part" msgstr "Basisteil" -#: company/models.py:281 +#: company/models.py:284 msgid "Select part" msgstr "Teil auswählen" -#: company/models.py:287 +#: company/models.py:290 msgid "Select supplier" msgstr "Zulieferer auswählen" -#: company/models.py:290 +#: company/models.py:293 msgid "Supplier stock keeping unit" msgstr "Stock Keeping Units (SKU) des Zulieferers" -#: company/models.py:297 +#: company/models.py:300 msgid "Select manufacturer" msgstr "Hersteller auswählen" -#: company/models.py:301 +#: company/models.py:304 msgid "Manufacturer part number" msgstr "Hersteller-Teilenummer" -#: company/models.py:303 +#: company/models.py:306 msgid "URL for external supplier part link" msgstr "Teil-URL des Zulieferers" -#: company/models.py:305 +#: company/models.py:308 msgid "Supplier part description" msgstr "Zuliefererbeschreibung des Teils" -#: company/models.py:309 +#: company/models.py:312 msgid "Minimum charge (e.g. stocking fee)" msgstr "Mindestpreis" -#: company/models.py:311 +#: company/models.py:314 msgid "Part packaging" msgstr "Teile-Packaging" @@ -1025,14 +1016,14 @@ msgstr "Hersteller" #: company/templates/company/supplier_part_detail.html:21 order/models.py:148 #: order/templates/order/order_base.html:74 #: order/templates/order/order_wizard/select_pos.html:30 -#: stock/templates/stock/item_base.html:237 templates/js/company.html:52 +#: stock/templates/stock/item_base.html:244 templates/js/company.html:52 #: templates/js/company.html:134 templates/js/order.html:144 msgid "Supplier" msgstr "Zulieferer" #: company/templates/company/detail.html:26 order/models.py:314 -#: order/templates/order/sales_order_base.html:73 stock/models.py:357 -#: stock/models.py:358 stock/templates/stock/item_base.html:159 +#: order/templates/order/sales_order_base.html:73 stock/models.py:359 +#: stock/models.py:360 stock/templates/stock/item_base.html:166 #: templates/js/company.html:44 templates/js/order.html:217 msgid "Customer" msgstr "Kunde" @@ -1087,7 +1078,7 @@ msgstr "Neuen Hersteller anlegen" msgid "Supplier Stock" msgstr "Zuliefererbestand" -#: company/templates/company/detail_stock.html:34 +#: company/templates/company/detail_stock.html:35 #: company/templates/company/supplier_part_stock.html:33 #: part/templates/part/stock.html:53 templates/stock_table.html:5 msgid "Export" @@ -1146,8 +1137,8 @@ msgid "New Sales Order" msgstr "Neuer Auftrag" #: company/templates/company/supplier_part_base.html:6 -#: company/templates/company/supplier_part_base.html:19 stock/models.py:331 -#: stock/templates/stock/item_base.html:242 templates/js/company.html:150 +#: company/templates/company/supplier_part_base.html:19 stock/models.py:333 +#: stock/templates/stock/item_base.html:249 templates/js/company.html:150 msgid "Supplier Part" msgstr "Zulieferer-Teil" @@ -1246,7 +1237,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:203 -#: templates/js/stock.html:453 templates/navbar.html:11 +#: templates/js/stock.html:448 templates/navbar.html:11 msgid "Stock" msgstr "Lagerbestand" @@ -1346,6 +1337,26 @@ msgstr "Preisstaffel bearbeiten" msgid "Delete Price Break" msgstr "Preisstaffel löschen" +#: label/models.py:55 +#, fuzzy +#| msgid "Part name" +msgid "Label name" +msgstr "Name des Teils" + +#: label/models.py:58 +#, fuzzy +#| msgid "Part description" +msgid "Label description" +msgstr "Beschreibung des Teils" + +#: label/models.py:63 +msgid "Label template file" +msgstr "" + +#: label/models.py:69 +msgid "Query filters (comma-separated list of key=value pairs" +msgstr "" + #: order/forms.py:24 msgid "Place order" msgstr "Bestellung aufgeben" @@ -1400,7 +1411,7 @@ msgid "Supplier order reference code" msgstr "Bestellreferenz" #: order/models.py:185 order/models.py:259 part/views.py:1167 -#: stock/models.py:243 stock/models.py:665 stock/views.py:1243 +#: stock/models.py:238 stock/models.py:687 msgid "Quantity must be greater than zero" msgstr "Anzahl muss größer Null sein" @@ -1434,7 +1445,7 @@ msgstr "Position - Notizen" #: order/models.py:466 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:23 -#: stock/templates/stock/item_base.html:216 templates/js/order.html:136 +#: stock/templates/stock/item_base.html:223 templates/js/order.html:136 msgid "Purchase Order" msgstr "Kaufvertrag" @@ -1718,7 +1729,7 @@ msgstr "Bestellungspositionen" msgid "Add Purchase Order Attachment" msgstr "Bestellanhang hinzufügen" -#: order/views.py:102 order/views.py:149 part/views.py:85 stock/views.py:166 +#: order/views.py:102 order/views.py:149 part/views.py:85 stock/views.py:167 msgid "Added attachment" msgstr "Anhang hinzugefügt" @@ -1738,7 +1749,7 @@ msgstr "Anhang aktualisiert" msgid "Delete Attachment" msgstr "Anhang löschen" -#: order/views.py:222 order/views.py:236 stock/views.py:222 +#: order/views.py:222 order/views.py:236 stock/views.py:223 msgid "Deleted attachment" msgstr "Anhang gelöscht" @@ -1871,11 +1882,11 @@ msgstr "Fehler beim Lesen der Stückliste (ungültige Daten)" msgid "Error reading BOM file (incorrect row size)" msgstr "Fehler beim Lesen der Stückliste (ungültige Zeilengröße)" -#: part/forms.py:55 stock/forms.py:200 +#: part/forms.py:55 stock/forms.py:243 msgid "File Format" msgstr "Dateiformat" -#: part/forms.py:55 stock/forms.py:200 +#: part/forms.py:55 stock/forms.py:243 msgid "Select output file format" msgstr "Ausgabe-Dateiformat auswählen" @@ -1925,105 +1936,114 @@ msgstr "Standard-Standort für Teile dieser Kategorie" msgid "Default keywords for parts in this category" msgstr "Standard-Stichworte für Teile dieser Kategorie" -#: part/models.py:427 +#: part/models.py:74 part/templates/part/part_app_base.html:9 +msgid "Part Category" +msgstr "Teilkategorie" + +#: part/models.py:75 part/templates/part/category.html:13 +#: part/templates/part/category.html:78 templates/stats.html:12 +msgid "Part Categories" +msgstr "Teile-Kategorien" + +#: part/models.py:428 msgid "Part must be unique for name, IPN and revision" msgstr "Namen, Teile- und Revisionsnummern müssen eindeutig sein" -#: part/models.py:442 part/templates/part/detail.html:19 +#: part/models.py:443 part/templates/part/detail.html:19 msgid "Part name" msgstr "Name des Teils" -#: part/models.py:446 +#: part/models.py:447 msgid "Is this part a template part?" msgstr "Ist dieses Teil eine Vorlage?" -#: part/models.py:455 +#: part/models.py:456 msgid "Is this part a variant of another part?" msgstr "Ist dieses Teil eine Variante eines anderen Teils?" -#: part/models.py:457 +#: part/models.py:458 msgid "Part description" msgstr "Beschreibung des Teils" -#: part/models.py:459 +#: part/models.py:460 msgid "Part keywords to improve visibility in search results" msgstr "Schlüsselworte um die Sichtbarkeit in Suchergebnissen zu verbessern" -#: part/models.py:464 +#: part/models.py:465 msgid "Part category" msgstr "Teile-Kategorie" -#: part/models.py:466 +#: part/models.py:467 msgid "Internal Part Number" msgstr "Interne Teilenummer" -#: part/models.py:468 +#: part/models.py:469 msgid "Part revision or version number" msgstr "Revisions- oder Versionsnummer" -#: part/models.py:470 +#: part/models.py:471 msgid "Link to extenal URL" msgstr "Link zu einer Externen URL" -#: part/models.py:482 +#: part/models.py:483 msgid "Where is this item normally stored?" msgstr "Wo wird dieses Teil normalerweise gelagert?" -#: part/models.py:526 +#: part/models.py:527 msgid "Default supplier part" msgstr "Standard-Zulieferer?" -#: part/models.py:529 +#: part/models.py:530 msgid "Minimum allowed stock level" msgstr "Minimal zulässiger Lagerbestand" -#: part/models.py:531 +#: part/models.py:532 msgid "Stock keeping units for this part" msgstr "Stock Keeping Units (SKU) für dieses Teil" -#: part/models.py:533 +#: part/models.py:534 msgid "Can this part be built from other parts?" msgstr "Kann dieses Teil aus anderen Teilen angefertigt werden?" -#: part/models.py:535 +#: part/models.py:536 msgid "Can this part be used to build other parts?" msgstr "Kann dieses Teil zum Bau von anderen genutzt werden?" -#: part/models.py:537 +#: part/models.py:538 msgid "Does this part have tracking for unique items?" msgstr "Hat dieses Teil Tracking für einzelne Objekte?" -#: part/models.py:539 +#: part/models.py:540 msgid "Can this part be purchased from external suppliers?" msgstr "Kann dieses Teil von externen Zulieferern gekauft werden?" -#: part/models.py:541 +#: part/models.py:542 msgid "Can this part be sold to customers?" msgstr "Kann dieses Teil an Kunden verkauft werden?" -#: part/models.py:543 +#: part/models.py:544 msgid "Is this part active?" msgstr "Ist dieses Teil aktiv?" -#: part/models.py:545 +#: part/models.py:546 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:547 +#: part/models.py:548 msgid "Part notes - supports Markdown formatting" msgstr "Bemerkungen - unterstüzt Markdown-Formatierung" -#: part/models.py:549 +#: part/models.py:550 msgid "Stored BOM checksum" msgstr "Prüfsumme der Stückliste gespeichert" -#: part/models.py:1221 +#: part/models.py:1222 #, 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:1238 +#: part/models.py:1239 #, fuzzy #| msgid "" #| "A stock item with this serial number already exists for template part " @@ -2033,121 +2053,127 @@ msgstr "" "Ein Teil mit dieser Seriennummer existiert bereits für die Teilevorlage " "{part}" -#: part/models.py:1257 templates/js/part.html:350 templates/js/stock.html:89 +#: part/models.py:1258 templates/js/part.html:350 templates/js/stock.html:90 #, fuzzy #| msgid "Instance Name" msgid "Test Name" msgstr "Instanzname" -#: part/models.py:1258 +#: part/models.py:1259 #, fuzzy #| msgid "Serial number for this item" msgid "Enter a name for the test" msgstr "Seriennummer für dieses Teil" -#: part/models.py:1263 +#: part/models.py:1264 #, fuzzy #| msgid "Description" msgid "Test Description" msgstr "Beschreibung" -#: part/models.py:1264 +#: part/models.py:1265 #, fuzzy #| msgid "Brief description of the build" msgid "Enter description for this test" msgstr "Kurze Beschreibung des Baus" -#: part/models.py:1270 +#: part/models.py:1271 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:1275 templates/js/part.html:367 +#: part/models.py:1276 templates/js/part.html:367 #, fuzzy #| msgid "Required Parts" msgid "Requires Value" msgstr "benötigte Teile" -#: part/models.py:1276 +#: part/models.py:1277 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:1281 templates/js/part.html:374 +#: part/models.py:1282 templates/js/part.html:374 #, fuzzy #| msgid "Delete Attachment" msgid "Requires Attachment" msgstr "Anhang löschen" -#: part/models.py:1282 +#: part/models.py:1283 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:1315 +#: part/models.py:1316 msgid "Parameter template name must be unique" msgstr "Vorlagen-Name des Parameters muss eindeutig sein" -#: part/models.py:1320 +#: part/models.py:1321 msgid "Parameter Name" msgstr "Name des Parameters" -#: part/models.py:1322 +#: part/models.py:1323 msgid "Parameter Units" msgstr "Parameter Einheit" -#: part/models.py:1348 +#: part/models.py:1349 msgid "Parent Part" msgstr "Ausgangsteil" -#: part/models.py:1350 +#: part/models.py:1351 msgid "Parameter Template" msgstr "Parameter Vorlage" -#: part/models.py:1352 +#: part/models.py:1353 msgid "Parameter Value" msgstr "Parameter Wert" -#: part/models.py:1381 +#: part/models.py:1382 msgid "Select parent part" msgstr "Ausgangsteil auswählen" -#: part/models.py:1389 +#: part/models.py:1390 msgid "Select part to be used in BOM" msgstr "Teil für die Nutzung in der Stückliste auswählen" -#: part/models.py:1395 +#: part/models.py:1396 msgid "BOM quantity for this BOM item" msgstr "Stücklisten-Anzahl für dieses Stücklisten-Teil" -#: part/models.py:1398 +#: part/models.py:1399 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "Geschätzter Ausschuss (absolut oder prozentual)" -#: part/models.py:1401 +#: part/models.py:1402 msgid "BOM item reference" msgstr "Referenz des Objekts auf der Stückliste" -#: part/models.py:1404 +#: part/models.py:1405 msgid "BOM item notes" msgstr "Notizen zum Stücklisten-Objekt" -#: part/models.py:1406 +#: part/models.py:1407 msgid "BOM line checksum" msgstr "Prüfsumme der Stückliste" -#: part/models.py:1470 stock/models.py:233 +#: part/models.py:1471 stock/models.py:228 #, 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:1479 +#: part/models.py:1480 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:1486 +#: part/models.py:1487 #, 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)" +#: part/models.py:1494 +#, fuzzy +#| msgid "New BOM Item" +msgid "BOM Item" +msgstr "Neue Stücklistenposition" + #: part/templates/part/allocation.html:10 msgid "Part Stock Allocations" msgstr "Teilbestandszuordnungen" @@ -2163,14 +2189,14 @@ msgstr "Bestellung" #: part/templates/part/allocation.html:45 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:58 -#: stock/templates/stock/item_base.html:224 +#: stock/templates/stock/item_base.html:231 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.html:106 -#: templates/js/stock.html:630 +#: templates/js/stock.html:643 msgid "Stock Item" msgstr "Lagerobjekt" #: part/templates/part/allocation.html:20 -#: stock/templates/stock/item_base.html:178 +#: stock/templates/stock/item_base.html:185 msgid "Build Order" msgstr "Bauauftrag" @@ -2210,11 +2236,6 @@ msgstr "Stückliste validieren" msgid "Export Bill of Materials" msgstr "Stückliste exportieren" -#: part/templates/part/category.html:13 part/templates/part/category.html:78 -#: templates/stats.html:12 -msgid "Part Categories" -msgstr "Teile-Kategorien" - #: part/templates/part/category.html:14 msgid "All parts" msgstr "Alle Teile" @@ -2310,8 +2331,8 @@ msgstr "Teil ist virtuell (kein physisches Teil)" msgid "Part is not a virtual part" msgstr "Teil ist nicht virtuell" -#: part/templates/part/detail.html:139 stock/forms.py:194 -#: templates/js/table_filters.html:149 +#: part/templates/part/detail.html:139 stock/forms.py:237 +#: templates/js/table_filters.html:159 msgid "Template" msgstr "Vorlage" @@ -2327,7 +2348,7 @@ msgstr "Teil kann keine Vorlage sein wenn es Variante eines anderen Teils ist" msgid "Part is not a template part" msgstr "Teil ist nicht virtuell" -#: part/templates/part/detail.html:148 templates/js/table_filters.html:161 +#: part/templates/part/detail.html:148 templates/js/table_filters.html:171 msgid "Assembly" msgstr "Baugruppe" @@ -2339,7 +2360,7 @@ msgstr "Teil kann aus anderen Teilen angefertigt werden" msgid "Part cannot be assembled from other parts" msgstr "Teil kann nicht aus anderen Teilen angefertigt werden" -#: part/templates/part/detail.html:157 templates/js/table_filters.html:165 +#: part/templates/part/detail.html:157 templates/js/table_filters.html:175 msgid "Component" msgstr "Komponente" @@ -2351,7 +2372,7 @@ msgstr "Teil kann in Baugruppen benutzt werden" msgid "Part cannot be used in assemblies" msgstr "Teil kann nicht in Baugruppen benutzt werden" -#: part/templates/part/detail.html:166 templates/js/table_filters.html:177 +#: part/templates/part/detail.html:166 templates/js/table_filters.html:187 msgid "Trackable" msgstr "nachverfolgbar" @@ -2371,7 +2392,7 @@ msgstr "Kaufbar" msgid "Part can be purchased from external suppliers" msgstr "Teil kann von externen Zulieferern gekauft werden" -#: part/templates/part/detail.html:184 templates/js/table_filters.html:173 +#: part/templates/part/detail.html:184 templates/js/table_filters.html:183 msgid "Salable" msgstr "Verkäuflich" @@ -2383,7 +2404,7 @@ msgstr "Teil kann an Kunden verkauft werden" msgid "Part cannot be sold to customers" msgstr "Teil kann nicht an Kunden verkauft werden" -#: part/templates/part/detail.html:193 templates/js/table_filters.html:144 +#: part/templates/part/detail.html:193 templates/js/table_filters.html:154 msgid "Active" msgstr "Aktiv" @@ -2419,8 +2440,8 @@ msgstr "Parameter hinzufügen" msgid "New Parameter" msgstr "Neuer Parameter" -#: part/templates/part/params.html:21 stock/models.py:1252 -#: templates/js/stock.html:109 +#: part/templates/part/params.html:21 stock/models.py:1274 +#: templates/js/stock.html:110 msgid "Value" msgstr "Wert" @@ -2432,10 +2453,6 @@ msgstr "Bearbeiten" msgid "Delete" msgstr "Löschen" -#: part/templates/part/part_app_base.html:9 -msgid "Part Category" -msgstr "Teilkategorie" - #: part/templates/part/part_app_base.html:11 msgid "Part List" msgstr "Teileliste" @@ -2517,7 +2534,7 @@ msgstr "Teile löschen" msgid "Available Stock" msgstr "Verfügbarer Lagerbestand" -#: part/templates/part/part_base.html:108 templates/js/table_filters.html:37 +#: part/templates/part/part_base.html:108 templates/js/table_filters.html:57 msgid "In Stock" msgstr "Auf Lager" @@ -2630,7 +2647,7 @@ msgstr "Stückliste" msgid "Used In" msgstr "Benutzt in" -#: part/templates/part/tabs.html:55 stock/templates/stock/item_base.html:268 +#: part/templates/part/tabs.html:55 stock/templates/stock/item_base.html:275 msgid "Tests" msgstr "" @@ -2859,236 +2876,252 @@ msgstr "" msgid "Asset file description" msgstr "Einstellungs-Beschreibung" -#: stock/forms.py:194 +#: stock/forms.py:185 +msgid "Label" +msgstr "" + +#: stock/forms.py:186 stock/forms.py:237 #, fuzzy #| msgid "Select stock item to allocate" msgid "Select test report template" msgstr "Lagerobjekt für Zuordnung auswählen" -#: stock/forms.py:202 +#: stock/forms.py:245 msgid "Include stock items in sub locations" msgstr "Lagerobjekte in untergeordneten Lagerorten einschließen" -#: stock/forms.py:235 +#: stock/forms.py:278 msgid "Destination stock location" msgstr "Ziel-Lagerbestand" -#: stock/forms.py:241 +#: stock/forms.py:284 msgid "Confirm movement of stock items" msgstr "Bewegung der Lagerobjekte bestätigen" -#: stock/forms.py:243 +#: stock/forms.py:286 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:208 +#: stock/models.py:209 #, fuzzy #| msgid "A stock item with this serial number already exists" msgid "StockItem with this serial number already exists" msgstr "Ein Teil mit dieser Seriennummer existiert bereits" -#: stock/models.py:250 +#: stock/models.py:245 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "Teile-Typ ('{pf}') muss {pe} sein" -#: stock/models.py:260 stock/models.py:269 +#: stock/models.py:255 stock/models.py:264 msgid "Quantity must be 1 for item with a serial number" msgstr "Anzahl muss für Objekte mit Seriennummer \"1\" sein" -#: stock/models.py:261 +#: stock/models.py:256 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:282 +#: stock/models.py:277 msgid "Item cannot belong to itself" msgstr "Teil kann nicht zu sich selbst gehören" -#: stock/models.py:314 +#: stock/models.py:316 msgid "Parent Stock Item" msgstr "Eltern-Lagerobjekt" -#: stock/models.py:323 +#: stock/models.py:325 msgid "Base part" msgstr "Basis-Teil" -#: stock/models.py:332 +#: stock/models.py:334 msgid "Select a matching supplier part for this stock item" msgstr "Passenden Zulieferer für dieses Lagerobjekt auswählen" -#: stock/models.py:337 stock/templates/stock/stock_app_base.html:7 +#: stock/models.py:339 stock/templates/stock/stock_app_base.html:7 msgid "Stock Location" msgstr "Lagerort" -#: stock/models.py:340 +#: stock/models.py:342 msgid "Where is this stock item located?" msgstr "Wo wird dieses Teil normalerweise gelagert?" -#: stock/models.py:345 +#: stock/models.py:347 msgid "Installed In" msgstr "Installiert in" -#: stock/models.py:348 +#: stock/models.py:350 msgid "Is this item installed in another item?" msgstr "Ist dieses Teil in einem anderen verbaut?" -#: stock/models.py:364 +#: stock/models.py:366 msgid "Serial number for this item" msgstr "Seriennummer für dieses Teil" -#: stock/models.py:376 +#: stock/models.py:378 msgid "Batch code for this stock item" msgstr "Losnummer für dieses Lagerobjekt" -#: stock/models.py:380 +#: stock/models.py:382 msgid "Stock Quantity" msgstr "Bestand" -#: stock/models.py:389 +#: stock/models.py:391 msgid "Source Build" msgstr "Quellbau" -#: stock/models.py:391 +#: stock/models.py:393 msgid "Build for this stock item" msgstr "Bau für dieses Lagerobjekt" -#: stock/models.py:398 +#: stock/models.py:400 msgid "Source Purchase Order" msgstr "Quellbestellung" -#: stock/models.py:401 +#: stock/models.py:403 msgid "Purchase order for this stock item" msgstr "Bestellung für dieses Teil" -#: stock/models.py:407 +#: stock/models.py:409 msgid "Destination Sales Order" msgstr "Zielauftrag" -#: stock/models.py:414 +#: stock/models.py:416 msgid "Destination Build Order" msgstr "Zielbauauftrag" -#: stock/models.py:427 +#: stock/models.py:429 msgid "Delete this Stock Item when stock is depleted" msgstr "Objekt löschen wenn Lagerbestand aufgebraucht" -#: stock/models.py:437 stock/templates/stock/item_notes.html:14 +#: stock/models.py:439 stock/templates/stock/item_notes.html:14 #: stock/templates/stock/item_notes.html:30 msgid "Stock Item Notes" msgstr "Lagerobjekt-Notizen" -#: stock/models.py:489 +#: stock/models.py:490 #, fuzzy #| msgid "Item assigned to customer?" msgid "Assigned to Customer" msgstr "Ist dieses Objekt einem Kunden zugeteilt?" -#: stock/models.py:491 +#: stock/models.py:492 #, fuzzy #| msgid "Item assigned to customer?" msgid "Manually assigned to customer" msgstr "Ist dieses Objekt einem Kunden zugeteilt?" -#: stock/models.py:656 +#: stock/models.py:505 +#, fuzzy +#| msgid "Item assigned to customer?" +msgid "Returned from customer" +msgstr "Ist dieses Objekt einem Kunden zugeteilt?" + +#: stock/models.py:507 +#, fuzzy +#| msgid "Create new stock location" +msgid "Returned to location" +msgstr "Neuen Lagerort anlegen" + +#: stock/models.py:678 #, fuzzy #| msgid "Part is not a virtual part" msgid "Part is not set as trackable" msgstr "Teil ist nicht virtuell" -#: stock/models.py:662 +#: stock/models.py:684 msgid "Quantity must be integer" msgstr "Anzahl muss eine Ganzzahl sein" -#: stock/models.py:668 +#: stock/models.py:690 #, 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:671 stock/models.py:674 +#: stock/models.py:693 stock/models.py:696 msgid "Serial numbers must be a list of integers" msgstr "Seriennummern muss eine Liste von Ganzzahlen sein" -#: stock/models.py:677 +#: stock/models.py:699 msgid "Quantity does not match serial numbers" msgstr "Anzahl stimmt nicht mit den Seriennummern überein" -#: stock/models.py:687 +#: stock/models.py:709 msgid "Serial numbers already exist: " msgstr "Seriennummern existieren bereits:" -#: stock/models.py:712 +#: stock/models.py:734 msgid "Add serial number" msgstr "Seriennummer hinzufügen" -#: stock/models.py:715 +#: stock/models.py:737 #, python-brace-format msgid "Serialized {n} items" msgstr "{n} Teile serialisiert" -#: stock/models.py:826 +#: stock/models.py:848 msgid "StockItem cannot be moved as it is not in stock" msgstr "Lagerobjekt kann nicht bewegt werden, da kein Bestand vorhanden ist" -#: stock/models.py:1153 +#: stock/models.py:1175 msgid "Tracking entry title" msgstr "Name des Eintrags-Trackings" -#: stock/models.py:1155 +#: stock/models.py:1177 msgid "Entry notes" msgstr "Eintrags-Notizen" -#: stock/models.py:1157 +#: stock/models.py:1179 msgid "Link to external page for further information" msgstr "Link auf externe Seite für weitere Informationen" -#: stock/models.py:1217 +#: stock/models.py:1239 #, fuzzy #| msgid "Serial number for this item" msgid "Value must be provided for this test" msgstr "Seriennummer für dieses Teil" -#: stock/models.py:1223 +#: stock/models.py:1245 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:1240 +#: stock/models.py:1262 msgid "Test" msgstr "" -#: stock/models.py:1241 +#: stock/models.py:1263 #, fuzzy #| msgid "Part name" msgid "Test name" msgstr "Name des Teils" -#: stock/models.py:1246 +#: stock/models.py:1268 #, fuzzy #| msgid "Search Results" msgid "Result" msgstr "Suchergebnisse" -#: stock/models.py:1247 templates/js/table_filters.html:80 +#: stock/models.py:1269 templates/js/table_filters.html:90 msgid "Test result" msgstr "" -#: stock/models.py:1253 +#: stock/models.py:1275 msgid "Test output value" msgstr "" -#: stock/models.py:1259 +#: stock/models.py:1281 #, fuzzy #| msgid "Attachments" msgid "Attachment" msgstr "Anhänge" -#: stock/models.py:1260 +#: stock/models.py:1282 #, fuzzy #| msgid "Delete attachment" msgid "Test result attachment" msgstr "Anhang löschen" -#: stock/models.py:1266 +#: stock/models.py:1288 #, fuzzy #| msgid "Edit notes" msgid "Test notes" @@ -3146,7 +3179,7 @@ msgstr "" msgid "Link Barcode" msgstr "" -#: stock/templates/stock/item_base.html:92 +#: stock/templates/stock/item_base.html:91 #, fuzzy #| msgid "Confirm stock adjustment" msgid "Stock adjustment actions" @@ -3171,84 +3204,94 @@ msgstr "Bestand entfernen" msgid "Transfer stock" msgstr "Bestand bestellen" +#: stock/templates/stock/item_base.html:101 +#, fuzzy +#| msgid "Serialize Stock" +msgid "Serialize stock" +msgstr "Lagerbestand erfassen" + #: stock/templates/stock/item_base.html:105 +#, fuzzy +#| msgid "Item assigned to customer?" +msgid "Assign to customer" +msgstr "Ist dieses Objekt einem Kunden zugeteilt?" + +#: stock/templates/stock/item_base.html:108 +#, fuzzy +#| msgid "Count stock" +msgid "Return to stock" +msgstr "Bestand zählen" + +#: stock/templates/stock/item_base.html:114 #: stock/templates/stock/location.html:30 #, fuzzy #| msgid "Stock Locations" msgid "Stock actions" msgstr "Lagerobjekt-Standorte" -#: stock/templates/stock/item_base.html:108 -#, fuzzy -#| msgid "Serialize Stock" -msgid "Serialize stock" -msgstr "Lagerbestand erfassen" - -#: stock/templates/stock/item_base.html:111 -#, fuzzy -#| msgid "Item assigned to customer?" -msgid "Assign to customer" -msgstr "Ist dieses Objekt einem Kunden zugeteilt?" - -#: stock/templates/stock/item_base.html:114 +#: stock/templates/stock/item_base.html:118 #, fuzzy #| msgid "Count stock items" msgid "Convert to variant" msgstr "Lagerobjekte zählen" -#: stock/templates/stock/item_base.html:116 +#: stock/templates/stock/item_base.html:120 #, fuzzy #| msgid "Count stock items" msgid "Duplicate stock item" msgstr "Lagerobjekte zählen" -#: stock/templates/stock/item_base.html:117 +#: stock/templates/stock/item_base.html:121 #, fuzzy #| msgid "Edit Stock Item" msgid "Edit stock item" msgstr "Lagerobjekt bearbeiten" -#: stock/templates/stock/item_base.html:119 +#: stock/templates/stock/item_base.html:123 #, fuzzy #| msgid "Delete Stock Item" msgid "Delete stock item" msgstr "Lagerobjekt löschen" -#: stock/templates/stock/item_base.html:124 +#: stock/templates/stock/item_base.html:128 msgid "Generate test report" msgstr "" -#: stock/templates/stock/item_base.html:133 +#: stock/templates/stock/item_base.html:132 +msgid "Print labels" +msgstr "" + +#: stock/templates/stock/item_base.html:140 msgid "Stock Item Details" msgstr "Lagerbestands-Details" -#: stock/templates/stock/item_base.html:166 +#: stock/templates/stock/item_base.html:173 msgid "Belongs To" msgstr "Gehört zu" -#: stock/templates/stock/item_base.html:188 +#: stock/templates/stock/item_base.html:195 #, fuzzy #| msgid "No stock location set" msgid "No location set" msgstr "Kein Lagerort gesetzt" -#: stock/templates/stock/item_base.html:195 +#: stock/templates/stock/item_base.html:202 msgid "Unique Identifier" msgstr "Eindeutiger Bezeichner" -#: stock/templates/stock/item_base.html:223 +#: stock/templates/stock/item_base.html:230 msgid "Parent Item" msgstr "Elternposition" -#: stock/templates/stock/item_base.html:248 +#: stock/templates/stock/item_base.html:255 msgid "Last Updated" msgstr "Zuletzt aktualisiert" -#: stock/templates/stock/item_base.html:253 +#: stock/templates/stock/item_base.html:260 msgid "Last Stocktake" msgstr "Letzte Inventur" -#: stock/templates/stock/item_base.html:257 +#: stock/templates/stock/item_base.html:264 msgid "No stocktake performed" msgstr "Keine Inventur ausgeführt" @@ -3349,7 +3392,17 @@ msgstr "Lagerobjekt-Standorte" msgid "Are you sure you want to delete this stock location?" msgstr "Sind Sie sicher, dass Sie diesen Anhang löschen wollen?" -#: stock/templates/stock/stockitem_convert.html:7 stock/views.py:934 +#: stock/templates/stock/stock_adjust.html:35 +#, fuzzy +#| msgid "" +#| "This stock item is serialized - it has a unique serial number and the " +#| "quantity cannot be adjusted." +msgid "Stock item is serialized and quantity cannot be adjusted" +msgstr "" +"Dieses Lagerobjekt ist serialisiert. Es hat eine eindeutige Seriennummer und " +"die Anzahl kann nicht angepasst werden." + +#: stock/templates/stock/stockitem_convert.html:7 stock/views.py:1052 #, fuzzy #| msgid "Count Stock Items" msgid "Convert Stock Item" @@ -3381,33 +3434,33 @@ msgstr "Baue" msgid "Children" msgstr "Kinder" -#: stock/views.py:113 +#: stock/views.py:114 msgid "Edit Stock Location" msgstr "Lagerobjekt-Standort bearbeiten" -#: stock/views.py:137 +#: stock/views.py:138 msgid "Stock Location QR code" msgstr "QR-Code für diesen Standort" -#: stock/views.py:155 +#: stock/views.py:156 #, fuzzy #| msgid "Add Attachment" msgid "Add Stock Item Attachment" msgstr "Anhang hinzufügen" -#: stock/views.py:200 +#: stock/views.py:201 #, fuzzy #| msgid "Edit Stock Item" msgid "Edit Stock Item Attachment" msgstr "Lagerobjekt bearbeiten" -#: stock/views.py:216 +#: stock/views.py:217 #, fuzzy #| msgid "Delete Part Attachment" msgid "Delete Stock Item Attachment" msgstr "Teilanhang löschen" -#: stock/views.py:232 +#: stock/views.py:233 #, fuzzy #| msgid "Item assigned to customer?" msgid "Assign to Customer" @@ -3415,178 +3468,212 @@ msgstr "Ist dieses Objekt einem Kunden zugeteilt?" #: stock/views.py:270 #, fuzzy +#| msgid "Part Stock" +msgid "Return to Stock" +msgstr "Teilbestand" + +#: stock/views.py:289 +#, fuzzy +#| msgid "Include sublocations" +msgid "Specify a valid location" +msgstr "Unterlagerorte einschließen" + +#: stock/views.py:293 +msgid "Stock item returned from customer" +msgstr "" + +#: stock/views.py:305 +#, fuzzy +#| msgid "Select valid part" +msgid "Select Label Template" +msgstr "Bitte ein gültiges Teil auswählen" + +#: stock/views.py:326 +#, fuzzy +#| msgid "Select valid part" +msgid "Select valid label" +msgstr "Bitte ein gültiges Teil auswählen" + +#: stock/views.py:388 +#, fuzzy #| msgid "Delete Template" msgid "Delete All Test Data" msgstr "Vorlage löschen" -#: stock/views.py:285 +#: stock/views.py:403 #, fuzzy #| msgid "Confirm Part Deletion" msgid "Confirm test data deletion" msgstr "Löschen des Teils bestätigen" -#: stock/views.py:305 +#: stock/views.py:423 msgid "Add Test Result" msgstr "" -#: stock/views.py:342 +#: stock/views.py:460 #, fuzzy #| msgid "Edit Template" msgid "Edit Test Result" msgstr "Vorlage bearbeiten" -#: stock/views.py:359 +#: stock/views.py:477 #, fuzzy #| msgid "Delete Template" msgid "Delete Test Result" msgstr "Vorlage löschen" -#: stock/views.py:370 +#: stock/views.py:488 #, fuzzy #| msgid "Delete Template" msgid "Select Test Report Template" msgstr "Vorlage löschen" -#: stock/views.py:384 +#: stock/views.py:502 #, fuzzy #| msgid "Select valid part" msgid "Select valid template" msgstr "Bitte ein gültiges Teil auswählen" -#: stock/views.py:436 +#: stock/views.py:554 msgid "Stock Export Options" msgstr "Lagerbestandsexportoptionen" -#: stock/views.py:556 +#: stock/views.py:674 msgid "Stock Item QR Code" msgstr "Lagerobjekt-QR-Code" -#: stock/views.py:579 +#: stock/views.py:697 msgid "Adjust Stock" msgstr "Lagerbestand anpassen" -#: stock/views.py:688 +#: stock/views.py:806 msgid "Move Stock Items" msgstr "Lagerobjekte bewegen" -#: stock/views.py:689 +#: stock/views.py:807 msgid "Count Stock Items" msgstr "Lagerobjekte zählen" -#: stock/views.py:690 +#: stock/views.py:808 msgid "Remove From Stock" msgstr "Aus Lagerbestand entfernen" -#: stock/views.py:691 +#: stock/views.py:809 msgid "Add Stock Items" msgstr "Lagerobjekte hinzufügen" -#: stock/views.py:692 +#: stock/views.py:810 msgid "Delete Stock Items" msgstr "Lagerobjekte löschen" -#: stock/views.py:720 +#: stock/views.py:838 msgid "Must enter integer value" msgstr "Nur Ganzzahl eingeben" -#: stock/views.py:725 +#: stock/views.py:843 msgid "Quantity must be positive" msgstr "Anzahl muss positiv sein" -#: stock/views.py:732 +#: stock/views.py:850 #, python-brace-format msgid "Quantity must not exceed {x}" msgstr "Anzahl darf {x} nicht überschreiten" -#: stock/views.py:740 +#: stock/views.py:858 msgid "Confirm stock adjustment" msgstr "Bestands-Anpassung bestätigen" -#: stock/views.py:811 +#: stock/views.py:929 #, python-brace-format msgid "Added stock to {n} items" msgstr "Vorrat zu {n} Lagerobjekten hinzugefügt" -#: stock/views.py:826 +#: stock/views.py:944 #, python-brace-format msgid "Removed stock from {n} items" msgstr "Vorrat von {n} Lagerobjekten entfernt" -#: stock/views.py:839 +#: stock/views.py:957 #, python-brace-format msgid "Counted stock for {n} items" msgstr "Bestand für {n} Objekte erfasst" -#: stock/views.py:867 +#: stock/views.py:985 msgid "No items were moved" msgstr "Keine Lagerobjekte wurden bewegt" -#: stock/views.py:870 +#: stock/views.py:988 #, python-brace-format msgid "Moved {n} items to {dest}" msgstr "{n} Teile nach {dest} bewegt" -#: stock/views.py:889 +#: stock/views.py:1007 #, python-brace-format msgid "Deleted {n} stock items" msgstr "{n} Teile im Lager gelöscht" -#: stock/views.py:901 +#: stock/views.py:1019 msgid "Edit Stock Item" msgstr "Lagerobjekt bearbeiten" -#: stock/views.py:961 +#: stock/views.py:1079 msgid "Create new Stock Location" msgstr "Neuen Lager-Standort erstellen" -#: stock/views.py:982 +#: stock/views.py:1100 msgid "Serialize Stock" msgstr "Lagerbestand erfassen" -#: stock/views.py:1074 +#: stock/views.py:1192 msgid "Create new Stock Item" msgstr "Neues Lagerobjekt hinzufügen" -#: stock/views.py:1167 +#: stock/views.py:1285 #, fuzzy #| msgid "Count stock items" msgid "Duplicate Stock Item" msgstr "Lagerobjekte zählen" -#: stock/views.py:1240 +#: stock/views.py:1358 msgid "Invalid quantity" msgstr "Ungültige Menge" -#: stock/views.py:1247 +#: stock/views.py:1361 +#, fuzzy +#| msgid "Quantity must be greater than zero" +msgid "Quantity cannot be less than zero" +msgstr "Anzahl muss größer Null sein" + +#: stock/views.py:1365 msgid "Invalid part selection" msgstr "Ungültige Teileauswahl" -#: stock/views.py:1296 +#: stock/views.py:1414 #, python-brace-format msgid "Created {n} new stock items" msgstr "{n} neue Lagerobjekte erstellt" -#: stock/views.py:1315 stock/views.py:1331 +#: stock/views.py:1433 stock/views.py:1449 msgid "Created new stock item" msgstr "Neues Lagerobjekt erstellt" -#: stock/views.py:1350 +#: stock/views.py:1468 msgid "Delete Stock Location" msgstr "Standort löschen" -#: stock/views.py:1363 +#: stock/views.py:1481 msgid "Delete Stock Item" msgstr "Lagerobjekt löschen" -#: stock/views.py:1374 +#: stock/views.py:1492 msgid "Delete Stock Tracking Entry" msgstr "Lagerbestands-Tracking-Eintrag löschen" -#: stock/views.py:1391 +#: stock/views.py:1509 msgid "Edit Stock Tracking Entry" msgstr "Lagerbestands-Tracking-Eintrag bearbeiten" -#: stock/views.py:1400 +#: stock/views.py:1518 msgid "Add Stock Tracking Entry" msgstr "Lagerbestands-Tracking-Eintrag hinzufügen" @@ -3839,7 +3926,7 @@ msgstr "Link" msgid "No purchase orders found" msgstr "Keine Bestellungen gefunden" -#: templates/js/order.html:170 templates/js/stock.html:612 +#: templates/js/order.html:170 templates/js/stock.html:625 msgid "Date" msgstr "Datum" @@ -3851,7 +3938,7 @@ msgstr "Keine Aufträge gefunden" msgid "Shipment Date" msgstr "Versanddatum" -#: templates/js/part.html:106 templates/js/stock.html:405 +#: templates/js/part.html:106 templates/js/stock.html:406 msgid "Select" msgstr "Auswählen" @@ -3867,7 +3954,7 @@ msgstr "Verkäufliches Teil" msgid "No category" msgstr "Keine Kategorie" -#: templates/js/part.html:214 templates/js/table_filters.html:157 +#: templates/js/part.html:214 templates/js/table_filters.html:167 msgid "Low stock" msgstr "Bestand niedrig" @@ -3893,13 +3980,13 @@ msgstr "" msgid "No test templates matching query" msgstr "Keine zur Anfrage passenden Lagerobjekte" -#: templates/js/part.html:387 templates/js/stock.html:62 +#: templates/js/part.html:387 templates/js/stock.html:63 #, fuzzy #| msgid "Edit Sales Order" msgid "Edit test result" msgstr "Auftrag bearbeiten" -#: templates/js/part.html:388 templates/js/stock.html:63 +#: templates/js/part.html:388 templates/js/stock.html:64 #, fuzzy #| msgid "Delete attachment" msgid "Delete test result" @@ -3909,165 +3996,215 @@ msgstr "Anhang löschen" msgid "This test is defined for a parent part" msgstr "" -#: templates/js/stock.html:25 +#: templates/js/stock.html:26 msgid "PASS" msgstr "" -#: templates/js/stock.html:27 +#: templates/js/stock.html:28 msgid "FAIL" msgstr "" -#: templates/js/stock.html:32 +#: templates/js/stock.html:33 msgid "NO RESULT" msgstr "" -#: templates/js/stock.html:58 +#: templates/js/stock.html:59 #, fuzzy #| msgid "Edit Sales Order" msgid "Add test result" msgstr "Auftrag bearbeiten" -#: templates/js/stock.html:76 +#: templates/js/stock.html:77 #, fuzzy #| msgid "No results found" msgid "No test results found" msgstr "Keine Ergebnisse gefunden" -#: templates/js/stock.html:117 +#: templates/js/stock.html:118 #, fuzzy #| msgid "Shipment Date" msgid "Test Date" msgstr "Versanddatum" -#: templates/js/stock.html:260 +#: templates/js/stock.html:261 msgid "No stock items matching query" msgstr "Keine zur Anfrage passenden Lagerobjekte" -#: templates/js/stock.html:357 templates/js/stock.html:372 +#: templates/js/stock.html:358 templates/js/stock.html:373 #, fuzzy #| msgid "Include sublocations" msgid "Undefined location" msgstr "Unterlagerorte einschließen" -#: templates/js/stock.html:469 -msgid "StockItem has been allocated" +#: templates/js/stock.html:464 +#, fuzzy +#| msgid "StockItem has been allocated" +msgid "Stock item has been allocated" msgstr "Lagerobjekt wurde zugewiesen" -#: templates/js/stock.html:474 -msgid "StockItem is lost" +#: templates/js/stock.html:468 +#, fuzzy +#| msgid "StockItem has been allocated" +msgid "Stock item has been assigned to customer" +msgstr "Lagerobjekt wurde zugewiesen" + +#: templates/js/stock.html:470 +#, fuzzy +#| msgid "This stock item is allocated to Sales Order" +msgid "Stock item was assigned to a build order" +msgstr "Dieses Lagerobjekt ist dem Auftrag zugewiesen" + +#: templates/js/stock.html:472 +#, fuzzy +#| msgid "This stock item is allocated to Sales Order" +msgid "Stock item was assigned to a sales order" +msgstr "Dieses Lagerobjekt ist dem Auftrag zugewiesen" + +#: templates/js/stock.html:479 +#, fuzzy +#| msgid "StockItem has been allocated" +msgid "Stock item has been rejected" +msgstr "Lagerobjekt wurde zugewiesen" + +#: templates/js/stock.html:483 +#, fuzzy +#| msgid "StockItem is lost" +msgid "Stock item is lost" msgstr "Lagerobjekt verloren" -#: templates/js/stock.html:503 +#: templates/js/stock.html:487 templates/js/table_filters.html:52 +#, fuzzy +#| msgid "Delete" +msgid "Depleted" +msgstr "Löschen" + +#: templates/js/stock.html:516 #, fuzzy #| msgid "Item assigned to customer?" msgid "Shipped to customer" msgstr "Ist dieses Objekt einem Kunden zugeteilt?" -#: templates/js/stock.html:506 +#: templates/js/stock.html:519 msgid "No stock location set" msgstr "Kein Lagerort gesetzt" -#: templates/js/stock.html:678 +#: templates/js/stock.html:691 msgid "No user information" msgstr "Keine Benutzerinformation" -#: templates/js/table_filters.html:19 templates/js/table_filters.html:62 +#: templates/js/table_filters.html:19 templates/js/table_filters.html:67 #, fuzzy #| msgid "Serialize Stock" msgid "Is Serialized" msgstr "Lagerbestand erfassen" -#: templates/js/table_filters.html:22 templates/js/table_filters.html:65 +#: templates/js/table_filters.html:22 templates/js/table_filters.html:70 #, fuzzy #| msgid "Serial Number" msgid "Serial number GTE" msgstr "Seriennummer" -#: templates/js/table_filters.html:23 templates/js/table_filters.html:66 +#: templates/js/table_filters.html:23 templates/js/table_filters.html:71 #, fuzzy #| msgid "Serial number for this item" msgid "Serial number greater than or equal to" msgstr "Seriennummer für dieses Teil" -#: templates/js/table_filters.html:26 templates/js/table_filters.html:69 +#: templates/js/table_filters.html:26 templates/js/table_filters.html:74 #, fuzzy #| msgid "Serial Number" msgid "Serial number LTE" msgstr "Seriennummer" -#: templates/js/table_filters.html:27 templates/js/table_filters.html:70 +#: templates/js/table_filters.html:27 templates/js/table_filters.html:75 #, fuzzy #| msgid "Serial numbers already exist: " msgid "Serial number less than or equal to" msgstr "Seriennummern existieren bereits:" -#: templates/js/table_filters.html:38 -msgid "Show items which are in stock" -msgstr "" - -#: templates/js/table_filters.html:42 -msgid "Include sublocations" -msgstr "Unterlagerorte einschließen" - -#: templates/js/table_filters.html:43 -msgid "Include stock in sublocations" -msgstr "Bestand in Unterlagerorten einschließen" - -#: templates/js/table_filters.html:47 +#: templates/js/table_filters.html:37 msgid "Active parts" msgstr "Aktive Teile" -#: templates/js/table_filters.html:48 +#: templates/js/table_filters.html:38 msgid "Show stock for active parts" msgstr "Bestand aktiver Teile anzeigen" -#: templates/js/table_filters.html:52 templates/js/table_filters.html:53 -msgid "Stock status" -msgstr "Bestandsstatus" - -#: templates/js/table_filters.html:57 +#: templates/js/table_filters.html:42 msgid "Is allocated" msgstr "Ist zugeordnet" -#: templates/js/table_filters.html:58 +#: templates/js/table_filters.html:43 msgid "Item has been alloacted" msgstr "Position wurde zugeordnet" -#: templates/js/table_filters.html:99 +#: templates/js/table_filters.html:47 +msgid "Include sublocations" +msgstr "Unterlagerorte einschließen" + +#: templates/js/table_filters.html:48 +msgid "Include stock in sublocations" +msgstr "Bestand in Unterlagerorten einschließen" + +#: templates/js/table_filters.html:53 +#, fuzzy +#| msgid "Delete this Stock Item when stock is depleted" +msgid "Show stock items which are depleted" +msgstr "Objekt löschen wenn Lagerbestand aufgebraucht" + +#: templates/js/table_filters.html:58 +msgid "Show items which are in stock" +msgstr "" + +#: templates/js/table_filters.html:62 +#, fuzzy +#| msgid "Item assigned to customer?" +msgid "Sent to customer" +msgstr "Ist dieses Objekt einem Kunden zugeteilt?" + +#: templates/js/table_filters.html:63 +msgid "Show items which have been assigned to a customer" +msgstr "" + +#: templates/js/table_filters.html:79 templates/js/table_filters.html:80 +msgid "Stock status" +msgstr "Bestandsstatus" + +#: templates/js/table_filters.html:109 msgid "Build status" msgstr "Bau-Status" -#: templates/js/table_filters.html:111 templates/js/table_filters.html:124 +#: templates/js/table_filters.html:121 templates/js/table_filters.html:134 msgid "Order status" msgstr "Bestellstatus" -#: templates/js/table_filters.html:116 templates/js/table_filters.html:129 +#: templates/js/table_filters.html:126 templates/js/table_filters.html:139 #, fuzzy #| msgid "Cascading" msgid "Outstanding" msgstr "Kaskadierend" -#: templates/js/table_filters.html:139 +#: templates/js/table_filters.html:149 msgid "Include subcategories" msgstr "Unterkategorien einschließen" -#: templates/js/table_filters.html:140 +#: templates/js/table_filters.html:150 msgid "Include parts in subcategories" msgstr "Teile in Unterkategorien einschließen" -#: templates/js/table_filters.html:145 +#: templates/js/table_filters.html:155 msgid "Show active parts" msgstr "Aktive Teile anzeigen" -#: templates/js/table_filters.html:153 +#: templates/js/table_filters.html:163 msgid "Stock available" msgstr "Bestand verfügbar" -#: templates/js/table_filters.html:169 +#: templates/js/table_filters.html:179 msgid "Starred" msgstr "Favorit" -#: templates/js/table_filters.html:181 +#: templates/js/table_filters.html:191 msgid "Purchasable" msgstr "Käuflich" @@ -4123,6 +4260,12 @@ msgstr "Bestand bestellen" msgid "Delete Stock" msgstr "Bestand löschen" +#~ msgid "Used for Build" +#~ msgstr "Verwendet für Bau" + +#~ msgid "Installed in Stock Item" +#~ msgstr "In Lagerobjekt installiert" + #~ msgid "Count stock items" #~ msgstr "Lagerobjekte zählen" diff --git a/InvenTree/locale/en/LC_MESSAGES/django.po b/InvenTree/locale/en/LC_MESSAGES/django.po index 972a9ee6af..dda559ee7e 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-07-30 10:24+0000\n" +"POT-Creation-Date: 2020-08-16 02:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -78,7 +78,7 @@ msgstr "" msgid "File comment" msgstr "" -#: InvenTree/models.py:68 templates/js/stock.html:669 +#: InvenTree/models.py:68 templates/js/stock.html:682 msgid "User" msgstr "" @@ -90,24 +90,24 @@ msgstr "" msgid "Description (optional)" msgstr "" -#: InvenTree/settings.py:330 +#: InvenTree/settings.py:335 msgid "English" msgstr "" -#: InvenTree/settings.py:331 +#: InvenTree/settings.py:336 msgid "German" msgstr "" -#: InvenTree/settings.py:332 +#: InvenTree/settings.py:337 msgid "French" msgstr "" -#: InvenTree/settings.py:333 +#: InvenTree/settings.py:338 msgid "Polish" msgstr "" #: InvenTree/status_codes.py:94 InvenTree/status_codes.py:135 -#: InvenTree/status_codes.py:235 +#: InvenTree/status_codes.py:222 msgid "Pending" msgstr "" @@ -115,59 +115,50 @@ msgstr "" msgid "Placed" msgstr "" -#: InvenTree/status_codes.py:96 InvenTree/status_codes.py:238 +#: InvenTree/status_codes.py:96 InvenTree/status_codes.py:225 msgid "Complete" msgstr "" #: InvenTree/status_codes.py:97 InvenTree/status_codes.py:137 -#: InvenTree/status_codes.py:237 +#: InvenTree/status_codes.py:224 msgid "Cancelled" msgstr "" #: InvenTree/status_codes.py:98 InvenTree/status_codes.py:138 -#: InvenTree/status_codes.py:179 +#: InvenTree/status_codes.py:175 msgid "Lost" msgstr "" #: InvenTree/status_codes.py:99 InvenTree/status_codes.py:139 -#: InvenTree/status_codes.py:181 +#: InvenTree/status_codes.py:177 msgid "Returned" msgstr "" -#: InvenTree/status_codes.py:136 InvenTree/status_codes.py:182 -#: order/templates/order/sales_order_base.html:98 +#: InvenTree/status_codes.py:136 order/templates/order/sales_order_base.html:98 msgid "Shipped" msgstr "" -#: InvenTree/status_codes.py:175 +#: InvenTree/status_codes.py:171 msgid "OK" msgstr "" -#: InvenTree/status_codes.py:176 +#: InvenTree/status_codes.py:172 msgid "Attention needed" msgstr "" -#: InvenTree/status_codes.py:177 +#: InvenTree/status_codes.py:173 msgid "Damaged" msgstr "" -#: InvenTree/status_codes.py:178 +#: InvenTree/status_codes.py:174 msgid "Destroyed" msgstr "" -#: InvenTree/status_codes.py:180 +#: InvenTree/status_codes.py:176 msgid "Rejected" msgstr "" -#: InvenTree/status_codes.py:183 -msgid "Used for Build" -msgstr "" - -#: InvenTree/status_codes.py:184 -msgid "Installed in Stock Item" -msgstr "" - -#: InvenTree/status_codes.py:236 build/templates/build/allocate.html:349 +#: InvenTree/status_codes.py:223 build/templates/build/allocate.html:349 #: order/templates/order/sales_order_detail.html:220 #: part/templates/part/tabs.html:23 templates/js/build.html:120 msgid "Allocated" @@ -250,7 +241,7 @@ msgstr "" msgid "Serial numbers" msgstr "" -#: build/forms.py:64 stock/forms.py:93 +#: build/forms.py:64 stock/forms.py:105 msgid "Enter unique serial numbers (or leave blank)" msgstr "" @@ -289,7 +280,7 @@ msgstr "" #: part/templates/part/set_category.html:13 templates/js/barcode.html:336 #: templates/js/bom.html:135 templates/js/build.html:41 #: templates/js/company.html:109 templates/js/part.html:120 -#: templates/js/stock.html:424 +#: templates/js/stock.html:425 msgid "Part" msgstr "" @@ -331,7 +322,7 @@ msgstr "" msgid "Build status code" msgstr "" -#: build/models.py:136 stock/models.py:374 +#: build/models.py:136 stock/models.py:376 msgid "Batch Code" msgstr "" @@ -343,21 +334,21 @@ msgstr "" #: company/templates/company/supplier_part_base.html:60 #: company/templates/company/supplier_part_detail.html:24 #: part/templates/part/detail.html:74 part/templates/part/part_base.html:86 -#: stock/models.py:368 stock/templates/stock/item_base.html:230 +#: stock/models.py:370 stock/templates/stock/item_base.html:237 msgid "External Link" msgstr "" -#: build/models.py:156 stock/models.py:370 +#: build/models.py:156 stock/models.py:372 msgid "Link to external URL" msgstr "" -#: build/models.py:160 build/templates/build/tabs.html:14 company/models.py:307 +#: build/models.py:160 build/templates/build/tabs.html:14 company/models.py:310 #: company/templates/company/tabs.html:33 order/templates/order/po_tabs.html:15 #: order/templates/order/purchase_order_detail.html:200 #: order/templates/order/so_tabs.html:23 part/templates/part/tabs.html:64 -#: stock/models.py:436 stock/models.py:1265 stock/templates/stock/tabs.html:26 +#: stock/models.py:438 stock/models.py:1287 stock/templates/stock/tabs.html:26 #: templates/js/barcode.html:391 templates/js/bom.html:229 -#: templates/js/stock.html:113 templates/js/stock.html:513 +#: templates/js/stock.html:114 templates/js/stock.html:526 msgid "Notes" msgstr "" @@ -387,15 +378,15 @@ msgstr "" msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:512 +#: build/models.py:511 msgid "Build to allocate parts" msgstr "" -#: build/models.py:519 +#: build/models.py:518 msgid "Stock Item to allocate to build" msgstr "" -#: build/models.py:532 +#: build/models.py:531 msgid "Stock quantity to allocate to build" msgstr "" @@ -422,8 +413,8 @@ msgstr "" #: build/templates/build/allocate.html:161 #: order/templates/order/sales_order_detail.html:68 -#: order/templates/order/sales_order_detail.html:150 stock/models.py:362 -#: stock/templates/stock/item_base.html:146 +#: order/templates/order/sales_order_detail.html:150 stock/models.py:364 +#: stock/templates/stock/item_base.html:153 msgid "Serial Number" msgstr "" @@ -440,18 +431,18 @@ msgstr "" #: part/templates/part/allocation.html:49 #: stock/templates/stock/item_base.html:26 #: stock/templates/stock/item_base.html:32 -#: stock/templates/stock/item_base.html:152 +#: stock/templates/stock/item_base.html:159 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.html:338 #: templates/js/bom.html:172 templates/js/build.html:52 -#: templates/js/stock.html:660 +#: templates/js/stock.html:673 msgid "Quantity" msgstr "" #: build/templates/build/allocate.html:177 #: build/templates/build/auto_allocate.html:20 -#: stock/templates/stock/item_base.html:184 +#: stock/templates/stock/item_base.html:191 #: stock/templates/stock/stock_adjust.html:17 templates/js/barcode.html:337 -#: templates/js/stock.html:495 +#: templates/js/stock.html:508 msgid "Location" msgstr "" @@ -477,7 +468,7 @@ msgstr "" #: templates/js/bom.html:157 templates/js/company.html:60 #: templates/js/order.html:157 templates/js/order.html:230 #: templates/js/part.html:176 templates/js/part.html:355 -#: templates/js/stock.html:445 templates/js/stock.html:641 +#: templates/js/stock.html:440 templates/js/stock.html:654 msgid "Description" msgstr "" @@ -487,8 +478,8 @@ msgstr "" msgid "Reference" msgstr "" -#: build/templates/build/allocate.html:338 part/models.py:1269 -#: templates/js/part.html:359 templates/js/table_filters.html:90 +#: build/templates/build/allocate.html:338 part/models.py:1270 +#: templates/js/part.html:359 templates/js/table_filters.html:100 msgid "Required" msgstr "" @@ -531,7 +522,7 @@ msgstr "" #: build/templates/build/build_base.html:8 #: build/templates/build/build_base.html:34 #: build/templates/build/complete.html:6 -#: stock/templates/stock/item_base.html:209 templates/js/build.html:33 +#: stock/templates/stock/item_base.html:216 templates/js/build.html:33 #: templates/navbar.html:12 msgid "Build" msgstr "" @@ -551,9 +542,9 @@ msgstr "" #: build/templates/build/build_base.html:80 #: build/templates/build/detail.html:42 #: order/templates/order/receive_parts.html:24 -#: stock/templates/stock/item_base.html:262 templates/js/barcode.html:42 +#: stock/templates/stock/item_base.html:269 templates/js/barcode.html:42 #: templates/js/build.html:57 templates/js/order.html:162 -#: templates/js/order.html:235 templates/js/stock.html:482 +#: templates/js/order.html:235 templates/js/stock.html:495 msgid "Status" msgstr "" @@ -563,7 +554,7 @@ msgstr "" #: order/templates/order/sales_order_notes.html:10 #: order/templates/order/sales_order_ship.html:25 #: part/templates/part/allocation.html:27 -#: stock/templates/stock/item_base.html:172 templates/js/order.html:209 +#: stock/templates/stock/item_base.html:179 templates/js/order.html:209 msgid "Sales Order" msgstr "" @@ -630,7 +621,7 @@ msgid "Stock can be taken from any available location." msgstr "" #: build/templates/build/detail.html:48 -#: stock/templates/stock/item_base.html:202 templates/js/stock.html:490 +#: stock/templates/stock/item_base.html:209 templates/js/stock.html:503 msgid "Batch" msgstr "" @@ -733,7 +724,7 @@ msgstr "" msgid "Confirm unallocation of build stock" msgstr "" -#: build/views.py:162 stock/views.py:286 +#: build/views.py:162 stock/views.py:404 msgid "Check the confirmation box" msgstr "" @@ -741,7 +732,7 @@ msgstr "" msgid "Complete Build" msgstr "" -#: build/views.py:201 stock/views.py:1118 stock/views.py:1232 +#: build/views.py:201 stock/views.py:1236 stock/views.py:1350 msgid "Next available serial number is" msgstr "" @@ -757,7 +748,7 @@ msgstr "" msgid "Invalid location selected" msgstr "" -#: build/views.py:300 stock/views.py:1268 +#: build/views.py:300 stock/views.py:1386 #, python-brace-format msgid "The following serial numbers already exist: ({sn})" msgstr "" @@ -850,113 +841,113 @@ msgstr "" msgid "Delete Currency" msgstr "" -#: company/models.py:83 company/models.py:84 +#: company/models.py:86 company/models.py:87 msgid "Company name" msgstr "" -#: company/models.py:86 +#: company/models.py:89 msgid "Company description" msgstr "" -#: company/models.py:86 +#: company/models.py:89 msgid "Description of the company" msgstr "" -#: company/models.py:88 company/templates/company/company_base.html:48 +#: company/models.py:91 company/templates/company/company_base.html:48 #: templates/js/company.html:65 msgid "Website" msgstr "" -#: company/models.py:88 +#: company/models.py:91 msgid "Company website URL" msgstr "" -#: company/models.py:91 company/templates/company/company_base.html:55 +#: company/models.py:94 company/templates/company/company_base.html:55 msgid "Address" msgstr "" -#: company/models.py:92 +#: company/models.py:95 msgid "Company address" msgstr "" -#: company/models.py:95 +#: company/models.py:98 msgid "Phone number" msgstr "" -#: company/models.py:96 +#: company/models.py:99 msgid "Contact phone number" msgstr "" -#: company/models.py:98 company/templates/company/company_base.html:69 +#: company/models.py:101 company/templates/company/company_base.html:69 msgid "Email" msgstr "" -#: company/models.py:98 +#: company/models.py:101 msgid "Contact email address" msgstr "" -#: company/models.py:101 company/templates/company/company_base.html:76 +#: company/models.py:104 company/templates/company/company_base.html:76 msgid "Contact" msgstr "" -#: company/models.py:102 +#: company/models.py:105 msgid "Point of contact" msgstr "" -#: company/models.py:104 +#: company/models.py:107 msgid "Link to external company information" msgstr "" -#: company/models.py:116 +#: company/models.py:119 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:118 +#: company/models.py:121 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:120 +#: company/models.py:123 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:276 stock/models.py:322 -#: stock/templates/stock/item_base.html:138 +#: company/models.py:279 stock/models.py:324 +#: stock/templates/stock/item_base.html:145 msgid "Base Part" msgstr "" -#: company/models.py:281 +#: company/models.py:284 msgid "Select part" msgstr "" -#: company/models.py:287 +#: company/models.py:290 msgid "Select supplier" msgstr "" -#: company/models.py:290 +#: company/models.py:293 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:297 +#: company/models.py:300 msgid "Select manufacturer" msgstr "" -#: company/models.py:301 +#: company/models.py:304 msgid "Manufacturer part number" msgstr "" -#: company/models.py:303 +#: company/models.py:306 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:305 +#: company/models.py:308 msgid "Supplier part description" msgstr "" -#: company/models.py:309 +#: company/models.py:312 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:311 +#: company/models.py:314 msgid "Part packaging" msgstr "" @@ -991,14 +982,14 @@ msgstr "" #: company/templates/company/supplier_part_detail.html:21 order/models.py:148 #: order/templates/order/order_base.html:74 #: order/templates/order/order_wizard/select_pos.html:30 -#: stock/templates/stock/item_base.html:237 templates/js/company.html:52 +#: stock/templates/stock/item_base.html:244 templates/js/company.html:52 #: templates/js/company.html:134 templates/js/order.html:144 msgid "Supplier" msgstr "" #: company/templates/company/detail.html:26 order/models.py:314 -#: order/templates/order/sales_order_base.html:73 stock/models.py:357 -#: stock/models.py:358 stock/templates/stock/item_base.html:159 +#: order/templates/order/sales_order_base.html:73 stock/models.py:359 +#: stock/models.py:360 stock/templates/stock/item_base.html:166 #: templates/js/company.html:44 templates/js/order.html:217 msgid "Customer" msgstr "" @@ -1053,7 +1044,7 @@ msgstr "" msgid "Supplier Stock" msgstr "" -#: company/templates/company/detail_stock.html:34 +#: company/templates/company/detail_stock.html:35 #: company/templates/company/supplier_part_stock.html:33 #: part/templates/part/stock.html:53 templates/stock_table.html:5 msgid "Export" @@ -1111,8 +1102,8 @@ msgid "New Sales Order" msgstr "" #: company/templates/company/supplier_part_base.html:6 -#: company/templates/company/supplier_part_base.html:19 stock/models.py:331 -#: stock/templates/stock/item_base.html:242 templates/js/company.html:150 +#: company/templates/company/supplier_part_base.html:19 stock/models.py:333 +#: stock/templates/stock/item_base.html:249 templates/js/company.html:150 msgid "Supplier Part" msgstr "" @@ -1211,7 +1202,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:203 -#: templates/js/stock.html:453 templates/navbar.html:11 +#: templates/js/stock.html:448 templates/navbar.html:11 msgid "Stock" msgstr "" @@ -1311,6 +1302,22 @@ msgstr "" msgid "Delete Price Break" msgstr "" +#: label/models.py:55 +msgid "Label name" +msgstr "" + +#: label/models.py:58 +msgid "Label description" +msgstr "" + +#: label/models.py:63 +msgid "Label template file" +msgstr "" + +#: label/models.py:69 +msgid "Query filters (comma-separated list of key=value pairs" +msgstr "" + #: order/forms.py:24 msgid "Place order" msgstr "" @@ -1361,7 +1368,7 @@ msgid "Supplier order reference code" msgstr "" #: order/models.py:185 order/models.py:259 part/views.py:1167 -#: stock/models.py:243 stock/models.py:665 stock/views.py:1243 +#: stock/models.py:238 stock/models.py:687 msgid "Quantity must be greater than zero" msgstr "" @@ -1395,7 +1402,7 @@ msgstr "" #: order/models.py:466 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:23 -#: stock/templates/stock/item_base.html:216 templates/js/order.html:136 +#: stock/templates/stock/item_base.html:223 templates/js/order.html:136 msgid "Purchase Order" msgstr "" @@ -1672,7 +1679,7 @@ msgstr "" msgid "Add Purchase Order Attachment" msgstr "" -#: order/views.py:102 order/views.py:149 part/views.py:85 stock/views.py:166 +#: order/views.py:102 order/views.py:149 part/views.py:85 stock/views.py:167 msgid "Added attachment" msgstr "" @@ -1692,7 +1699,7 @@ msgstr "" msgid "Delete Attachment" msgstr "" -#: order/views.py:222 order/views.py:236 stock/views.py:222 +#: order/views.py:222 order/views.py:236 stock/views.py:223 msgid "Deleted attachment" msgstr "" @@ -1825,11 +1832,11 @@ msgstr "" msgid "Error reading BOM file (incorrect row size)" msgstr "" -#: part/forms.py:55 stock/forms.py:200 +#: part/forms.py:55 stock/forms.py:243 msgid "File Format" msgstr "" -#: part/forms.py:55 stock/forms.py:200 +#: part/forms.py:55 stock/forms.py:243 msgid "Select output file format" msgstr "" @@ -1877,207 +1884,220 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:427 +#: part/models.py:74 part/templates/part/part_app_base.html:9 +msgid "Part Category" +msgstr "" + +#: part/models.py:75 part/templates/part/category.html:13 +#: part/templates/part/category.html:78 templates/stats.html:12 +msgid "Part Categories" +msgstr "" + +#: part/models.py:428 msgid "Part must be unique for name, IPN and revision" msgstr "" -#: part/models.py:442 part/templates/part/detail.html:19 +#: part/models.py:443 part/templates/part/detail.html:19 msgid "Part name" msgstr "" -#: part/models.py:446 +#: part/models.py:447 msgid "Is this part a template part?" msgstr "" -#: part/models.py:455 +#: part/models.py:456 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:457 +#: part/models.py:458 msgid "Part description" msgstr "" -#: part/models.py:459 +#: part/models.py:460 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:464 +#: part/models.py:465 msgid "Part category" msgstr "" -#: part/models.py:466 +#: part/models.py:467 msgid "Internal Part Number" msgstr "" -#: part/models.py:468 +#: part/models.py:469 msgid "Part revision or version number" msgstr "" -#: part/models.py:470 +#: part/models.py:471 msgid "Link to extenal URL" msgstr "" -#: part/models.py:482 +#: part/models.py:483 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:526 +#: part/models.py:527 msgid "Default supplier part" msgstr "" -#: part/models.py:529 +#: part/models.py:530 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:531 +#: part/models.py:532 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:533 +#: part/models.py:534 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:535 +#: part/models.py:536 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:537 +#: part/models.py:538 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:539 +#: part/models.py:540 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:541 +#: part/models.py:542 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:543 +#: part/models.py:544 msgid "Is this part active?" msgstr "" -#: part/models.py:545 +#: part/models.py:546 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:547 +#: part/models.py:548 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:549 +#: part/models.py:550 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1221 +#: part/models.py:1222 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:1238 +#: part/models.py:1239 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:1257 templates/js/part.html:350 templates/js/stock.html:89 +#: part/models.py:1258 templates/js/part.html:350 templates/js/stock.html:90 msgid "Test Name" msgstr "" -#: part/models.py:1258 +#: part/models.py:1259 msgid "Enter a name for the test" msgstr "" -#: part/models.py:1263 +#: part/models.py:1264 msgid "Test Description" msgstr "" -#: part/models.py:1264 +#: part/models.py:1265 msgid "Enter description for this test" msgstr "" -#: part/models.py:1270 +#: part/models.py:1271 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:1275 templates/js/part.html:367 +#: part/models.py:1276 templates/js/part.html:367 msgid "Requires Value" msgstr "" -#: part/models.py:1276 +#: part/models.py:1277 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:1281 templates/js/part.html:374 +#: part/models.py:1282 templates/js/part.html:374 msgid "Requires Attachment" msgstr "" -#: part/models.py:1282 +#: part/models.py:1283 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:1315 +#: part/models.py:1316 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:1320 +#: part/models.py:1321 msgid "Parameter Name" msgstr "" -#: part/models.py:1322 +#: part/models.py:1323 msgid "Parameter Units" msgstr "" -#: part/models.py:1348 +#: part/models.py:1349 msgid "Parent Part" msgstr "" -#: part/models.py:1350 +#: part/models.py:1351 msgid "Parameter Template" msgstr "" -#: part/models.py:1352 +#: part/models.py:1353 msgid "Parameter Value" msgstr "" -#: part/models.py:1381 +#: part/models.py:1382 msgid "Select parent part" msgstr "" -#: part/models.py:1389 +#: part/models.py:1390 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:1395 +#: part/models.py:1396 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:1398 +#: part/models.py:1399 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:1401 +#: part/models.py:1402 msgid "BOM item reference" msgstr "" -#: part/models.py:1404 +#: part/models.py:1405 msgid "BOM item notes" msgstr "" -#: part/models.py:1406 +#: part/models.py:1407 msgid "BOM line checksum" msgstr "" -#: part/models.py:1470 stock/models.py:233 +#: part/models.py:1471 stock/models.py:228 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:1479 +#: part/models.py:1480 msgid "Part cannot be added to its own Bill of Materials" msgstr "" -#: part/models.py:1486 +#: part/models.py:1487 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" +#: part/models.py:1494 +msgid "BOM Item" +msgstr "" + #: part/templates/part/allocation.html:10 msgid "Part Stock Allocations" msgstr "" @@ -2093,14 +2113,14 @@ msgstr "" #: part/templates/part/allocation.html:45 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:58 -#: stock/templates/stock/item_base.html:224 +#: stock/templates/stock/item_base.html:231 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.html:106 -#: templates/js/stock.html:630 +#: templates/js/stock.html:643 msgid "Stock Item" msgstr "" #: part/templates/part/allocation.html:20 -#: stock/templates/stock/item_base.html:178 +#: stock/templates/stock/item_base.html:185 msgid "Build Order" msgstr "" @@ -2140,11 +2160,6 @@ msgstr "" msgid "Export Bill of Materials" msgstr "" -#: part/templates/part/category.html:13 part/templates/part/category.html:78 -#: templates/stats.html:12 -msgid "Part Categories" -msgstr "" - #: part/templates/part/category.html:14 msgid "All parts" msgstr "" @@ -2238,8 +2253,8 @@ msgstr "" msgid "Part is not a virtual part" msgstr "" -#: part/templates/part/detail.html:139 stock/forms.py:194 -#: templates/js/table_filters.html:149 +#: part/templates/part/detail.html:139 stock/forms.py:237 +#: templates/js/table_filters.html:159 msgid "Template" msgstr "" @@ -2251,7 +2266,7 @@ msgstr "" msgid "Part is not a template part" msgstr "" -#: part/templates/part/detail.html:148 templates/js/table_filters.html:161 +#: part/templates/part/detail.html:148 templates/js/table_filters.html:171 msgid "Assembly" msgstr "" @@ -2263,7 +2278,7 @@ msgstr "" msgid "Part cannot be assembled from other parts" msgstr "" -#: part/templates/part/detail.html:157 templates/js/table_filters.html:165 +#: part/templates/part/detail.html:157 templates/js/table_filters.html:175 msgid "Component" msgstr "" @@ -2275,7 +2290,7 @@ msgstr "" msgid "Part cannot be used in assemblies" msgstr "" -#: part/templates/part/detail.html:166 templates/js/table_filters.html:177 +#: part/templates/part/detail.html:166 templates/js/table_filters.html:187 msgid "Trackable" msgstr "" @@ -2295,7 +2310,7 @@ msgstr "" msgid "Part can be purchased from external suppliers" msgstr "" -#: part/templates/part/detail.html:184 templates/js/table_filters.html:173 +#: part/templates/part/detail.html:184 templates/js/table_filters.html:183 msgid "Salable" msgstr "" @@ -2307,7 +2322,7 @@ msgstr "" msgid "Part cannot be sold to customers" msgstr "" -#: part/templates/part/detail.html:193 templates/js/table_filters.html:144 +#: part/templates/part/detail.html:193 templates/js/table_filters.html:154 msgid "Active" msgstr "" @@ -2339,8 +2354,8 @@ msgstr "" msgid "New Parameter" msgstr "" -#: part/templates/part/params.html:21 stock/models.py:1252 -#: templates/js/stock.html:109 +#: part/templates/part/params.html:21 stock/models.py:1274 +#: templates/js/stock.html:110 msgid "Value" msgstr "" @@ -2352,10 +2367,6 @@ msgstr "" msgid "Delete" msgstr "" -#: part/templates/part/part_app_base.html:9 -msgid "Part Category" -msgstr "" - #: part/templates/part/part_app_base.html:11 msgid "Part List" msgstr "" @@ -2423,7 +2434,7 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/templates/part/part_base.html:108 templates/js/table_filters.html:37 +#: part/templates/part/part_base.html:108 templates/js/table_filters.html:57 msgid "In Stock" msgstr "" @@ -2524,7 +2535,7 @@ msgstr "" msgid "Used In" msgstr "" -#: part/templates/part/tabs.html:55 stock/templates/stock/item_base.html:268 +#: part/templates/part/tabs.html:55 stock/templates/stock/item_base.html:275 msgid "Tests" msgstr "" @@ -2741,215 +2752,227 @@ msgstr "" msgid "Asset file description" msgstr "" -#: stock/forms.py:194 +#: stock/forms.py:185 +msgid "Label" +msgstr "" + +#: stock/forms.py:186 stock/forms.py:237 msgid "Select test report template" msgstr "" -#: stock/forms.py:202 +#: stock/forms.py:245 msgid "Include stock items in sub locations" msgstr "" -#: stock/forms.py:235 +#: stock/forms.py:278 msgid "Destination stock location" msgstr "" -#: stock/forms.py:241 +#: stock/forms.py:284 msgid "Confirm movement of stock items" msgstr "" -#: stock/forms.py:243 +#: stock/forms.py:286 msgid "Set the destination as the default location for selected parts" msgstr "" -#: stock/models.py:208 +#: stock/models.py:209 msgid "StockItem with this serial number already exists" msgstr "" -#: stock/models.py:250 +#: stock/models.py:245 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "" -#: stock/models.py:260 stock/models.py:269 +#: stock/models.py:255 stock/models.py:264 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:261 +#: stock/models.py:256 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:282 +#: stock/models.py:277 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:314 +#: stock/models.py:316 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:323 +#: stock/models.py:325 msgid "Base part" msgstr "" -#: stock/models.py:332 +#: stock/models.py:334 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:337 stock/templates/stock/stock_app_base.html:7 +#: stock/models.py:339 stock/templates/stock/stock_app_base.html:7 msgid "Stock Location" msgstr "" -#: stock/models.py:340 +#: stock/models.py:342 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:345 +#: stock/models.py:347 msgid "Installed In" msgstr "" -#: stock/models.py:348 +#: stock/models.py:350 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:364 +#: stock/models.py:366 msgid "Serial number for this item" msgstr "" -#: stock/models.py:376 +#: stock/models.py:378 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:380 +#: stock/models.py:382 msgid "Stock Quantity" msgstr "" -#: stock/models.py:389 +#: stock/models.py:391 msgid "Source Build" msgstr "" -#: stock/models.py:391 +#: stock/models.py:393 msgid "Build for this stock item" msgstr "" -#: stock/models.py:398 +#: stock/models.py:400 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:401 +#: stock/models.py:403 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:407 +#: stock/models.py:409 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:414 +#: stock/models.py:416 msgid "Destination Build Order" msgstr "" -#: stock/models.py:427 +#: stock/models.py:429 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:437 stock/templates/stock/item_notes.html:14 +#: stock/models.py:439 stock/templates/stock/item_notes.html:14 #: stock/templates/stock/item_notes.html:30 msgid "Stock Item Notes" msgstr "" -#: stock/models.py:489 +#: stock/models.py:490 msgid "Assigned to Customer" msgstr "" -#: stock/models.py:491 +#: stock/models.py:492 msgid "Manually assigned to customer" msgstr "" -#: stock/models.py:656 +#: stock/models.py:505 +msgid "Returned from customer" +msgstr "" + +#: stock/models.py:507 +msgid "Returned to location" +msgstr "" + +#: stock/models.py:678 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:662 +#: stock/models.py:684 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:668 +#: stock/models.py:690 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "" -#: stock/models.py:671 stock/models.py:674 +#: stock/models.py:693 stock/models.py:696 msgid "Serial numbers must be a list of integers" msgstr "" -#: stock/models.py:677 +#: stock/models.py:699 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:687 +#: stock/models.py:709 msgid "Serial numbers already exist: " msgstr "" -#: stock/models.py:712 +#: stock/models.py:734 msgid "Add serial number" msgstr "" -#: stock/models.py:715 +#: stock/models.py:737 #, python-brace-format msgid "Serialized {n} items" msgstr "" -#: stock/models.py:826 +#: stock/models.py:848 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1175 msgid "Tracking entry title" msgstr "" -#: stock/models.py:1155 +#: stock/models.py:1177 msgid "Entry notes" msgstr "" -#: stock/models.py:1157 +#: stock/models.py:1179 msgid "Link to external page for further information" msgstr "" -#: stock/models.py:1217 +#: stock/models.py:1239 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:1223 +#: stock/models.py:1245 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:1240 +#: stock/models.py:1262 msgid "Test" msgstr "" -#: stock/models.py:1241 +#: stock/models.py:1263 msgid "Test name" msgstr "" -#: stock/models.py:1246 +#: stock/models.py:1268 msgid "Result" msgstr "" -#: stock/models.py:1247 templates/js/table_filters.html:80 +#: stock/models.py:1269 templates/js/table_filters.html:90 msgid "Test result" msgstr "" -#: stock/models.py:1253 +#: stock/models.py:1275 msgid "Test output value" msgstr "" -#: stock/models.py:1259 +#: stock/models.py:1281 msgid "Attachment" msgstr "" -#: stock/models.py:1260 +#: stock/models.py:1282 msgid "Test result attachment" msgstr "" -#: stock/models.py:1266 +#: stock/models.py:1288 msgid "Test notes" msgstr "" @@ -2997,7 +3020,7 @@ msgstr "" msgid "Link Barcode" msgstr "" -#: stock/templates/stock/item_base.html:92 +#: stock/templates/stock/item_base.html:91 msgid "Stock adjustment actions" msgstr "" @@ -3018,68 +3041,76 @@ msgstr "" msgid "Transfer stock" msgstr "" +#: stock/templates/stock/item_base.html:101 +msgid "Serialize stock" +msgstr "" + #: stock/templates/stock/item_base.html:105 +msgid "Assign to customer" +msgstr "" + +#: stock/templates/stock/item_base.html:108 +msgid "Return to stock" +msgstr "" + +#: stock/templates/stock/item_base.html:114 #: stock/templates/stock/location.html:30 msgid "Stock actions" msgstr "" -#: stock/templates/stock/item_base.html:108 -msgid "Serialize stock" -msgstr "" - -#: stock/templates/stock/item_base.html:111 -msgid "Assign to customer" -msgstr "" - -#: stock/templates/stock/item_base.html:114 +#: stock/templates/stock/item_base.html:118 msgid "Convert to variant" msgstr "" -#: stock/templates/stock/item_base.html:116 +#: stock/templates/stock/item_base.html:120 msgid "Duplicate stock item" msgstr "" -#: stock/templates/stock/item_base.html:117 +#: stock/templates/stock/item_base.html:121 msgid "Edit stock item" msgstr "" -#: stock/templates/stock/item_base.html:119 +#: stock/templates/stock/item_base.html:123 msgid "Delete stock item" msgstr "" -#: stock/templates/stock/item_base.html:124 +#: stock/templates/stock/item_base.html:128 msgid "Generate test report" msgstr "" -#: stock/templates/stock/item_base.html:133 +#: stock/templates/stock/item_base.html:132 +msgid "Print labels" +msgstr "" + +#: stock/templates/stock/item_base.html:140 msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:166 +#: stock/templates/stock/item_base.html:173 msgid "Belongs To" msgstr "" -#: stock/templates/stock/item_base.html:188 +#: stock/templates/stock/item_base.html:195 msgid "No location set" msgstr "" -#: stock/templates/stock/item_base.html:195 +#: stock/templates/stock/item_base.html:202 msgid "Unique Identifier" msgstr "" -#: stock/templates/stock/item_base.html:223 +#: stock/templates/stock/item_base.html:230 msgid "Parent Item" msgstr "" -#: stock/templates/stock/item_base.html:248 +#: stock/templates/stock/item_base.html:255 msgid "Last Updated" msgstr "" -#: stock/templates/stock/item_base.html:253 +#: stock/templates/stock/item_base.html:260 msgid "Last Stocktake" msgstr "" -#: stock/templates/stock/item_base.html:257 +#: stock/templates/stock/item_base.html:264 msgid "No stocktake performed" msgstr "" @@ -3166,7 +3197,11 @@ msgstr "" msgid "Are you sure you want to delete this stock location?" msgstr "" -#: stock/templates/stock/stockitem_convert.html:7 stock/views.py:934 +#: stock/templates/stock/stock_adjust.html:35 +msgid "Stock item is serialized and quantity cannot be adjusted" +msgstr "" + +#: stock/templates/stock/stockitem_convert.html:7 stock/views.py:1052 msgid "Convert Stock Item" msgstr "" @@ -3194,190 +3229,214 @@ msgstr "" msgid "Children" msgstr "" -#: stock/views.py:113 +#: stock/views.py:114 msgid "Edit Stock Location" msgstr "" -#: stock/views.py:137 +#: stock/views.py:138 msgid "Stock Location QR code" msgstr "" -#: stock/views.py:155 +#: stock/views.py:156 msgid "Add Stock Item Attachment" msgstr "" -#: stock/views.py:200 +#: stock/views.py:201 msgid "Edit Stock Item Attachment" msgstr "" -#: stock/views.py:216 +#: stock/views.py:217 msgid "Delete Stock Item Attachment" msgstr "" -#: stock/views.py:232 +#: stock/views.py:233 msgid "Assign to Customer" msgstr "" #: stock/views.py:270 -msgid "Delete All Test Data" +msgid "Return to Stock" msgstr "" -#: stock/views.py:285 -msgid "Confirm test data deletion" +#: stock/views.py:289 +msgid "Specify a valid location" +msgstr "" + +#: stock/views.py:293 +msgid "Stock item returned from customer" msgstr "" #: stock/views.py:305 +msgid "Select Label Template" +msgstr "" + +#: stock/views.py:326 +msgid "Select valid label" +msgstr "" + +#: stock/views.py:388 +msgid "Delete All Test Data" +msgstr "" + +#: stock/views.py:403 +msgid "Confirm test data deletion" +msgstr "" + +#: stock/views.py:423 msgid "Add Test Result" msgstr "" -#: stock/views.py:342 +#: stock/views.py:460 msgid "Edit Test Result" msgstr "" -#: stock/views.py:359 +#: stock/views.py:477 msgid "Delete Test Result" msgstr "" -#: stock/views.py:370 +#: stock/views.py:488 msgid "Select Test Report Template" msgstr "" -#: stock/views.py:384 +#: stock/views.py:502 msgid "Select valid template" msgstr "" -#: stock/views.py:436 +#: stock/views.py:554 msgid "Stock Export Options" msgstr "" -#: stock/views.py:556 +#: stock/views.py:674 msgid "Stock Item QR Code" msgstr "" -#: stock/views.py:579 +#: stock/views.py:697 msgid "Adjust Stock" msgstr "" -#: stock/views.py:688 +#: stock/views.py:806 msgid "Move Stock Items" msgstr "" -#: stock/views.py:689 +#: stock/views.py:807 msgid "Count Stock Items" msgstr "" -#: stock/views.py:690 +#: stock/views.py:808 msgid "Remove From Stock" msgstr "" -#: stock/views.py:691 +#: stock/views.py:809 msgid "Add Stock Items" msgstr "" -#: stock/views.py:692 +#: stock/views.py:810 msgid "Delete Stock Items" msgstr "" -#: stock/views.py:720 +#: stock/views.py:838 msgid "Must enter integer value" msgstr "" -#: stock/views.py:725 +#: stock/views.py:843 msgid "Quantity must be positive" msgstr "" -#: stock/views.py:732 +#: stock/views.py:850 #, python-brace-format msgid "Quantity must not exceed {x}" msgstr "" -#: stock/views.py:740 +#: stock/views.py:858 msgid "Confirm stock adjustment" msgstr "" -#: stock/views.py:811 +#: stock/views.py:929 #, python-brace-format msgid "Added stock to {n} items" msgstr "" -#: stock/views.py:826 +#: stock/views.py:944 #, python-brace-format msgid "Removed stock from {n} items" msgstr "" -#: stock/views.py:839 +#: stock/views.py:957 #, python-brace-format msgid "Counted stock for {n} items" msgstr "" -#: stock/views.py:867 +#: stock/views.py:985 msgid "No items were moved" msgstr "" -#: stock/views.py:870 +#: stock/views.py:988 #, python-brace-format msgid "Moved {n} items to {dest}" msgstr "" -#: stock/views.py:889 +#: stock/views.py:1007 #, python-brace-format msgid "Deleted {n} stock items" msgstr "" -#: stock/views.py:901 +#: stock/views.py:1019 msgid "Edit Stock Item" msgstr "" -#: stock/views.py:961 +#: stock/views.py:1079 msgid "Create new Stock Location" msgstr "" -#: stock/views.py:982 +#: stock/views.py:1100 msgid "Serialize Stock" msgstr "" -#: stock/views.py:1074 +#: stock/views.py:1192 msgid "Create new Stock Item" msgstr "" -#: stock/views.py:1167 +#: stock/views.py:1285 msgid "Duplicate Stock Item" msgstr "" -#: stock/views.py:1240 +#: stock/views.py:1358 msgid "Invalid quantity" msgstr "" -#: stock/views.py:1247 +#: stock/views.py:1361 +msgid "Quantity cannot be less than zero" +msgstr "" + +#: stock/views.py:1365 msgid "Invalid part selection" msgstr "" -#: stock/views.py:1296 +#: stock/views.py:1414 #, python-brace-format msgid "Created {n} new stock items" msgstr "" -#: stock/views.py:1315 stock/views.py:1331 +#: stock/views.py:1433 stock/views.py:1449 msgid "Created new stock item" msgstr "" -#: stock/views.py:1350 +#: stock/views.py:1468 msgid "Delete Stock Location" msgstr "" -#: stock/views.py:1363 +#: stock/views.py:1481 msgid "Delete Stock Item" msgstr "" -#: stock/views.py:1374 +#: stock/views.py:1492 msgid "Delete Stock Tracking Entry" msgstr "" -#: stock/views.py:1391 +#: stock/views.py:1509 msgid "Edit Stock Tracking Entry" msgstr "" -#: stock/views.py:1400 +#: stock/views.py:1518 msgid "Add Stock Tracking Entry" msgstr "" @@ -3602,7 +3661,7 @@ msgstr "" msgid "No purchase orders found" msgstr "" -#: templates/js/order.html:170 templates/js/stock.html:612 +#: templates/js/order.html:170 templates/js/stock.html:625 msgid "Date" msgstr "" @@ -3614,7 +3673,7 @@ msgstr "" msgid "Shipment Date" msgstr "" -#: templates/js/part.html:106 templates/js/stock.html:405 +#: templates/js/part.html:106 templates/js/stock.html:406 msgid "Select" msgstr "" @@ -3630,7 +3689,7 @@ msgstr "" msgid "No category" msgstr "" -#: templates/js/part.html:214 templates/js/table_filters.html:157 +#: templates/js/part.html:214 templates/js/table_filters.html:167 msgid "Low stock" msgstr "" @@ -3654,11 +3713,11 @@ msgstr "" msgid "No test templates matching query" msgstr "" -#: templates/js/part.html:387 templates/js/stock.html:62 +#: templates/js/part.html:387 templates/js/stock.html:63 msgid "Edit test result" msgstr "" -#: templates/js/part.html:388 templates/js/stock.html:63 +#: templates/js/part.html:388 templates/js/stock.html:64 msgid "Delete test result" msgstr "" @@ -3666,143 +3725,175 @@ msgstr "" msgid "This test is defined for a parent part" msgstr "" -#: templates/js/stock.html:25 +#: templates/js/stock.html:26 msgid "PASS" msgstr "" -#: templates/js/stock.html:27 +#: templates/js/stock.html:28 msgid "FAIL" msgstr "" -#: templates/js/stock.html:32 +#: templates/js/stock.html:33 msgid "NO RESULT" msgstr "" -#: templates/js/stock.html:58 +#: templates/js/stock.html:59 msgid "Add test result" msgstr "" -#: templates/js/stock.html:76 +#: templates/js/stock.html:77 msgid "No test results found" msgstr "" -#: templates/js/stock.html:117 +#: templates/js/stock.html:118 msgid "Test Date" msgstr "" -#: templates/js/stock.html:260 +#: templates/js/stock.html:261 msgid "No stock items matching query" msgstr "" -#: templates/js/stock.html:357 templates/js/stock.html:372 +#: templates/js/stock.html:358 templates/js/stock.html:373 msgid "Undefined location" msgstr "" -#: templates/js/stock.html:469 -msgid "StockItem has been allocated" +#: templates/js/stock.html:464 +msgid "Stock item has been allocated" msgstr "" -#: templates/js/stock.html:474 -msgid "StockItem is lost" +#: templates/js/stock.html:468 +msgid "Stock item has been assigned to customer" msgstr "" -#: templates/js/stock.html:503 +#: templates/js/stock.html:470 +msgid "Stock item was assigned to a build order" +msgstr "" + +#: templates/js/stock.html:472 +msgid "Stock item was assigned to a sales order" +msgstr "" + +#: templates/js/stock.html:479 +msgid "Stock item has been rejected" +msgstr "" + +#: templates/js/stock.html:483 +msgid "Stock item is lost" +msgstr "" + +#: templates/js/stock.html:487 templates/js/table_filters.html:52 +msgid "Depleted" +msgstr "" + +#: templates/js/stock.html:516 msgid "Shipped to customer" msgstr "" -#: templates/js/stock.html:506 +#: templates/js/stock.html:519 msgid "No stock location set" msgstr "" -#: templates/js/stock.html:678 +#: templates/js/stock.html:691 msgid "No user information" msgstr "" -#: templates/js/table_filters.html:19 templates/js/table_filters.html:62 +#: templates/js/table_filters.html:19 templates/js/table_filters.html:67 msgid "Is Serialized" msgstr "" -#: templates/js/table_filters.html:22 templates/js/table_filters.html:65 +#: templates/js/table_filters.html:22 templates/js/table_filters.html:70 msgid "Serial number GTE" msgstr "" -#: templates/js/table_filters.html:23 templates/js/table_filters.html:66 +#: templates/js/table_filters.html:23 templates/js/table_filters.html:71 msgid "Serial number greater than or equal to" msgstr "" -#: templates/js/table_filters.html:26 templates/js/table_filters.html:69 +#: templates/js/table_filters.html:26 templates/js/table_filters.html:74 msgid "Serial number LTE" msgstr "" -#: templates/js/table_filters.html:27 templates/js/table_filters.html:70 +#: templates/js/table_filters.html:27 templates/js/table_filters.html:75 msgid "Serial number less than or equal to" msgstr "" -#: templates/js/table_filters.html:38 -msgid "Show items which are in stock" -msgstr "" - -#: templates/js/table_filters.html:42 -msgid "Include sublocations" -msgstr "" - -#: templates/js/table_filters.html:43 -msgid "Include stock in sublocations" -msgstr "" - -#: templates/js/table_filters.html:47 +#: templates/js/table_filters.html:37 msgid "Active parts" msgstr "" -#: templates/js/table_filters.html:48 +#: templates/js/table_filters.html:38 msgid "Show stock for active parts" msgstr "" -#: templates/js/table_filters.html:52 templates/js/table_filters.html:53 -msgid "Stock status" -msgstr "" - -#: templates/js/table_filters.html:57 +#: templates/js/table_filters.html:42 msgid "Is allocated" msgstr "" -#: templates/js/table_filters.html:58 +#: templates/js/table_filters.html:43 msgid "Item has been alloacted" msgstr "" -#: templates/js/table_filters.html:99 +#: templates/js/table_filters.html:47 +msgid "Include sublocations" +msgstr "" + +#: templates/js/table_filters.html:48 +msgid "Include stock in sublocations" +msgstr "" + +#: templates/js/table_filters.html:53 +msgid "Show stock items which are depleted" +msgstr "" + +#: templates/js/table_filters.html:58 +msgid "Show items which are in stock" +msgstr "" + +#: templates/js/table_filters.html:62 +msgid "Sent to customer" +msgstr "" + +#: templates/js/table_filters.html:63 +msgid "Show items which have been assigned to a customer" +msgstr "" + +#: templates/js/table_filters.html:79 templates/js/table_filters.html:80 +msgid "Stock status" +msgstr "" + +#: templates/js/table_filters.html:109 msgid "Build status" msgstr "" -#: templates/js/table_filters.html:111 templates/js/table_filters.html:124 +#: templates/js/table_filters.html:121 templates/js/table_filters.html:134 msgid "Order status" msgstr "" -#: templates/js/table_filters.html:116 templates/js/table_filters.html:129 +#: templates/js/table_filters.html:126 templates/js/table_filters.html:139 msgid "Outstanding" msgstr "" -#: templates/js/table_filters.html:139 +#: templates/js/table_filters.html:149 msgid "Include subcategories" msgstr "" -#: templates/js/table_filters.html:140 +#: templates/js/table_filters.html:150 msgid "Include parts in subcategories" msgstr "" -#: templates/js/table_filters.html:145 +#: templates/js/table_filters.html:155 msgid "Show active parts" msgstr "" -#: templates/js/table_filters.html:153 +#: templates/js/table_filters.html:163 msgid "Stock available" msgstr "" -#: templates/js/table_filters.html:169 +#: templates/js/table_filters.html:179 msgid "Starred" msgstr "" -#: templates/js/table_filters.html:181 +#: templates/js/table_filters.html:191 msgid "Purchasable" msgstr "" diff --git a/InvenTree/locale/es/LC_MESSAGES/django.po b/InvenTree/locale/es/LC_MESSAGES/django.po index 972a9ee6af..dda559ee7e 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-07-30 10:24+0000\n" +"POT-Creation-Date: 2020-08-16 02:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -78,7 +78,7 @@ msgstr "" msgid "File comment" msgstr "" -#: InvenTree/models.py:68 templates/js/stock.html:669 +#: InvenTree/models.py:68 templates/js/stock.html:682 msgid "User" msgstr "" @@ -90,24 +90,24 @@ msgstr "" msgid "Description (optional)" msgstr "" -#: InvenTree/settings.py:330 +#: InvenTree/settings.py:335 msgid "English" msgstr "" -#: InvenTree/settings.py:331 +#: InvenTree/settings.py:336 msgid "German" msgstr "" -#: InvenTree/settings.py:332 +#: InvenTree/settings.py:337 msgid "French" msgstr "" -#: InvenTree/settings.py:333 +#: InvenTree/settings.py:338 msgid "Polish" msgstr "" #: InvenTree/status_codes.py:94 InvenTree/status_codes.py:135 -#: InvenTree/status_codes.py:235 +#: InvenTree/status_codes.py:222 msgid "Pending" msgstr "" @@ -115,59 +115,50 @@ msgstr "" msgid "Placed" msgstr "" -#: InvenTree/status_codes.py:96 InvenTree/status_codes.py:238 +#: InvenTree/status_codes.py:96 InvenTree/status_codes.py:225 msgid "Complete" msgstr "" #: InvenTree/status_codes.py:97 InvenTree/status_codes.py:137 -#: InvenTree/status_codes.py:237 +#: InvenTree/status_codes.py:224 msgid "Cancelled" msgstr "" #: InvenTree/status_codes.py:98 InvenTree/status_codes.py:138 -#: InvenTree/status_codes.py:179 +#: InvenTree/status_codes.py:175 msgid "Lost" msgstr "" #: InvenTree/status_codes.py:99 InvenTree/status_codes.py:139 -#: InvenTree/status_codes.py:181 +#: InvenTree/status_codes.py:177 msgid "Returned" msgstr "" -#: InvenTree/status_codes.py:136 InvenTree/status_codes.py:182 -#: order/templates/order/sales_order_base.html:98 +#: InvenTree/status_codes.py:136 order/templates/order/sales_order_base.html:98 msgid "Shipped" msgstr "" -#: InvenTree/status_codes.py:175 +#: InvenTree/status_codes.py:171 msgid "OK" msgstr "" -#: InvenTree/status_codes.py:176 +#: InvenTree/status_codes.py:172 msgid "Attention needed" msgstr "" -#: InvenTree/status_codes.py:177 +#: InvenTree/status_codes.py:173 msgid "Damaged" msgstr "" -#: InvenTree/status_codes.py:178 +#: InvenTree/status_codes.py:174 msgid "Destroyed" msgstr "" -#: InvenTree/status_codes.py:180 +#: InvenTree/status_codes.py:176 msgid "Rejected" msgstr "" -#: InvenTree/status_codes.py:183 -msgid "Used for Build" -msgstr "" - -#: InvenTree/status_codes.py:184 -msgid "Installed in Stock Item" -msgstr "" - -#: InvenTree/status_codes.py:236 build/templates/build/allocate.html:349 +#: InvenTree/status_codes.py:223 build/templates/build/allocate.html:349 #: order/templates/order/sales_order_detail.html:220 #: part/templates/part/tabs.html:23 templates/js/build.html:120 msgid "Allocated" @@ -250,7 +241,7 @@ msgstr "" msgid "Serial numbers" msgstr "" -#: build/forms.py:64 stock/forms.py:93 +#: build/forms.py:64 stock/forms.py:105 msgid "Enter unique serial numbers (or leave blank)" msgstr "" @@ -289,7 +280,7 @@ msgstr "" #: part/templates/part/set_category.html:13 templates/js/barcode.html:336 #: templates/js/bom.html:135 templates/js/build.html:41 #: templates/js/company.html:109 templates/js/part.html:120 -#: templates/js/stock.html:424 +#: templates/js/stock.html:425 msgid "Part" msgstr "" @@ -331,7 +322,7 @@ msgstr "" msgid "Build status code" msgstr "" -#: build/models.py:136 stock/models.py:374 +#: build/models.py:136 stock/models.py:376 msgid "Batch Code" msgstr "" @@ -343,21 +334,21 @@ msgstr "" #: company/templates/company/supplier_part_base.html:60 #: company/templates/company/supplier_part_detail.html:24 #: part/templates/part/detail.html:74 part/templates/part/part_base.html:86 -#: stock/models.py:368 stock/templates/stock/item_base.html:230 +#: stock/models.py:370 stock/templates/stock/item_base.html:237 msgid "External Link" msgstr "" -#: build/models.py:156 stock/models.py:370 +#: build/models.py:156 stock/models.py:372 msgid "Link to external URL" msgstr "" -#: build/models.py:160 build/templates/build/tabs.html:14 company/models.py:307 +#: build/models.py:160 build/templates/build/tabs.html:14 company/models.py:310 #: company/templates/company/tabs.html:33 order/templates/order/po_tabs.html:15 #: order/templates/order/purchase_order_detail.html:200 #: order/templates/order/so_tabs.html:23 part/templates/part/tabs.html:64 -#: stock/models.py:436 stock/models.py:1265 stock/templates/stock/tabs.html:26 +#: stock/models.py:438 stock/models.py:1287 stock/templates/stock/tabs.html:26 #: templates/js/barcode.html:391 templates/js/bom.html:229 -#: templates/js/stock.html:113 templates/js/stock.html:513 +#: templates/js/stock.html:114 templates/js/stock.html:526 msgid "Notes" msgstr "" @@ -387,15 +378,15 @@ msgstr "" msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:512 +#: build/models.py:511 msgid "Build to allocate parts" msgstr "" -#: build/models.py:519 +#: build/models.py:518 msgid "Stock Item to allocate to build" msgstr "" -#: build/models.py:532 +#: build/models.py:531 msgid "Stock quantity to allocate to build" msgstr "" @@ -422,8 +413,8 @@ msgstr "" #: build/templates/build/allocate.html:161 #: order/templates/order/sales_order_detail.html:68 -#: order/templates/order/sales_order_detail.html:150 stock/models.py:362 -#: stock/templates/stock/item_base.html:146 +#: order/templates/order/sales_order_detail.html:150 stock/models.py:364 +#: stock/templates/stock/item_base.html:153 msgid "Serial Number" msgstr "" @@ -440,18 +431,18 @@ msgstr "" #: part/templates/part/allocation.html:49 #: stock/templates/stock/item_base.html:26 #: stock/templates/stock/item_base.html:32 -#: stock/templates/stock/item_base.html:152 +#: stock/templates/stock/item_base.html:159 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.html:338 #: templates/js/bom.html:172 templates/js/build.html:52 -#: templates/js/stock.html:660 +#: templates/js/stock.html:673 msgid "Quantity" msgstr "" #: build/templates/build/allocate.html:177 #: build/templates/build/auto_allocate.html:20 -#: stock/templates/stock/item_base.html:184 +#: stock/templates/stock/item_base.html:191 #: stock/templates/stock/stock_adjust.html:17 templates/js/barcode.html:337 -#: templates/js/stock.html:495 +#: templates/js/stock.html:508 msgid "Location" msgstr "" @@ -477,7 +468,7 @@ msgstr "" #: templates/js/bom.html:157 templates/js/company.html:60 #: templates/js/order.html:157 templates/js/order.html:230 #: templates/js/part.html:176 templates/js/part.html:355 -#: templates/js/stock.html:445 templates/js/stock.html:641 +#: templates/js/stock.html:440 templates/js/stock.html:654 msgid "Description" msgstr "" @@ -487,8 +478,8 @@ msgstr "" msgid "Reference" msgstr "" -#: build/templates/build/allocate.html:338 part/models.py:1269 -#: templates/js/part.html:359 templates/js/table_filters.html:90 +#: build/templates/build/allocate.html:338 part/models.py:1270 +#: templates/js/part.html:359 templates/js/table_filters.html:100 msgid "Required" msgstr "" @@ -531,7 +522,7 @@ msgstr "" #: build/templates/build/build_base.html:8 #: build/templates/build/build_base.html:34 #: build/templates/build/complete.html:6 -#: stock/templates/stock/item_base.html:209 templates/js/build.html:33 +#: stock/templates/stock/item_base.html:216 templates/js/build.html:33 #: templates/navbar.html:12 msgid "Build" msgstr "" @@ -551,9 +542,9 @@ msgstr "" #: build/templates/build/build_base.html:80 #: build/templates/build/detail.html:42 #: order/templates/order/receive_parts.html:24 -#: stock/templates/stock/item_base.html:262 templates/js/barcode.html:42 +#: stock/templates/stock/item_base.html:269 templates/js/barcode.html:42 #: templates/js/build.html:57 templates/js/order.html:162 -#: templates/js/order.html:235 templates/js/stock.html:482 +#: templates/js/order.html:235 templates/js/stock.html:495 msgid "Status" msgstr "" @@ -563,7 +554,7 @@ msgstr "" #: order/templates/order/sales_order_notes.html:10 #: order/templates/order/sales_order_ship.html:25 #: part/templates/part/allocation.html:27 -#: stock/templates/stock/item_base.html:172 templates/js/order.html:209 +#: stock/templates/stock/item_base.html:179 templates/js/order.html:209 msgid "Sales Order" msgstr "" @@ -630,7 +621,7 @@ msgid "Stock can be taken from any available location." msgstr "" #: build/templates/build/detail.html:48 -#: stock/templates/stock/item_base.html:202 templates/js/stock.html:490 +#: stock/templates/stock/item_base.html:209 templates/js/stock.html:503 msgid "Batch" msgstr "" @@ -733,7 +724,7 @@ msgstr "" msgid "Confirm unallocation of build stock" msgstr "" -#: build/views.py:162 stock/views.py:286 +#: build/views.py:162 stock/views.py:404 msgid "Check the confirmation box" msgstr "" @@ -741,7 +732,7 @@ msgstr "" msgid "Complete Build" msgstr "" -#: build/views.py:201 stock/views.py:1118 stock/views.py:1232 +#: build/views.py:201 stock/views.py:1236 stock/views.py:1350 msgid "Next available serial number is" msgstr "" @@ -757,7 +748,7 @@ msgstr "" msgid "Invalid location selected" msgstr "" -#: build/views.py:300 stock/views.py:1268 +#: build/views.py:300 stock/views.py:1386 #, python-brace-format msgid "The following serial numbers already exist: ({sn})" msgstr "" @@ -850,113 +841,113 @@ msgstr "" msgid "Delete Currency" msgstr "" -#: company/models.py:83 company/models.py:84 +#: company/models.py:86 company/models.py:87 msgid "Company name" msgstr "" -#: company/models.py:86 +#: company/models.py:89 msgid "Company description" msgstr "" -#: company/models.py:86 +#: company/models.py:89 msgid "Description of the company" msgstr "" -#: company/models.py:88 company/templates/company/company_base.html:48 +#: company/models.py:91 company/templates/company/company_base.html:48 #: templates/js/company.html:65 msgid "Website" msgstr "" -#: company/models.py:88 +#: company/models.py:91 msgid "Company website URL" msgstr "" -#: company/models.py:91 company/templates/company/company_base.html:55 +#: company/models.py:94 company/templates/company/company_base.html:55 msgid "Address" msgstr "" -#: company/models.py:92 +#: company/models.py:95 msgid "Company address" msgstr "" -#: company/models.py:95 +#: company/models.py:98 msgid "Phone number" msgstr "" -#: company/models.py:96 +#: company/models.py:99 msgid "Contact phone number" msgstr "" -#: company/models.py:98 company/templates/company/company_base.html:69 +#: company/models.py:101 company/templates/company/company_base.html:69 msgid "Email" msgstr "" -#: company/models.py:98 +#: company/models.py:101 msgid "Contact email address" msgstr "" -#: company/models.py:101 company/templates/company/company_base.html:76 +#: company/models.py:104 company/templates/company/company_base.html:76 msgid "Contact" msgstr "" -#: company/models.py:102 +#: company/models.py:105 msgid "Point of contact" msgstr "" -#: company/models.py:104 +#: company/models.py:107 msgid "Link to external company information" msgstr "" -#: company/models.py:116 +#: company/models.py:119 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:118 +#: company/models.py:121 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:120 +#: company/models.py:123 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:276 stock/models.py:322 -#: stock/templates/stock/item_base.html:138 +#: company/models.py:279 stock/models.py:324 +#: stock/templates/stock/item_base.html:145 msgid "Base Part" msgstr "" -#: company/models.py:281 +#: company/models.py:284 msgid "Select part" msgstr "" -#: company/models.py:287 +#: company/models.py:290 msgid "Select supplier" msgstr "" -#: company/models.py:290 +#: company/models.py:293 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:297 +#: company/models.py:300 msgid "Select manufacturer" msgstr "" -#: company/models.py:301 +#: company/models.py:304 msgid "Manufacturer part number" msgstr "" -#: company/models.py:303 +#: company/models.py:306 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:305 +#: company/models.py:308 msgid "Supplier part description" msgstr "" -#: company/models.py:309 +#: company/models.py:312 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:311 +#: company/models.py:314 msgid "Part packaging" msgstr "" @@ -991,14 +982,14 @@ msgstr "" #: company/templates/company/supplier_part_detail.html:21 order/models.py:148 #: order/templates/order/order_base.html:74 #: order/templates/order/order_wizard/select_pos.html:30 -#: stock/templates/stock/item_base.html:237 templates/js/company.html:52 +#: stock/templates/stock/item_base.html:244 templates/js/company.html:52 #: templates/js/company.html:134 templates/js/order.html:144 msgid "Supplier" msgstr "" #: company/templates/company/detail.html:26 order/models.py:314 -#: order/templates/order/sales_order_base.html:73 stock/models.py:357 -#: stock/models.py:358 stock/templates/stock/item_base.html:159 +#: order/templates/order/sales_order_base.html:73 stock/models.py:359 +#: stock/models.py:360 stock/templates/stock/item_base.html:166 #: templates/js/company.html:44 templates/js/order.html:217 msgid "Customer" msgstr "" @@ -1053,7 +1044,7 @@ msgstr "" msgid "Supplier Stock" msgstr "" -#: company/templates/company/detail_stock.html:34 +#: company/templates/company/detail_stock.html:35 #: company/templates/company/supplier_part_stock.html:33 #: part/templates/part/stock.html:53 templates/stock_table.html:5 msgid "Export" @@ -1111,8 +1102,8 @@ msgid "New Sales Order" msgstr "" #: company/templates/company/supplier_part_base.html:6 -#: company/templates/company/supplier_part_base.html:19 stock/models.py:331 -#: stock/templates/stock/item_base.html:242 templates/js/company.html:150 +#: company/templates/company/supplier_part_base.html:19 stock/models.py:333 +#: stock/templates/stock/item_base.html:249 templates/js/company.html:150 msgid "Supplier Part" msgstr "" @@ -1211,7 +1202,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:203 -#: templates/js/stock.html:453 templates/navbar.html:11 +#: templates/js/stock.html:448 templates/navbar.html:11 msgid "Stock" msgstr "" @@ -1311,6 +1302,22 @@ msgstr "" msgid "Delete Price Break" msgstr "" +#: label/models.py:55 +msgid "Label name" +msgstr "" + +#: label/models.py:58 +msgid "Label description" +msgstr "" + +#: label/models.py:63 +msgid "Label template file" +msgstr "" + +#: label/models.py:69 +msgid "Query filters (comma-separated list of key=value pairs" +msgstr "" + #: order/forms.py:24 msgid "Place order" msgstr "" @@ -1361,7 +1368,7 @@ msgid "Supplier order reference code" msgstr "" #: order/models.py:185 order/models.py:259 part/views.py:1167 -#: stock/models.py:243 stock/models.py:665 stock/views.py:1243 +#: stock/models.py:238 stock/models.py:687 msgid "Quantity must be greater than zero" msgstr "" @@ -1395,7 +1402,7 @@ msgstr "" #: order/models.py:466 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:23 -#: stock/templates/stock/item_base.html:216 templates/js/order.html:136 +#: stock/templates/stock/item_base.html:223 templates/js/order.html:136 msgid "Purchase Order" msgstr "" @@ -1672,7 +1679,7 @@ msgstr "" msgid "Add Purchase Order Attachment" msgstr "" -#: order/views.py:102 order/views.py:149 part/views.py:85 stock/views.py:166 +#: order/views.py:102 order/views.py:149 part/views.py:85 stock/views.py:167 msgid "Added attachment" msgstr "" @@ -1692,7 +1699,7 @@ msgstr "" msgid "Delete Attachment" msgstr "" -#: order/views.py:222 order/views.py:236 stock/views.py:222 +#: order/views.py:222 order/views.py:236 stock/views.py:223 msgid "Deleted attachment" msgstr "" @@ -1825,11 +1832,11 @@ msgstr "" msgid "Error reading BOM file (incorrect row size)" msgstr "" -#: part/forms.py:55 stock/forms.py:200 +#: part/forms.py:55 stock/forms.py:243 msgid "File Format" msgstr "" -#: part/forms.py:55 stock/forms.py:200 +#: part/forms.py:55 stock/forms.py:243 msgid "Select output file format" msgstr "" @@ -1877,207 +1884,220 @@ msgstr "" msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:427 +#: part/models.py:74 part/templates/part/part_app_base.html:9 +msgid "Part Category" +msgstr "" + +#: part/models.py:75 part/templates/part/category.html:13 +#: part/templates/part/category.html:78 templates/stats.html:12 +msgid "Part Categories" +msgstr "" + +#: part/models.py:428 msgid "Part must be unique for name, IPN and revision" msgstr "" -#: part/models.py:442 part/templates/part/detail.html:19 +#: part/models.py:443 part/templates/part/detail.html:19 msgid "Part name" msgstr "" -#: part/models.py:446 +#: part/models.py:447 msgid "Is this part a template part?" msgstr "" -#: part/models.py:455 +#: part/models.py:456 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:457 +#: part/models.py:458 msgid "Part description" msgstr "" -#: part/models.py:459 +#: part/models.py:460 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:464 +#: part/models.py:465 msgid "Part category" msgstr "" -#: part/models.py:466 +#: part/models.py:467 msgid "Internal Part Number" msgstr "" -#: part/models.py:468 +#: part/models.py:469 msgid "Part revision or version number" msgstr "" -#: part/models.py:470 +#: part/models.py:471 msgid "Link to extenal URL" msgstr "" -#: part/models.py:482 +#: part/models.py:483 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:526 +#: part/models.py:527 msgid "Default supplier part" msgstr "" -#: part/models.py:529 +#: part/models.py:530 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:531 +#: part/models.py:532 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:533 +#: part/models.py:534 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:535 +#: part/models.py:536 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:537 +#: part/models.py:538 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:539 +#: part/models.py:540 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:541 +#: part/models.py:542 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:543 +#: part/models.py:544 msgid "Is this part active?" msgstr "" -#: part/models.py:545 +#: part/models.py:546 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:547 +#: part/models.py:548 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:549 +#: part/models.py:550 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1221 +#: part/models.py:1222 msgid "Test templates can only be created for trackable parts" msgstr "" -#: part/models.py:1238 +#: part/models.py:1239 msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:1257 templates/js/part.html:350 templates/js/stock.html:89 +#: part/models.py:1258 templates/js/part.html:350 templates/js/stock.html:90 msgid "Test Name" msgstr "" -#: part/models.py:1258 +#: part/models.py:1259 msgid "Enter a name for the test" msgstr "" -#: part/models.py:1263 +#: part/models.py:1264 msgid "Test Description" msgstr "" -#: part/models.py:1264 +#: part/models.py:1265 msgid "Enter description for this test" msgstr "" -#: part/models.py:1270 +#: part/models.py:1271 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:1275 templates/js/part.html:367 +#: part/models.py:1276 templates/js/part.html:367 msgid "Requires Value" msgstr "" -#: part/models.py:1276 +#: part/models.py:1277 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:1281 templates/js/part.html:374 +#: part/models.py:1282 templates/js/part.html:374 msgid "Requires Attachment" msgstr "" -#: part/models.py:1282 +#: part/models.py:1283 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:1315 +#: part/models.py:1316 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:1320 +#: part/models.py:1321 msgid "Parameter Name" msgstr "" -#: part/models.py:1322 +#: part/models.py:1323 msgid "Parameter Units" msgstr "" -#: part/models.py:1348 +#: part/models.py:1349 msgid "Parent Part" msgstr "" -#: part/models.py:1350 +#: part/models.py:1351 msgid "Parameter Template" msgstr "" -#: part/models.py:1352 +#: part/models.py:1353 msgid "Parameter Value" msgstr "" -#: part/models.py:1381 +#: part/models.py:1382 msgid "Select parent part" msgstr "" -#: part/models.py:1389 +#: part/models.py:1390 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:1395 +#: part/models.py:1396 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:1398 +#: part/models.py:1399 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:1401 +#: part/models.py:1402 msgid "BOM item reference" msgstr "" -#: part/models.py:1404 +#: part/models.py:1405 msgid "BOM item notes" msgstr "" -#: part/models.py:1406 +#: part/models.py:1407 msgid "BOM line checksum" msgstr "" -#: part/models.py:1470 stock/models.py:233 +#: part/models.py:1471 stock/models.py:228 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:1479 +#: part/models.py:1480 msgid "Part cannot be added to its own Bill of Materials" msgstr "" -#: part/models.py:1486 +#: part/models.py:1487 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" +#: part/models.py:1494 +msgid "BOM Item" +msgstr "" + #: part/templates/part/allocation.html:10 msgid "Part Stock Allocations" msgstr "" @@ -2093,14 +2113,14 @@ msgstr "" #: part/templates/part/allocation.html:45 #: stock/templates/stock/item_base.html:8 #: stock/templates/stock/item_base.html:58 -#: stock/templates/stock/item_base.html:224 +#: stock/templates/stock/item_base.html:231 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.html:106 -#: templates/js/stock.html:630 +#: templates/js/stock.html:643 msgid "Stock Item" msgstr "" #: part/templates/part/allocation.html:20 -#: stock/templates/stock/item_base.html:178 +#: stock/templates/stock/item_base.html:185 msgid "Build Order" msgstr "" @@ -2140,11 +2160,6 @@ msgstr "" msgid "Export Bill of Materials" msgstr "" -#: part/templates/part/category.html:13 part/templates/part/category.html:78 -#: templates/stats.html:12 -msgid "Part Categories" -msgstr "" - #: part/templates/part/category.html:14 msgid "All parts" msgstr "" @@ -2238,8 +2253,8 @@ msgstr "" msgid "Part is not a virtual part" msgstr "" -#: part/templates/part/detail.html:139 stock/forms.py:194 -#: templates/js/table_filters.html:149 +#: part/templates/part/detail.html:139 stock/forms.py:237 +#: templates/js/table_filters.html:159 msgid "Template" msgstr "" @@ -2251,7 +2266,7 @@ msgstr "" msgid "Part is not a template part" msgstr "" -#: part/templates/part/detail.html:148 templates/js/table_filters.html:161 +#: part/templates/part/detail.html:148 templates/js/table_filters.html:171 msgid "Assembly" msgstr "" @@ -2263,7 +2278,7 @@ msgstr "" msgid "Part cannot be assembled from other parts" msgstr "" -#: part/templates/part/detail.html:157 templates/js/table_filters.html:165 +#: part/templates/part/detail.html:157 templates/js/table_filters.html:175 msgid "Component" msgstr "" @@ -2275,7 +2290,7 @@ msgstr "" msgid "Part cannot be used in assemblies" msgstr "" -#: part/templates/part/detail.html:166 templates/js/table_filters.html:177 +#: part/templates/part/detail.html:166 templates/js/table_filters.html:187 msgid "Trackable" msgstr "" @@ -2295,7 +2310,7 @@ msgstr "" msgid "Part can be purchased from external suppliers" msgstr "" -#: part/templates/part/detail.html:184 templates/js/table_filters.html:173 +#: part/templates/part/detail.html:184 templates/js/table_filters.html:183 msgid "Salable" msgstr "" @@ -2307,7 +2322,7 @@ msgstr "" msgid "Part cannot be sold to customers" msgstr "" -#: part/templates/part/detail.html:193 templates/js/table_filters.html:144 +#: part/templates/part/detail.html:193 templates/js/table_filters.html:154 msgid "Active" msgstr "" @@ -2339,8 +2354,8 @@ msgstr "" msgid "New Parameter" msgstr "" -#: part/templates/part/params.html:21 stock/models.py:1252 -#: templates/js/stock.html:109 +#: part/templates/part/params.html:21 stock/models.py:1274 +#: templates/js/stock.html:110 msgid "Value" msgstr "" @@ -2352,10 +2367,6 @@ msgstr "" msgid "Delete" msgstr "" -#: part/templates/part/part_app_base.html:9 -msgid "Part Category" -msgstr "" - #: part/templates/part/part_app_base.html:11 msgid "Part List" msgstr "" @@ -2423,7 +2434,7 @@ msgstr "" msgid "Available Stock" msgstr "" -#: part/templates/part/part_base.html:108 templates/js/table_filters.html:37 +#: part/templates/part/part_base.html:108 templates/js/table_filters.html:57 msgid "In Stock" msgstr "" @@ -2524,7 +2535,7 @@ msgstr "" msgid "Used In" msgstr "" -#: part/templates/part/tabs.html:55 stock/templates/stock/item_base.html:268 +#: part/templates/part/tabs.html:55 stock/templates/stock/item_base.html:275 msgid "Tests" msgstr "" @@ -2741,215 +2752,227 @@ msgstr "" msgid "Asset file description" msgstr "" -#: stock/forms.py:194 +#: stock/forms.py:185 +msgid "Label" +msgstr "" + +#: stock/forms.py:186 stock/forms.py:237 msgid "Select test report template" msgstr "" -#: stock/forms.py:202 +#: stock/forms.py:245 msgid "Include stock items in sub locations" msgstr "" -#: stock/forms.py:235 +#: stock/forms.py:278 msgid "Destination stock location" msgstr "" -#: stock/forms.py:241 +#: stock/forms.py:284 msgid "Confirm movement of stock items" msgstr "" -#: stock/forms.py:243 +#: stock/forms.py:286 msgid "Set the destination as the default location for selected parts" msgstr "" -#: stock/models.py:208 +#: stock/models.py:209 msgid "StockItem with this serial number already exists" msgstr "" -#: stock/models.py:250 +#: stock/models.py:245 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "" -#: stock/models.py:260 stock/models.py:269 +#: stock/models.py:255 stock/models.py:264 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:261 +#: stock/models.py:256 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:282 +#: stock/models.py:277 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:314 +#: stock/models.py:316 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:323 +#: stock/models.py:325 msgid "Base part" msgstr "" -#: stock/models.py:332 +#: stock/models.py:334 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:337 stock/templates/stock/stock_app_base.html:7 +#: stock/models.py:339 stock/templates/stock/stock_app_base.html:7 msgid "Stock Location" msgstr "" -#: stock/models.py:340 +#: stock/models.py:342 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:345 +#: stock/models.py:347 msgid "Installed In" msgstr "" -#: stock/models.py:348 +#: stock/models.py:350 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:364 +#: stock/models.py:366 msgid "Serial number for this item" msgstr "" -#: stock/models.py:376 +#: stock/models.py:378 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:380 +#: stock/models.py:382 msgid "Stock Quantity" msgstr "" -#: stock/models.py:389 +#: stock/models.py:391 msgid "Source Build" msgstr "" -#: stock/models.py:391 +#: stock/models.py:393 msgid "Build for this stock item" msgstr "" -#: stock/models.py:398 +#: stock/models.py:400 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:401 +#: stock/models.py:403 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:407 +#: stock/models.py:409 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:414 +#: stock/models.py:416 msgid "Destination Build Order" msgstr "" -#: stock/models.py:427 +#: stock/models.py:429 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:437 stock/templates/stock/item_notes.html:14 +#: stock/models.py:439 stock/templates/stock/item_notes.html:14 #: stock/templates/stock/item_notes.html:30 msgid "Stock Item Notes" msgstr "" -#: stock/models.py:489 +#: stock/models.py:490 msgid "Assigned to Customer" msgstr "" -#: stock/models.py:491 +#: stock/models.py:492 msgid "Manually assigned to customer" msgstr "" -#: stock/models.py:656 +#: stock/models.py:505 +msgid "Returned from customer" +msgstr "" + +#: stock/models.py:507 +msgid "Returned to location" +msgstr "" + +#: stock/models.py:678 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:662 +#: stock/models.py:684 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:668 +#: stock/models.py:690 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "" -#: stock/models.py:671 stock/models.py:674 +#: stock/models.py:693 stock/models.py:696 msgid "Serial numbers must be a list of integers" msgstr "" -#: stock/models.py:677 +#: stock/models.py:699 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:687 +#: stock/models.py:709 msgid "Serial numbers already exist: " msgstr "" -#: stock/models.py:712 +#: stock/models.py:734 msgid "Add serial number" msgstr "" -#: stock/models.py:715 +#: stock/models.py:737 #, python-brace-format msgid "Serialized {n} items" msgstr "" -#: stock/models.py:826 +#: stock/models.py:848 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1175 msgid "Tracking entry title" msgstr "" -#: stock/models.py:1155 +#: stock/models.py:1177 msgid "Entry notes" msgstr "" -#: stock/models.py:1157 +#: stock/models.py:1179 msgid "Link to external page for further information" msgstr "" -#: stock/models.py:1217 +#: stock/models.py:1239 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:1223 +#: stock/models.py:1245 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:1240 +#: stock/models.py:1262 msgid "Test" msgstr "" -#: stock/models.py:1241 +#: stock/models.py:1263 msgid "Test name" msgstr "" -#: stock/models.py:1246 +#: stock/models.py:1268 msgid "Result" msgstr "" -#: stock/models.py:1247 templates/js/table_filters.html:80 +#: stock/models.py:1269 templates/js/table_filters.html:90 msgid "Test result" msgstr "" -#: stock/models.py:1253 +#: stock/models.py:1275 msgid "Test output value" msgstr "" -#: stock/models.py:1259 +#: stock/models.py:1281 msgid "Attachment" msgstr "" -#: stock/models.py:1260 +#: stock/models.py:1282 msgid "Test result attachment" msgstr "" -#: stock/models.py:1266 +#: stock/models.py:1288 msgid "Test notes" msgstr "" @@ -2997,7 +3020,7 @@ msgstr "" msgid "Link Barcode" msgstr "" -#: stock/templates/stock/item_base.html:92 +#: stock/templates/stock/item_base.html:91 msgid "Stock adjustment actions" msgstr "" @@ -3018,68 +3041,76 @@ msgstr "" msgid "Transfer stock" msgstr "" +#: stock/templates/stock/item_base.html:101 +msgid "Serialize stock" +msgstr "" + #: stock/templates/stock/item_base.html:105 +msgid "Assign to customer" +msgstr "" + +#: stock/templates/stock/item_base.html:108 +msgid "Return to stock" +msgstr "" + +#: stock/templates/stock/item_base.html:114 #: stock/templates/stock/location.html:30 msgid "Stock actions" msgstr "" -#: stock/templates/stock/item_base.html:108 -msgid "Serialize stock" -msgstr "" - -#: stock/templates/stock/item_base.html:111 -msgid "Assign to customer" -msgstr "" - -#: stock/templates/stock/item_base.html:114 +#: stock/templates/stock/item_base.html:118 msgid "Convert to variant" msgstr "" -#: stock/templates/stock/item_base.html:116 +#: stock/templates/stock/item_base.html:120 msgid "Duplicate stock item" msgstr "" -#: stock/templates/stock/item_base.html:117 +#: stock/templates/stock/item_base.html:121 msgid "Edit stock item" msgstr "" -#: stock/templates/stock/item_base.html:119 +#: stock/templates/stock/item_base.html:123 msgid "Delete stock item" msgstr "" -#: stock/templates/stock/item_base.html:124 +#: stock/templates/stock/item_base.html:128 msgid "Generate test report" msgstr "" -#: stock/templates/stock/item_base.html:133 +#: stock/templates/stock/item_base.html:132 +msgid "Print labels" +msgstr "" + +#: stock/templates/stock/item_base.html:140 msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:166 +#: stock/templates/stock/item_base.html:173 msgid "Belongs To" msgstr "" -#: stock/templates/stock/item_base.html:188 +#: stock/templates/stock/item_base.html:195 msgid "No location set" msgstr "" -#: stock/templates/stock/item_base.html:195 +#: stock/templates/stock/item_base.html:202 msgid "Unique Identifier" msgstr "" -#: stock/templates/stock/item_base.html:223 +#: stock/templates/stock/item_base.html:230 msgid "Parent Item" msgstr "" -#: stock/templates/stock/item_base.html:248 +#: stock/templates/stock/item_base.html:255 msgid "Last Updated" msgstr "" -#: stock/templates/stock/item_base.html:253 +#: stock/templates/stock/item_base.html:260 msgid "Last Stocktake" msgstr "" -#: stock/templates/stock/item_base.html:257 +#: stock/templates/stock/item_base.html:264 msgid "No stocktake performed" msgstr "" @@ -3166,7 +3197,11 @@ msgstr "" msgid "Are you sure you want to delete this stock location?" msgstr "" -#: stock/templates/stock/stockitem_convert.html:7 stock/views.py:934 +#: stock/templates/stock/stock_adjust.html:35 +msgid "Stock item is serialized and quantity cannot be adjusted" +msgstr "" + +#: stock/templates/stock/stockitem_convert.html:7 stock/views.py:1052 msgid "Convert Stock Item" msgstr "" @@ -3194,190 +3229,214 @@ msgstr "" msgid "Children" msgstr "" -#: stock/views.py:113 +#: stock/views.py:114 msgid "Edit Stock Location" msgstr "" -#: stock/views.py:137 +#: stock/views.py:138 msgid "Stock Location QR code" msgstr "" -#: stock/views.py:155 +#: stock/views.py:156 msgid "Add Stock Item Attachment" msgstr "" -#: stock/views.py:200 +#: stock/views.py:201 msgid "Edit Stock Item Attachment" msgstr "" -#: stock/views.py:216 +#: stock/views.py:217 msgid "Delete Stock Item Attachment" msgstr "" -#: stock/views.py:232 +#: stock/views.py:233 msgid "Assign to Customer" msgstr "" #: stock/views.py:270 -msgid "Delete All Test Data" +msgid "Return to Stock" msgstr "" -#: stock/views.py:285 -msgid "Confirm test data deletion" +#: stock/views.py:289 +msgid "Specify a valid location" +msgstr "" + +#: stock/views.py:293 +msgid "Stock item returned from customer" msgstr "" #: stock/views.py:305 +msgid "Select Label Template" +msgstr "" + +#: stock/views.py:326 +msgid "Select valid label" +msgstr "" + +#: stock/views.py:388 +msgid "Delete All Test Data" +msgstr "" + +#: stock/views.py:403 +msgid "Confirm test data deletion" +msgstr "" + +#: stock/views.py:423 msgid "Add Test Result" msgstr "" -#: stock/views.py:342 +#: stock/views.py:460 msgid "Edit Test Result" msgstr "" -#: stock/views.py:359 +#: stock/views.py:477 msgid "Delete Test Result" msgstr "" -#: stock/views.py:370 +#: stock/views.py:488 msgid "Select Test Report Template" msgstr "" -#: stock/views.py:384 +#: stock/views.py:502 msgid "Select valid template" msgstr "" -#: stock/views.py:436 +#: stock/views.py:554 msgid "Stock Export Options" msgstr "" -#: stock/views.py:556 +#: stock/views.py:674 msgid "Stock Item QR Code" msgstr "" -#: stock/views.py:579 +#: stock/views.py:697 msgid "Adjust Stock" msgstr "" -#: stock/views.py:688 +#: stock/views.py:806 msgid "Move Stock Items" msgstr "" -#: stock/views.py:689 +#: stock/views.py:807 msgid "Count Stock Items" msgstr "" -#: stock/views.py:690 +#: stock/views.py:808 msgid "Remove From Stock" msgstr "" -#: stock/views.py:691 +#: stock/views.py:809 msgid "Add Stock Items" msgstr "" -#: stock/views.py:692 +#: stock/views.py:810 msgid "Delete Stock Items" msgstr "" -#: stock/views.py:720 +#: stock/views.py:838 msgid "Must enter integer value" msgstr "" -#: stock/views.py:725 +#: stock/views.py:843 msgid "Quantity must be positive" msgstr "" -#: stock/views.py:732 +#: stock/views.py:850 #, python-brace-format msgid "Quantity must not exceed {x}" msgstr "" -#: stock/views.py:740 +#: stock/views.py:858 msgid "Confirm stock adjustment" msgstr "" -#: stock/views.py:811 +#: stock/views.py:929 #, python-brace-format msgid "Added stock to {n} items" msgstr "" -#: stock/views.py:826 +#: stock/views.py:944 #, python-brace-format msgid "Removed stock from {n} items" msgstr "" -#: stock/views.py:839 +#: stock/views.py:957 #, python-brace-format msgid "Counted stock for {n} items" msgstr "" -#: stock/views.py:867 +#: stock/views.py:985 msgid "No items were moved" msgstr "" -#: stock/views.py:870 +#: stock/views.py:988 #, python-brace-format msgid "Moved {n} items to {dest}" msgstr "" -#: stock/views.py:889 +#: stock/views.py:1007 #, python-brace-format msgid "Deleted {n} stock items" msgstr "" -#: stock/views.py:901 +#: stock/views.py:1019 msgid "Edit Stock Item" msgstr "" -#: stock/views.py:961 +#: stock/views.py:1079 msgid "Create new Stock Location" msgstr "" -#: stock/views.py:982 +#: stock/views.py:1100 msgid "Serialize Stock" msgstr "" -#: stock/views.py:1074 +#: stock/views.py:1192 msgid "Create new Stock Item" msgstr "" -#: stock/views.py:1167 +#: stock/views.py:1285 msgid "Duplicate Stock Item" msgstr "" -#: stock/views.py:1240 +#: stock/views.py:1358 msgid "Invalid quantity" msgstr "" -#: stock/views.py:1247 +#: stock/views.py:1361 +msgid "Quantity cannot be less than zero" +msgstr "" + +#: stock/views.py:1365 msgid "Invalid part selection" msgstr "" -#: stock/views.py:1296 +#: stock/views.py:1414 #, python-brace-format msgid "Created {n} new stock items" msgstr "" -#: stock/views.py:1315 stock/views.py:1331 +#: stock/views.py:1433 stock/views.py:1449 msgid "Created new stock item" msgstr "" -#: stock/views.py:1350 +#: stock/views.py:1468 msgid "Delete Stock Location" msgstr "" -#: stock/views.py:1363 +#: stock/views.py:1481 msgid "Delete Stock Item" msgstr "" -#: stock/views.py:1374 +#: stock/views.py:1492 msgid "Delete Stock Tracking Entry" msgstr "" -#: stock/views.py:1391 +#: stock/views.py:1509 msgid "Edit Stock Tracking Entry" msgstr "" -#: stock/views.py:1400 +#: stock/views.py:1518 msgid "Add Stock Tracking Entry" msgstr "" @@ -3602,7 +3661,7 @@ msgstr "" msgid "No purchase orders found" msgstr "" -#: templates/js/order.html:170 templates/js/stock.html:612 +#: templates/js/order.html:170 templates/js/stock.html:625 msgid "Date" msgstr "" @@ -3614,7 +3673,7 @@ msgstr "" msgid "Shipment Date" msgstr "" -#: templates/js/part.html:106 templates/js/stock.html:405 +#: templates/js/part.html:106 templates/js/stock.html:406 msgid "Select" msgstr "" @@ -3630,7 +3689,7 @@ msgstr "" msgid "No category" msgstr "" -#: templates/js/part.html:214 templates/js/table_filters.html:157 +#: templates/js/part.html:214 templates/js/table_filters.html:167 msgid "Low stock" msgstr "" @@ -3654,11 +3713,11 @@ msgstr "" msgid "No test templates matching query" msgstr "" -#: templates/js/part.html:387 templates/js/stock.html:62 +#: templates/js/part.html:387 templates/js/stock.html:63 msgid "Edit test result" msgstr "" -#: templates/js/part.html:388 templates/js/stock.html:63 +#: templates/js/part.html:388 templates/js/stock.html:64 msgid "Delete test result" msgstr "" @@ -3666,143 +3725,175 @@ msgstr "" msgid "This test is defined for a parent part" msgstr "" -#: templates/js/stock.html:25 +#: templates/js/stock.html:26 msgid "PASS" msgstr "" -#: templates/js/stock.html:27 +#: templates/js/stock.html:28 msgid "FAIL" msgstr "" -#: templates/js/stock.html:32 +#: templates/js/stock.html:33 msgid "NO RESULT" msgstr "" -#: templates/js/stock.html:58 +#: templates/js/stock.html:59 msgid "Add test result" msgstr "" -#: templates/js/stock.html:76 +#: templates/js/stock.html:77 msgid "No test results found" msgstr "" -#: templates/js/stock.html:117 +#: templates/js/stock.html:118 msgid "Test Date" msgstr "" -#: templates/js/stock.html:260 +#: templates/js/stock.html:261 msgid "No stock items matching query" msgstr "" -#: templates/js/stock.html:357 templates/js/stock.html:372 +#: templates/js/stock.html:358 templates/js/stock.html:373 msgid "Undefined location" msgstr "" -#: templates/js/stock.html:469 -msgid "StockItem has been allocated" +#: templates/js/stock.html:464 +msgid "Stock item has been allocated" msgstr "" -#: templates/js/stock.html:474 -msgid "StockItem is lost" +#: templates/js/stock.html:468 +msgid "Stock item has been assigned to customer" msgstr "" -#: templates/js/stock.html:503 +#: templates/js/stock.html:470 +msgid "Stock item was assigned to a build order" +msgstr "" + +#: templates/js/stock.html:472 +msgid "Stock item was assigned to a sales order" +msgstr "" + +#: templates/js/stock.html:479 +msgid "Stock item has been rejected" +msgstr "" + +#: templates/js/stock.html:483 +msgid "Stock item is lost" +msgstr "" + +#: templates/js/stock.html:487 templates/js/table_filters.html:52 +msgid "Depleted" +msgstr "" + +#: templates/js/stock.html:516 msgid "Shipped to customer" msgstr "" -#: templates/js/stock.html:506 +#: templates/js/stock.html:519 msgid "No stock location set" msgstr "" -#: templates/js/stock.html:678 +#: templates/js/stock.html:691 msgid "No user information" msgstr "" -#: templates/js/table_filters.html:19 templates/js/table_filters.html:62 +#: templates/js/table_filters.html:19 templates/js/table_filters.html:67 msgid "Is Serialized" msgstr "" -#: templates/js/table_filters.html:22 templates/js/table_filters.html:65 +#: templates/js/table_filters.html:22 templates/js/table_filters.html:70 msgid "Serial number GTE" msgstr "" -#: templates/js/table_filters.html:23 templates/js/table_filters.html:66 +#: templates/js/table_filters.html:23 templates/js/table_filters.html:71 msgid "Serial number greater than or equal to" msgstr "" -#: templates/js/table_filters.html:26 templates/js/table_filters.html:69 +#: templates/js/table_filters.html:26 templates/js/table_filters.html:74 msgid "Serial number LTE" msgstr "" -#: templates/js/table_filters.html:27 templates/js/table_filters.html:70 +#: templates/js/table_filters.html:27 templates/js/table_filters.html:75 msgid "Serial number less than or equal to" msgstr "" -#: templates/js/table_filters.html:38 -msgid "Show items which are in stock" -msgstr "" - -#: templates/js/table_filters.html:42 -msgid "Include sublocations" -msgstr "" - -#: templates/js/table_filters.html:43 -msgid "Include stock in sublocations" -msgstr "" - -#: templates/js/table_filters.html:47 +#: templates/js/table_filters.html:37 msgid "Active parts" msgstr "" -#: templates/js/table_filters.html:48 +#: templates/js/table_filters.html:38 msgid "Show stock for active parts" msgstr "" -#: templates/js/table_filters.html:52 templates/js/table_filters.html:53 -msgid "Stock status" -msgstr "" - -#: templates/js/table_filters.html:57 +#: templates/js/table_filters.html:42 msgid "Is allocated" msgstr "" -#: templates/js/table_filters.html:58 +#: templates/js/table_filters.html:43 msgid "Item has been alloacted" msgstr "" -#: templates/js/table_filters.html:99 +#: templates/js/table_filters.html:47 +msgid "Include sublocations" +msgstr "" + +#: templates/js/table_filters.html:48 +msgid "Include stock in sublocations" +msgstr "" + +#: templates/js/table_filters.html:53 +msgid "Show stock items which are depleted" +msgstr "" + +#: templates/js/table_filters.html:58 +msgid "Show items which are in stock" +msgstr "" + +#: templates/js/table_filters.html:62 +msgid "Sent to customer" +msgstr "" + +#: templates/js/table_filters.html:63 +msgid "Show items which have been assigned to a customer" +msgstr "" + +#: templates/js/table_filters.html:79 templates/js/table_filters.html:80 +msgid "Stock status" +msgstr "" + +#: templates/js/table_filters.html:109 msgid "Build status" msgstr "" -#: templates/js/table_filters.html:111 templates/js/table_filters.html:124 +#: templates/js/table_filters.html:121 templates/js/table_filters.html:134 msgid "Order status" msgstr "" -#: templates/js/table_filters.html:116 templates/js/table_filters.html:129 +#: templates/js/table_filters.html:126 templates/js/table_filters.html:139 msgid "Outstanding" msgstr "" -#: templates/js/table_filters.html:139 +#: templates/js/table_filters.html:149 msgid "Include subcategories" msgstr "" -#: templates/js/table_filters.html:140 +#: templates/js/table_filters.html:150 msgid "Include parts in subcategories" msgstr "" -#: templates/js/table_filters.html:145 +#: templates/js/table_filters.html:155 msgid "Show active parts" msgstr "" -#: templates/js/table_filters.html:153 +#: templates/js/table_filters.html:163 msgid "Stock available" msgstr "" -#: templates/js/table_filters.html:169 +#: templates/js/table_filters.html:179 msgid "Starred" msgstr "" -#: templates/js/table_filters.html:181 +#: templates/js/table_filters.html:191 msgid "Purchasable" msgstr "" From 2bbc65cc5933ea4b3e937ffbd25644dacd4e8118 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 13:29:38 +1000 Subject: [PATCH 51/58] Add "brief" version of QR codes - Use this to render to labels (as it contains much less information) --- InvenTree/InvenTree/helpers.py | 19 ++++++++----- .../barcode/plugins/inventree_barcode.py | 28 +++++++++++++------ InvenTree/label/models.py | 2 +- InvenTree/stock/models.py | 13 +++------ 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index bf7e9083b5..fb54bc4c6f 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -242,7 +242,7 @@ def WrapWithQuotes(text, quote='"'): return text -def MakeBarcode(object_name, object_data): +def MakeBarcode(object_name, object_pk, object_data, **kwargs): """ Generate a string for a barcode. Adds some global InvenTree parameters. Args: @@ -255,12 +255,17 @@ def MakeBarcode(object_name, object_data): json string of the supplied data plus some other data """ - data = { - 'tool': 'InvenTree', - 'version': inventreeVersion(), - 'instance': inventreeInstanceName(), - object_name: object_data - } + brief = kwargs.get('brief', False) + + data = {} + + if brief: + data[object_name] = object_pk + else: + data['tool'] = 'InvenTree' + data['version'] = inventreeVersion() + data['instance'] = inventreeInstanceName() + data[object_name] = object_data return json.dumps(data, sort_keys=True) diff --git a/InvenTree/barcode/plugins/inventree_barcode.py b/InvenTree/barcode/plugins/inventree_barcode.py index 821cdc9c88..780b7e888a 100644 --- a/InvenTree/barcode/plugins/inventree_barcode.py +++ b/InvenTree/barcode/plugins/inventree_barcode.py @@ -47,12 +47,12 @@ class InvenTreeBarcodePlugin(BarcodePlugin): else: return False - for key in ['tool', 'version']: - if key not in self.data.keys(): - return False + # If any of the following keys are in the JSON data, + # let's go ahead and assume that the code is a valid InvenTree one... - if not self.data['tool'] == 'InvenTree': - return False + for key in ['tool', 'version', 'InvenTree', 'stockitem', 'location', 'part']: + if key in self.data.keys(): + return True return True @@ -60,10 +60,22 @@ class InvenTreeBarcodePlugin(BarcodePlugin): for k in self.data.keys(): if k.lower() == 'stockitem': + + data = self.data[k] + + pk = None + + # Initially try casting to an integer try: - pk = self.data[k]['id'] - except (AttributeError, KeyError): - raise ValidationError({k: "id parameter not supplied"}) + pk = int(data) + except (ValueError): + pk = None + + if pk is None: + try: + pk = self.data[k]['id'] + except (AttributeError, KeyError): + raise ValidationError({k: "id parameter not supplied"}) try: item = StockItem.objects.get(pk=pk) diff --git a/InvenTree/label/models.py b/InvenTree/label/models.py index 6faf966d7e..7d481327a9 100644 --- a/InvenTree/label/models.py +++ b/InvenTree/label/models.py @@ -142,7 +142,7 @@ class StockItemLabel(LabelTemplate): 'serial': item.serial, 'uid': item.uid, 'pk': item.pk, - 'qr_data': item.format_short_barcode(), + 'qr_data': item.format_barcode(brief=True), 'tests': item.testResultMap() }) diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index 664593e600..e523ed70d3 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -283,7 +283,7 @@ class StockItem(MPTTModel): def get_part_name(self): return self.part.full_name - def format_barcode(self): + def format_barcode(self, **kwargs): """ Return a JSON string for formatting a barcode for this StockItem. Can be used to perform lookup of a stockitem using barcode @@ -296,19 +296,14 @@ class StockItem(MPTTModel): return helpers.MakeBarcode( "stockitem", + self.id, { "id": self.id, "url": reverse('api-stock-detail', kwargs={'pk': self.id}), - } + }, + **kwargs ) - def format_short_barcode(self): - """ - Return a short barcode - """ - - return "stockid={pk}".format(pk=self.pk) - uid = models.CharField(blank=True, max_length=128, help_text=("Unique identifier field")) parent = TreeForeignKey( From a4267f76e86432c3a99ee9fc299797254d56e3fe Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 13:39:05 +1000 Subject: [PATCH 52/58] Fixes for barcode data rendering --- InvenTree/InvenTree/helpers.py | 3 +++ InvenTree/InvenTree/tests.py | 1 + InvenTree/part/models.py | 7 ++++--- InvenTree/stock/models.py | 8 ++++---- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index fb54bc4c6f..28cebbcd3d 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -265,6 +265,9 @@ def MakeBarcode(object_name, object_pk, object_data, **kwargs): data['tool'] = 'InvenTree' data['version'] = inventreeVersion() data['instance'] = inventreeInstanceName() + + # Ensure PK is included + object_data['id'] = object_pk data[object_name] = object_data return json.dumps(data, sort_keys=True) diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py index 877adab919..c46a059c8d 100644 --- a/InvenTree/InvenTree/tests.py +++ b/InvenTree/InvenTree/tests.py @@ -138,6 +138,7 @@ class TestMakeBarcode(TestCase): bc = helpers.MakeBarcode( "part", + 3, { "id": 3, "url": "www.google.com", diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 308808fbdd..c074d197b9 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -560,16 +560,17 @@ class Part(MPTTModel): responsible = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True, related_name='parts_responible') - def format_barcode(self): + def format_barcode(self, **kwargs): """ Return a JSON string for formatting a barcode for this Part object """ return helpers.MakeBarcode( "part", + self.id, { - "id": self.id, "name": self.full_name, "url": reverse('api-part-detail', kwargs={'pk': self.id}), - } + }, + **kwargs ) @property diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index e523ed70d3..788bf845df 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -45,16 +45,17 @@ class StockLocation(InvenTreeTree): def get_absolute_url(self): return reverse('stock-location-detail', kwargs={'pk': self.id}) - def format_barcode(self): + def format_barcode(self, **kwargs): """ Return a JSON string for formatting a barcode for this StockLocation object """ return helpers.MakeBarcode( 'stocklocation', + self.pk, { - "id": self.id, "name": self.name, "url": reverse('api-location-detail', kwargs={'pk': self.id}), - } + }, + **kwargs ) def get_stock_items(self, cascade=True): @@ -298,7 +299,6 @@ class StockItem(MPTTModel): "stockitem", self.id, { - "id": self.id, "url": reverse('api-stock-detail', kwargs={'pk': self.id}), }, **kwargs From ccda637e3c67f462b35f9efee3b5813f90dc17e0 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 13:42:27 +1000 Subject: [PATCH 53/58] Fixes for barcode decoding --- .../barcode/plugins/inventree_barcode.py | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/InvenTree/barcode/plugins/inventree_barcode.py b/InvenTree/barcode/plugins/inventree_barcode.py index 780b7e888a..6e4e6937a0 100644 --- a/InvenTree/barcode/plugins/inventree_barcode.py +++ b/InvenTree/barcode/plugins/inventree_barcode.py @@ -68,7 +68,7 @@ class InvenTreeBarcodePlugin(BarcodePlugin): # Initially try casting to an integer try: pk = int(data) - except (ValueError): + except (TypeError, ValueError): pk = None if pk is None: @@ -89,10 +89,21 @@ class InvenTreeBarcodePlugin(BarcodePlugin): for k in self.data.keys(): if k.lower() == 'stocklocation': + + pk = None + + # First try simple integer lookup try: - pk = self.data[k]['id'] - except (AttributeError, KeyError): - raise ValidationError({k: "id parameter not supplied"}) + pk = int(self.data[k]) + except (TypeError, ValueError): + pk = None + + if pk is None: + # Lookup by 'id' field + try: + pk = self.data[k]['id'] + except (AttributeError, KeyError): + raise ValidationError({k: "id parameter not supplied"}) try: loc = StockLocation.objects.get(pk=pk) @@ -106,10 +117,20 @@ class InvenTreeBarcodePlugin(BarcodePlugin): for k in self.data.keys(): if k.lower() == 'part': + + pk = None + + # Try integer lookup first try: - pk = self.data[k]['id'] - except (AttributeError, KeyError): - raise ValidationError({k, 'id parameter not supplied'}) + pk = int(self.data[k]) + except (TypeError, ValueError): + pk = None + + if pk is None: + try: + pk = self.data[k]['id'] + except (AttributeError, KeyError): + raise ValidationError({k, 'id parameter not supplied'}) try: part = Part.objects.get(pk=pk) From da079b23dcba7d4ae8414d22a5413595aa8dd14d Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 16 Aug 2020 13:43:59 +1000 Subject: [PATCH 54/58] Fix duplicate label printing menu action --- InvenTree/stock/templates/stock/item_base.html | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index a7bc263bbf..e65f8e0b33 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -78,7 +78,7 @@ InvenTree | {% trans "Stock Item" %} - {{ item }}