From 3bea80982385edbfe9721a86821c3bc6aa269d85 Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 5 Jul 2023 11:11:19 +1000 Subject: [PATCH] Unit check option (#5175) * Add option to control parameter units * Check setting before validation * Update part parameter settings page * Update unit tests * Update docs --- InvenTree/common/models.py | 7 +++ InvenTree/part/models.py | 10 +++++ InvenTree/part/test_param.py | 16 ++++++- .../InvenTree/settings/part_parameters.html | 41 ++++++++++++------ .../images/part/part_parameters_enforce.png | Bin 0 -> 6264 bytes docs/docs/part/parameter.md | 6 +++ 6 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 docs/docs/assets/images/part/part_parameters_enforce.png diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 2177521480f..23f83a75871 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -1249,6 +1249,13 @@ def save(self, *args, **kwargs): 'default': '', }, + 'PART_PARAMETER_ENFORCE_UNITS': { + 'name': _('Enforce Parameter Units'), + 'description': _('If units are provided, parameter values must match the specified units'), + 'default': True, + 'validator': bool, + }, + 'PRICING_DECIMAL_PLACES_MIN': { 'name': _('Minimum Pricing Decimal Places'), 'description': _('Minimum number of decimal places to display when rendering pricing data'), diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index cd993ed8261..7b1d2286961 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -3532,6 +3532,16 @@ def clean(self): super().clean() + # Validate the parameter data against the template units + if InvenTreeSetting.get_setting('PART_PARAMETER_ENFORCE_UNITS', True, cache=False, create=False): + if self.template.units: + try: + InvenTree.conversion.convert_physical_value(self.data, self.template.units) + except ValidationError as e: + raise ValidationError({ + 'data': e.message + }) + # Validate the parameter data against the template choices if choices := self.template.get_choices(): if self.data not in choices: diff --git a/InvenTree/part/test_param.py b/InvenTree/part/test_param.py index 13767676c7f..8ae2ca5d7c7 100644 --- a/InvenTree/part/test_param.py +++ b/InvenTree/part/test_param.py @@ -4,6 +4,7 @@ from django.test import TestCase, TransactionTestCase from django.urls import reverse +from common.models import InvenTreeSetting from InvenTree.unit_test import InvenTreeAPITestCase from .models import (Part, PartCategory, PartCategoryParameterTemplate, @@ -168,11 +169,24 @@ def test_param_unit_validation(self): param = PartParameter(part=prt, template=template, data=value) param.full_clean() + bad_values = ['3 Amps', '-3 zogs', '3.14F'] + + # Disable enforcing of part parameter units + InvenTreeSetting.set_setting('PART_PARAMETER_ENFORCE_UNITS', False, change_user=None) + # Invalid units also pass, but will be converted to the template units - for value in ['3 Amps', '-3 zogs', '3.14F']: + for value in bad_values: param = PartParameter(part=prt, template=template, data=value) param.full_clean() + # Enable enforcing of part parameter units + InvenTreeSetting.set_setting('PART_PARAMETER_ENFORCE_UNITS', True, change_user=None) + + for value in bad_values: + param = PartParameter(part=prt, template=template, data=value) + with self.assertRaises(django_exceptions.ValidationError): + param.full_clean() + def test_param_unit_conversion(self): """Test that parameters are correctly converted to template units""" diff --git a/InvenTree/templates/InvenTree/settings/part_parameters.html b/InvenTree/templates/InvenTree/settings/part_parameters.html index d2b15edf872..95812ef51e3 100644 --- a/InvenTree/templates/InvenTree/settings/part_parameters.html +++ b/InvenTree/templates/InvenTree/settings/part_parameters.html @@ -4,22 +4,37 @@ {% block label %}part-parameters{% endblock label %} {% block heading %} -{% trans "Part Parameter Templates" %} +{% trans "Part Parameters" %} {% endblock heading %} -{% block actions %} - -{% endblock actions %} +{% block panel_content %} -{% block content %} -
-
- {% include "filter_list.html" with id="parameter-templates" %} + + + {% include "InvenTree/settings/setting.html" with key="PART_PARAMETER_ENFORCE_UNITS" icon="fa-clipboard-check" %} + +
+ +
+
+

{% trans "Part Parameter Templates" %}

+ {% include "spacer.html" %} +
+ +
- -
-{% endblock content %} +
+
+
+ {% include "filter_list.html" with id="parameter-templates" %} +
+
+ +
+
+ +{% endblock panel_content %} diff --git a/docs/docs/assets/images/part/part_parameters_enforce.png b/docs/docs/assets/images/part/part_parameters_enforce.png new file mode 100644 index 0000000000000000000000000000000000000000..2ce41ad2f342311da4d51e0ea1c7e105c22232a1 GIT binary patch literal 6264 zcmb_Ac|6qJ*OXRUrIKALB+-oQYsnI2XY8IZc&uaWyC_0KWtkXE$j(?MjQy!0nXx3h zv1H%I$TAoP@ASM6zvrL#{pWqp=kxu3@45HfbIV#OUd0FrVi%8QxX6kL|;o$A}3<{>xfP%s9UQQm~*2ZUPQ`lD@KYC!~Z@rRX;c*3& z621rDbmBGF(%xVdSbMYGP~B%B!0TTjdNyU{>Weu6SB{t%!FbNNoU19EE~EVFS^8&k z^VQxzm#KW6z{8nEy4du_RLbG6KO$k-H`%5;ng*=vosn@cM!qlGi-tyyNUP$3@%*A8 zYgstbjV9TDgGxJ_ zbe%L-zfBtRGM3VRt_wO?@+=`fLo)wrB*Iqapcx5`_TqP$j zUteDS)7dT4n}bBzm`|F#aPc3IcBwMYNKGAn#Ni$stiXQasQ==!ypqzm5l2@rzmHu= zNCuGmNX97#9zH%~W~Q~N>Cn&+a&!%cegJOW9OO76@#G2#0Amh{wKuk5hW+S}J-2hj zZ@IO>hn;l_ezU=|Ej?YIE4~<3pqRD^jBHY{y|@~sQtukX*Ld7FXwzY_eQ#p;k^1DP z@OQAx-_G|eb$(_sJe2dFG#S81CaxLQ0Y`iAhS{D6y-H(41LI+CcU^+Xu7Q`16zi!m zngtw1dz3N1&o;FHKf3SU%6GaSM-4zGzch*JG$gI(P$J~Guv$@|tq*Ztd+ z2$<&Sg~GTni}U+!B6<5et@XNJqvBWHJUm?ZxPwf1?!C2h86c;LV8@V+&;z4xk5NYl z!npi*2^qQicVuL}f8Qr03e^!j5T@t1Oxef|bq0IR{P-D@lM%EMzbBUv>}__igYC zEq?_j>iKDaOD7dLWWE0K86O-D`F?de-loB2`{B`%db+ochq%NU<|I#yWb4lV_5QXL zjG0%?Ykwd@Tw#olr`$NJ#6G2eaYSyfOiXN8eK|!rsjflBv#=Q(FV)=f>!%>{jBMRr=1=YH)qCQRWW8If#e$f`ShsY>l%*8AL=v(0EL3|TVXuWtM3Gc-Q5=SaZ3{40r!_)3y zd9EEq54G+JfH73R+}ne5hn^dW8`a-2D);bP)k%!Pjp@jPSRUD7_QUw1G7HL7 znwQTSF8mNExkrYC2n7-06aC^?N%u{g{k;6#g<3#8$o5j&aK%?hlD3~%=r#4e>Q(&H99y^zGLQvA%zuTnIOas+Y8P4&%u`04DA$MBH(p@$9r&9E7>G zb%)l@OqissQX;?@RlfSw_u3ZqOd!9u5wOhkk1rW6a1o7BixW9EFqLBq9XTBUfH8s-UQ9mGpUp@a9nv`-HwG?G^2LTwjz zCsyPcj>PfQPO&-m_K$*Ba+#u!0*qc746Fw8hL);h6pxW+b)n^IdWAgoK3djt)^#QH(hv-+=>VUWzIy z8PYmVw&?mC0|ElT;9T=k_iUzoJ$Z$Y-OctyA!o;9UIpEWLb{nsA?Bqfj*gB95$tU# zDJelgK@$+DKl7OCJ5zCSF&i5j8jb#)e!cvie&xSUPdBRXpPYz3+?hkw9FQZ!yb_Kx zL+c|sClfsp&>R*AwSq_&|)|&xoC`h#5vr=c45O~{NPu;G)wTIZpLAa zS--Wj&6Urs5$diM9HdSwkNpktP&1>ddfw6&5H=`V!H+d;HnZ@vX4y)BYl~#kUkiZL zAL5}D(yu{MD(Jj?jX;1rYFvC2%V4wF^kw>#)2&fAd%T}W2w*F|?o1hP;7(yh@m63B z|K~x~`fa98%$YJC3GAwryuPw=Utwhon~IgVJXIVX+Ftnrjc*=!`R3tW59^tC372Rx zhl3K9Hqllg6NmV$(#ty{g~>K|trARZy}&Y!IB!K8+J4Mn`>}nk z)tK_o9$_*mLI2QZxxZa1`}+kIVep?`D*&5)7H&R`$-Y0UcJc8gpNP zX<4dTF9R*n%W8Wjm>-O)`n5QdJe;!ArF{?%FN#%b_&9uer|<%NvU;Wa4;-ZQEEvN+ zpKlpO&;tIQu3OvrlHDp!5Bh}ePZkwlyxmvrtiK|X7Q2|O%B&@d1@jsDD4NIEb99+B z#lwaKlEUKBOV7)WEsbt{+U;);w}LH5dkuffMi6>}}PGP-5>9&QlO?yx`5{@&)i!v>$hv~Q#p{r{n zFKatzOWHe4J2ynq&J5m+{t&ba7bT2w_q_hHY7pH1=z;~aF!b? z@m&Szl0$ni2_`I^ck4Igiz;5+YLa>z&fy_O&x3y!ZDvZ!H>?bs8TwpQzIJ(qgENlh zuI-6%4J(s_GAEx?SHu$w^sTz8EB`24hVVhcjEduWd`zB&Fh8_;e{kWHdO~gfrs8*! z3u=K_{eeVxAntpy*N(*6q`!L2;5@uRho8`M=B*h85M|fysHRkC553VTcllm--Mbg* zpUR?wRG$QW2tFXo4V6D5+{&3ZIuP2T1a;?iDv`0WIaZd z6sVNRaWDrJX@$U%8?8Ny+@JL?BY!N9h$gKH!m}JImMw@CRJkErc}=fk)1b4xPKK8l z!MZS|RyTBb^`Dq@>^-$N<{|cfU6U6Iy^AWJ7WsJH0hk7RqYmYy=U2A^ZUq8BNX#a; zeokH9`7i~%GQPj{n%Gu}DSwSiB9Aabg){@wn$#VnN}Uf(F;21`)o^s-b+BtUf7m@L zM#2=@e;HynD_~e7_1se=sdyf|Gm4(^y+3be0wg%S4qeYtf3A#rEPs%%q2D303EHtT z&?u2Lcu7Q#$G=;1gnHT<8kRb7D_;;}14N5Zs4+Y%2nCeuYq=eG$!A%c_Z6D~$qMve zgcStRl+Roq7S5i;u;|Yib;vj-CuE?6yNMV9dH~n@BU)u7{3_U`Ic~RWH4IXfb$Kgj z%E;c2NwcC8EK}v_=&ZFbUHtiW=SJyE>!<3u0xI!r z8|OOOG#sC@zEQCP9t2(ti$0UB?xPsBr!pn(Ry8SCTt3C(P`132IS0|@SZTVhNiFG_ z80OYb<)`lR<<4^{DiLhm1maQ%t%^@>O-IT=S#NBTrtn~YUI6p-=kqvwDfN#H*RXM>LU+hXy0@SBufH-Y%4*gSOr%*U^Q6zG!_zO(nwk0$ zU)OT}y!?6W0rsMVJvZgj8GE3<=|xBCddS|pofL~)Gt5c6P8}u zym{GX-!ii)L6bi;bu_O&VFQHS2O5sVKT*vSF zi!LhZp8#wXwp^awIzL@1yTQwT)A$6P|Cm1fb+dI}vH>Q2THS{dy{Cd96u5l14tK`V zoCG5%z3Ecipu^XgB$as$yow36}C@Q04K@l*oe5dR}&TcR4lQFiSXkT;QRYgs)P>0e7>J`rgd6PF3fKVC zjg^DKq{Y2g3)h^;32s9E|M!@De%*!KuL~Uh3s#gPZd^Umn^FY zSMo=<#$Ncw6oR(Q7PT(=^{!BO*owpYGi?C*tbVp*u3mg=fv@gX4BM-U zlQB;^imsJ)Dlg@9hDlq(u=EY%1=?S2IHy)2&zF9Zq~?CGY(Iz8=nsBqr0b80yRdcX zGN)=7+o*e-dJun*-D6wQNwLEVS?{f7P#q6^2xCF6eghKJ&N9EX-s~E;Pe#C9=oRz^*4b7g>zG)m5Mpxg&t-uMydhk0fg{MgwvnZOpfreqUJ+c zDK-(f0amG6b%*i#0b+pYvPp4-K~LKwEl&gxP1B#9<6XJ(m8&!O{WyjRjufN2SAfUa z#IzSZ@O}!rzwa*740mRi?)btiVo3~&C)ee~@t+Pj**aLiyd}(V=SdV*9KtRb_{E|hisk3*)O>g#?VOO<>*&kXL{QdtM9)S?|N>% zHdpDyf@UCI19K~?#V~5!WXo78QrrfbVJUwKcbJxLh=iPYq26n#?Ac@wB9 zwE{4EH`Om4;Go!l{rvoE#$w(mv!_q^f2;O1)nG}d!VQd>Li{Y*vMZwXoysoKxC01$ zVpJmP$#LS3pq~x2nrwK6Eofp}S=?witzwy47p$8;QY|TS