From a5b1f68f624de6d3304ece496a307d39f3ec0cde Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 25 Oct 2021 13:06:54 +0200 Subject: [PATCH 1/7] #36 Quality checks * adds AbstractQualityChecker as base for all quality checker instances * adds InterventionQualityChecker, inheriting from AbstractQualityChecker * adds functionality to InterventionQualityChecker * adds/updates translations --- intervention/forms/modalForms.py | 6 +- intervention/models.py | 57 +--- intervention/utils/quality.py | 112 ++++++++ konova/utils/quality.py | 34 +++ locale/de/LC_MESSAGES/django.mo | Bin 26795 -> 26682 bytes locale/de/LC_MESSAGES/django.po | 445 ++++++++----------------------- 6 files changed, 272 insertions(+), 382 deletions(-) create mode 100644 intervention/utils/quality.py create mode 100644 konova/utils/quality.py diff --git a/intervention/forms/modalForms.py b/intervention/forms/modalForms.py index 1af0ddc..4f8fa75 100644 --- a/intervention/forms/modalForms.py +++ b/intervention/forms/modalForms.py @@ -208,13 +208,13 @@ class RunCheckModalForm(BaseModalForm): """ super_result = super().is_valid() # Perform check - msgs = self.instance.quality_check() - for msg in msgs: + checker = self.instance.quality_check() + for msg in checker.messages: self.add_error( "checked_intervention", msg ) - return super_result and (len(msgs) == 0) + return super_result and checker.valid def save(self): """ Saving logic diff --git a/intervention/models.py b/intervention/models.py index 9d0c881..7fbb922 100644 --- a/intervention/models.py +++ b/intervention/models.py @@ -16,6 +16,7 @@ from codelist.models import KonovaCode from codelist.settings import CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID, CODELIST_LAW_ID, \ CODELIST_PROCESS_TYPE_ID from intervention.managers import InterventionManager +from intervention.utils.quality import InterventionQualityChecker from konova.models import BaseObject, Geometry, UuidModel, BaseResource, AbstractDocument, \ generate_document_file_upload_path from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE, LANIS_ZOOM_LUT @@ -56,7 +57,6 @@ class ResponsibilityData(UuidModel): conservation_file_number = models.CharField(max_length=1000, blank=True, null=True) handler = models.CharField(max_length=500, null=True, blank=True, help_text="Refers to 'Eingriffsverursacher' or 'Maßnahmenträger'") - def __str__(self): return "ZB: {} | ETS: {} | Handler: {}".format( self.registration_office, @@ -296,62 +296,15 @@ class Intervention(BaseObject): pass super().delete(using, keep_parents) - def quality_check(self) -> list: + def quality_check(self) -> InterventionQualityChecker: """ Quality check Returns: ret_msgs (list): Holds error messages """ - ret_msgs = [] - - self._check_quality_responsible_data(ret_msgs) - self._check_quality_legal_data(ret_msgs) - - # ToDo: Extend for more! - - return ret_msgs - - def _check_quality_responsible_data(self, ret_msgs: list): - """ Checks data quality of related ResponsibilityData - - Args: - ret_msgs (dict): Holds error messages - - Returns: - - """ - try: - # Check for file numbers - if not self.responsible.registration_file_number or len(self.responsible.registration_file_number) == 0: - ret_msgs.append(_("Registration office file number missing")) - - if not self.responsible.conservation_file_number or len(self.responsible.conservation_file_number) == 0: - ret_msgs.append(_("Conservation office file number missing")) - except AttributeError: - # responsible data not found - ret_msgs.append(_("Responsible data missing")) - - def _check_quality_legal_data(self, ret_msgs: list): - """ Checks data quality of related LegalData - - Args: - ret_msgs (dict): Holds error messages - - Returns: - - """ - try: - # Check for a revocation - if self.legal.revocation: - ret_msgs.append(_("Revocation exists")) - - if self.legal.registration_date is None: - ret_msgs.append(_("Registration date missing")) - - if self.legal.binding_date is None: - ret_msgs.append(_("Binding on missing")) - except AttributeError: - ret_msgs.append(_("Legal data missing")) + checker = InterventionQualityChecker(obj=self) + checker.run_check() + return checker def get_LANIS_link(self) -> str: """ Generates a link for LANIS depending on the geometry diff --git a/intervention/utils/quality.py b/intervention/utils/quality.py new file mode 100644 index 0000000..72ed2a7 --- /dev/null +++ b/intervention/utils/quality.py @@ -0,0 +1,112 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 25.10.21 + +""" +from django.utils.translation import gettext_lazy as _ +from konova.utils.quality import AbstractQualityChecker + + +class InterventionQualityChecker(AbstractQualityChecker): + def run_check(self): + """ Perform all defined data checks + + Returns: + + """ + + self._check_responsible_data() + self._check_legal_data() + self._check_compensations() + self._check_geometry() + self.valid = len(self.messages) == 0 + + def _check_responsible_data(self): + """ Checks data quality of related ResponsibilityData + + Args: + self.messages (dict): Holds error messages + + Returns: + + """ + try: + resp = self.obj.responsible + # Check for file numbers + if not resp.registration_file_number or len(resp.registration_file_number) == 0: + self._add_missing_attr_name(_("Registration office file number")) + + if not resp.conservation_file_number or len(resp.conservation_file_number) == 0: + self._add_missing_attr_name(_("Conservation office file number")) + + # Check for selected offices + if resp.registration_office is None: + self._add_missing_attr_name(_("Registration office")) + + if resp.conservation_office is None: + self._add_missing_attr_name(_("Conservation office")) + + if resp.handler is None: + self._add_missing_attr_name(_("Intervention handler")) + except AttributeError: + # responsible data not found + self._add_missing_attr_name(_("Responsible data")) + + def _check_legal_data(self): + """ Checks data quality of related LegalData + + Args: + self.messages (dict): Holds error messages + + Returns: + + """ + try: + legal = self.obj.legal + # Check for a revocation + if legal.revocation: + self.messages.append(_("Revocation exists")) + + if legal.registration_date is None: + self._add_missing_attr_name(_("Registration date")) + + if legal.binding_date is None: + self._add_missing_attr_name(_("Binding date")) + + if legal.laws.count() == 0: + self._add_missing_attr_name(_("Laws")) + + if legal.process_type is None: + self._add_missing_attr_name(_("Process type")) + except AttributeError: + self._add_missing_attr_name(_("Legal data")) + + def _check_compensations(self): + """ Checks for compensation, deduction or payment + + Returns: + + """ + c_comps = self.obj.compensations.count() + c_pays = self.obj.payments.count() + c_deducs = self.obj.deductions.count() + c_all = c_comps + c_pays + c_deducs + if c_all == 0: + self.messages.append( + _("No compensation of any type found (Compensation, Payment, Deduction)") + ) + + def _check_geometry(self): + """ Checks on the geometry + + Returns: + + """ + try: + geometry_obj = self.obj.geometry + if geometry_obj.geom.empty: + self._add_missing_attr_name(_("Geometry")) + except AttributeError: + self._add_missing_attr_name(_("Geometry")) diff --git a/konova/utils/quality.py b/konova/utils/quality.py new file mode 100644 index 0000000..b59c327 --- /dev/null +++ b/konova/utils/quality.py @@ -0,0 +1,34 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 25.10.21 + +""" +from abc import abstractmethod +from django.utils.translation import gettext_lazy as _ + +from konova.models import BaseObject + + +class AbstractQualityChecker: + valid = False + messages = [] + obj = None + + class Meta: + abstract = True + + def __init__(self, obj: BaseObject): + self.obj = obj + self.messages = [] + self.valid = False + + @abstractmethod + def run_check(self): + raise NotImplementedError + + def _add_missing_attr_name(self, attr_name: str): + missing = _('missing') + self.messages.append(f"{attr_name} {missing}") + diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 8a1e11b3bf85fc2addccaff72983a2c4993babf7..a992cbb136e1f7e893caa5e4795d15c90460558b 100644 GIT binary patch delta 8583 zcmY+}34Bdw{>Skr$R=GoFG{hFfzFf&osJM|xM5tbhstTgw``=TC_@yS?)5X33V&bPkvK7V;;he_ZX9pd(eyZ+Z!_q z%W)OfVjCRR!I)-PXsyB^@{eGcF+Q`21Y?>fF&tmA9&j3%50SpiXL7`7ziWXQA3xp!#2n8gENo-e=77w&HbcOvPbjX69qm%+FywUPE;dMW#N+ zqgK)xHBc(5_kYp&uJDzS&BmA-^>^4g3Xat1hE%yp1};W(iJt z3Tg#IF%l=DRyZHE;#C-ozd`l86?H_rQT-jn)_4-*@Nxp@uK_|6of|u02>EU{-v@Q$ zAk@I)Q9Dv(>*u3(t`ZyIa@5LJqb9TkHIZGYiM)ZKcmy@hM~UpeI{ci15%?88id{N8 zTl^Mk;15v)ok4YY5w()*s1-L!a{7rv<=dhLh_`k_?N}ew{i9G5neHQ@2^6CS@}i#J zh%gtb~+42)kmOa9*NqzL{vv<*a*|DIj9}X$0#g9wR-?H!8NG<*4N4T`$>$Y zU<>xZE2y)M>t;+Z?2K*EjV@e{dT5_Pt?*sc1U^O$cph~WKcS8yEX6spcG#GFAJonb z!(hGtlSybsZfg;$<9Vo+E<@e82DLMrZTSp43KC#&sB>7o+a?t+EB{P&Yn-EpQiVC*H>9cmm__YkUd=*k28}1GVKZ zpay&k`39LIsQdnjns88W$Cjuak4O6VnVuvxa5k#L@u;ntit4z)T7i0)R--!HXv=q? zCb}2-4Q&o%GrWvC!kUb@-#8)v2 zk6<*O$ANeQ^X2&eIx=8YmexfuX35 z#-e8KMy}p3s-Jgl`7vAmIr?5bntllv*lM&&xY@Yt!OaF=`h3^ zhT7V2)XucRZkU1Enfa)PYAveWX4Dq%z%2f~@Cu$I|3fC<20WF;w*;#OJO55d8^YI9 z@Bf1&CQ{LNs4?&0CTxeJhw+yUEJJPGR@7PUK@Ic<>Mc2J>(8Ke=I^%t4r;=Uvz=d7 z8K|S2gxaY^b>%)|HrNI)*@_QP4bP({@-ymvZ+ovZU@vS%ek4X>G3qRrpZocl9?zlrZ7|%~$r$u?q@V){&3HKKp_q-aSc=-}$1oJPq9*tp>PX%|wLgjt@ib~> zU!r#CB5H^3pzezt;q)7it;r7_!TIZ{olhI0d4vR=dS zl;6TFIBKNR&n48E-^MU(I?CCBHmC_Dqb8E$vxz*^7EiT$Y@H9j6iif95sRI z)?y4MUxwO=YShtfKn=JV^+nu?YPSn@=C5FH+=t9F2O~3s4ie&svIVUx8Z4qt>TT?f0VYe+xCy>>IkY)1Ky9C;7Zi%`Y`H)^bD$>ck=D~ zUrT{j{t@bRyNKGNAF(MmnCLtsEm3FP4praH<_DlAl#8Qq66&FT0kx1?)RBCGyd)-a zlCu+0lh}VXNTQ%6rX!zcGY++d+pVvnp4#_O1Am2@=vCBK-a#Ev@MQbGV?6mbn219# z1-;l6pT=%@!bc*N#4k7uyG=2sJ1#;^Y&U8m2XPRdKn)Z=)j6tYY)!r$Y9i^Vog9Ku zI2rZDEJN+&M%2WgMIDWA9|@h+e$>_;!bm)h8u%O3*8Ygz#yo76(%CCh91DLJiP(hBI)iH5oO*K{lU{TKODQ z#|uzj#A;jrG-?5RvF@S6X!5lfsrUa337yF`)Yi3~>C8M0^)wGd4UmJ{`mv}Tn~Ivq zY}64f#zE*u?c{0HPJDxE7dp#XNF3^DQ!&d&B8!Apyc+c^Y)75ZNgROZQ608%J1a~= zeZhL5?#slsI0@Th6>5NOs0Hmo?MyA|NdAnv{~Y>aNL(SI83xUE-p^Q6gFdJZhN8}X z3Ti7$P!n8?_3&ZT4n1o1<6`pLusgOWaDF>xV*>fFtf7VMzl(zIh0dpP9BKtVtcN>M zzZ-U;wtg>a0&in|JZj62q1u0jTIt_x{nx08T}0jYJ!&DhY(C7x{%Z%KJkFV>p;q1x zHE=d+EAvnt6`%&1hZ@L>I0XLik*RjQ4@;5AdE)!6KCy!f#efW_jki!Otbm^s0I24lF%6sw-qxnn0x`M z!+ExR0jk3a)PPHD`3h9K)i(bKYOB{{N8F0~(!Gaqcn$ShN6e{f=QD96RFH%L_&)JF z;%A~E1+594y{`3y{xf1U<`dr$L&*2W3PJ;oA^#i9$Gg`Q(rd`9CiKRYlm85FDtDU% zzq(BZg-LiHp{tTuRF`so`~n5G(+SplDQibsujk!sk*(W6K_k+?w-p|&AfHR5**4#6 zHo6|P1<6*GjUqh{^$Mksjo*Vj2Re8uao5BYhG zs2g9eTwiWTB=|g=i-fM-#Jaka^LWy@+juu6mTYiP@wV5P8HILT|!w z;v1qP^}0B1(>8#YralG3i4vj%kxI;<@~_0(#HWO=cEoh*hG8tu@^5b4$v2GDX-XF2 zF+4^5i@2BkNMa-DhY4N!FD_kgIG6{qkg^5DWMVG)T|}I1_y4wC4OZE-$Rx^%v3C2+ zaWWqePY{8Gu8$q+elFqXQ6h|v^{&O#l`?7TuhF}7_qtBvF=DWt&-hde z!3bMeP2n<|9)#KCi)?;A>Aj@K6EjGc;H$(V#OK7{iN6sIsOwFz02t2ltY|1F6~TUkbW6tRWaL8KFRuXk-?tu+y!COQ+P zgnn}^r=LcsYcR3Q_S=$l57K+E3kG8mp48dDN2V*8#YBHX{{nrDvb)z15}S$bwxAa8 zA^wk8N>tHa*8^C9FVy9X`43LAb!SyZ`aYsN(Sxj8WsGnBp#)b;D*6x)kRE`#b`n1l zOUd^lo*{jL7)e|uE)WxmIruz@X#rUStZlJ9SvYyAD_WrL)KWfXT;7XeosYEl| zPWic{lkrU=hjfGr?X?M$C=0=%w(K39_k5dKVmtbTd~?$GW45h3WSwc-_{j&?taEh? zYEtN~@R+Q*-om-wVpplR=4kx1dJQVdD+~N73DGshiA#gS-Bk-suBX^t;-azJ|F4wv zn%=1~0htA*^A~u$3*8lSOTDhrBA44+?W(9=;Bgg|R(cCv34?!C-^De?T|M99t?1$! z;wh{w&^?JYqq=Xb@4wkIu_mY2f`FRZ-pfLQ<}O^wOlr~x?Fp^a|`BpTtnOy{_**l{v-LVYF^KG1q^p(RxT_q@lffy&r@92sN9uV zUg0YC6fqx<*Of5he`YkaoVhPq;+|7d=`HT!%A7sBvS1F$#F|qR&o}U&nU+?QHvL#Y nE8V)tQ||UwRF#%HqkCQBDm*1M&1QZc5?JJ!Q&Qo-Qe69Ao8Z#4 delta 8555 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%0A}>4#1EBwT9JB8g~b+9^Ml zbQj!5j3C`qh30w`yHMtjLrvL1op-s(JV0dw;w1TST!87O?k!^h<+>gt0%{jH+WUsj zEVt5Tlo!q@FLul=Y62QMiku~- zwOfZz^Nt&IPo=ZG+Bsu-iL>01T~JvyyJC7tRb}-wXURMJW*0g=O)G1?v)&H~ALE=} zQdz2|jv)+P?x}NM%pK%aSsOjBzgO+f@t^v*C+Elc+IP8^\n" "Language-Team: LANGUAGE \n" @@ -37,22 +37,23 @@ msgstr "Vom" msgid "To" msgstr "Bis" -#: analysis/forms.py:47 compensation/forms/forms.py:94 +#: analysis/forms.py:47 compensation/forms/forms.py:93 #: compensation/templates/compensation/detail/eco_account/view.html:58 #: compensation/templates/compensation/report/eco_account/report.html:16 #: ema/templates/ema/detail/view.html:42 #: ema/templates/ema/report/report.html:16 intervention/forms/forms.py:101 #: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/report/report.html:37 +#: intervention/utils/quality.py:49 msgid "Conservation office" msgstr "Eintragungsstelle" -#: analysis/forms.py:49 compensation/forms/forms.py:96 +#: analysis/forms.py:49 compensation/forms/forms.py:95 msgid "Select the responsible office" msgstr "Verantwortliche Stelle" -#: analysis/forms.py:58 compensation/forms/forms.py:68 -#: compensation/forms/forms.py:105 compensation/forms/forms.py:156 +#: analysis/forms.py:58 compensation/forms/forms.py:67 +#: compensation/forms/forms.py:104 compensation/forms/forms.py:155 #: intervention/forms/forms.py:63 intervention/forms/forms.py:80 #: intervention/forms/forms.py:96 intervention/forms/forms.py:112 msgid "Click for selection" @@ -298,18 +299,18 @@ msgstr "Vor" msgid "Show only unrecorded" msgstr "Nur unverzeichnete anzeigen" -#: compensation/forms/forms.py:32 compensation/tables.py:25 +#: compensation/forms/forms.py:31 compensation/tables.py:25 #: compensation/tables.py:166 ema/tables.py:28 intervention/forms/forms.py:27 #: intervention/tables.py:23 #: intervention/templates/intervention/detail/includes/compensations.html:30 msgid "Identifier" msgstr "Kennung" -#: compensation/forms/forms.py:35 intervention/forms/forms.py:30 +#: compensation/forms/forms.py:34 intervention/forms/forms.py:30 msgid "Generated automatically" msgstr "Automatisch generiert" -#: compensation/forms/forms.py:44 compensation/tables.py:30 +#: compensation/forms/forms.py:43 compensation/tables.py:30 #: compensation/tables.py:171 #: compensation/templates/compensation/detail/compensation/includes/documents.html:28 #: compensation/templates/compensation/detail/compensation/view.html:31 @@ -329,23 +330,23 @@ msgstr "Automatisch generiert" msgid "Title" msgstr "Bezeichnung" -#: compensation/forms/forms.py:46 intervention/forms/forms.py:41 +#: compensation/forms/forms.py:45 intervention/forms/forms.py:41 msgid "An explanatory name" msgstr "Aussagekräftiger Titel" -#: compensation/forms/forms.py:50 ema/forms.py:47 ema/forms.py:105 +#: compensation/forms/forms.py:49 ema/forms.py:47 ema/forms.py:105 msgid "Compensation XY; Location ABC" msgstr "Kompensation XY; Flur ABC" -#: compensation/forms/forms.py:56 +#: compensation/forms/forms.py:55 msgid "Fundings" msgstr "Förderungen" -#: compensation/forms/forms.py:59 +#: compensation/forms/forms.py:58 msgid "Select fundings for this compensation" msgstr "Wählen Sie ggf. Fördermittelprojekte" -#: compensation/forms/forms.py:74 compensation/forms/modalForms.py:61 +#: compensation/forms/forms.py:73 compensation/forms/modalForms.py:61 #: compensation/forms/modalForms.py:272 compensation/forms/modalForms.py:367 #: compensation/templates/compensation/detail/compensation/includes/actions.html:34 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34 @@ -364,63 +365,65 @@ msgstr "Wählen Sie ggf. Fördermittelprojekte" msgid "Comment" msgstr "Kommentar" -#: compensation/forms/forms.py:76 intervention/forms/forms.py:181 +#: compensation/forms/forms.py:75 intervention/forms/forms.py:181 msgid "Additional comment" msgstr "Zusätzlicher Kommentar" -#: compensation/forms/forms.py:110 +#: compensation/forms/forms.py:109 #: compensation/templates/compensation/detail/eco_account/view.html:62 #: compensation/templates/compensation/report/eco_account/report.html:20 #: ema/templates/ema/detail/view.html:46 #: ema/templates/ema/report/report.html:20 intervention/forms/forms.py:129 #: intervention/templates/intervention/detail/view.html:60 #: intervention/templates/intervention/report/report.html:41 +#: intervention/utils/quality.py:42 msgid "Conservation office file number" msgstr "Aktenzeichen Eintragungsstelle" -#: compensation/forms/forms.py:116 intervention/forms/forms.py:135 +#: compensation/forms/forms.py:115 intervention/forms/forms.py:135 msgid "ETS-123/ABC.456" msgstr "" -#: compensation/forms/forms.py:122 +#: compensation/forms/forms.py:121 msgid "Eco-account handler" msgstr "Maßnahmenträger" -#: compensation/forms/forms.py:126 +#: compensation/forms/forms.py:125 msgid "Who handles the eco-account" msgstr "Wer für die Herrichtung des Ökokontos verantwortlich ist" -#: compensation/forms/forms.py:129 intervention/forms/forms.py:148 +#: compensation/forms/forms.py:128 intervention/forms/forms.py:148 msgid "Company Mustermann" msgstr "Firma Mustermann" -#: compensation/forms/forms.py:147 +#: compensation/forms/forms.py:146 #: compensation/templates/compensation/detail/compensation/view.html:35 #: compensation/templates/compensation/report/compensation/report.html:16 msgid "compensates intervention" msgstr "kompensiert Eingriff" -#: compensation/forms/forms.py:149 +#: compensation/forms/forms.py:148 msgid "Select the intervention for which this compensation compensates" msgstr "Wählen Sie den Eingriff, für den diese Kompensation bestimmt ist" -#: compensation/forms/forms.py:174 +#: compensation/forms/forms.py:173 msgid "New compensation" msgstr "Neue Kompensation" -#: compensation/forms/forms.py:232 +#: compensation/forms/forms.py:231 msgid "Edit compensation" msgstr "Bearbeite Kompensation" -#: compensation/forms/forms.py:291 +#: compensation/forms/forms.py:290 msgid "Available Surface" msgstr "Verfügbare Fläche" -#: compensation/forms/forms.py:294 +#: compensation/forms/forms.py:293 msgid "The amount that can be used for deductions" msgstr "Die für Abbuchungen zur Verfügung stehende Menge" -#: compensation/forms/forms.py:303 +#: compensation/forms/forms.py:302 +#: compensation/templates/compensation/detail/eco_account/view.html:66 msgid "Agreement date" msgstr "Vereinbarungsdatum" @@ -876,7 +879,7 @@ msgid "Recorded on " msgstr "Verzeichnet am" #: compensation/templates/compensation/detail/compensation/view.html:71 -#: compensation/templates/compensation/detail/eco_account/view.html:70 +#: compensation/templates/compensation/detail/eco_account/view.html:74 #: compensation/templates/compensation/report/compensation/report.html:24 #: compensation/templates/compensation/report/eco_account/report.html:28 #: ema/templates/ema/detail/view.html:54 @@ -885,7 +888,7 @@ msgid "Funded by" msgstr "Gefördert mit" #: compensation/templates/compensation/detail/compensation/view.html:79 -#: compensation/templates/compensation/detail/eco_account/view.html:78 +#: compensation/templates/compensation/detail/eco_account/view.html:82 #: compensation/templates/compensation/report/compensation/report.html:31 #: compensation/templates/compensation/report/eco_account/report.html:35 #: compensation/templates/compensation/report/eco_account/report.html:49 @@ -897,7 +900,7 @@ msgid "None" msgstr "-" #: compensation/templates/compensation/detail/compensation/view.html:84 -#: compensation/templates/compensation/detail/eco_account/view.html:83 +#: compensation/templates/compensation/detail/eco_account/view.html:87 #: compensation/templates/compensation/report/compensation/report.html:37 #: compensation/templates/compensation/report/eco_account/report.html:54 #: ema/templates/ema/detail/view.html:67 @@ -908,7 +911,7 @@ msgid "Last modified" msgstr "Zuletzt bearbeitet" #: compensation/templates/compensation/detail/compensation/view.html:92 -#: compensation/templates/compensation/detail/eco_account/view.html:91 +#: compensation/templates/compensation/detail/eco_account/view.html:95 #: ema/templates/ema/detail/view.html:82 intervention/forms/modalForms.py:40 #: intervention/templates/intervention/detail/view.html:116 msgid "Shared with" @@ -962,6 +965,7 @@ msgstr "Keine Flächenmenge für Abbuchungen eingegeben. Bitte bearbeiten." #: compensation/templates/compensation/detail/eco_account/view.html:57 #: compensation/templates/compensation/detail/eco_account/view.html:61 #: compensation/templates/compensation/detail/eco_account/view.html:65 +#: compensation/templates/compensation/detail/eco_account/view.html:69 #: ema/templates/ema/detail/view.html:41 ema/templates/ema/detail/view.html:45 #: ema/templates/ema/detail/view.html:49 #: intervention/templates/intervention/detail/view.html:30 @@ -974,10 +978,10 @@ msgstr "Keine Flächenmenge für Abbuchungen eingegeben. Bitte bearbeiten." #: intervention/templates/intervention/detail/view.html:63 #: intervention/templates/intervention/detail/view.html:95 #: intervention/templates/intervention/detail/view.html:99 -msgid "Missing" -msgstr "Fehlt" +msgid "missing" +msgstr "fehlt" -#: compensation/templates/compensation/detail/eco_account/view.html:66 +#: compensation/templates/compensation/detail/eco_account/view.html:70 #: compensation/templates/compensation/report/eco_account/report.html:24 #: ema/templates/ema/detail/view.html:50 #: ema/templates/ema/report/report.html:24 @@ -1017,42 +1021,42 @@ msgstr "Kompensation {} hinzugefügt" msgid "Compensation {} edited" msgstr "Kompensation {} bearbeitet" -#: compensation/views/compensation_views.py:213 -#: compensation/views/eco_account_views.py:287 ema/views.py:175 -#: intervention/views.py:437 +#: compensation/views/compensation_views.py:216 +#: compensation/views/eco_account_views.py:290 ema/views.py:178 +#: intervention/views.py:447 msgid "Log" msgstr "Log" -#: compensation/views/compensation_views.py:234 +#: compensation/views/compensation_views.py:237 msgid "Compensation removed" msgstr "Kompensation entfernt" -#: compensation/views/compensation_views.py:253 -#: compensation/views/eco_account_views.py:386 ema/views.py:328 -#: intervention/views.py:126 +#: compensation/views/compensation_views.py:256 +#: compensation/views/eco_account_views.py:389 ema/views.py:331 +#: intervention/views.py:127 msgid "Document added" msgstr "Dokument hinzugefügt" -#: compensation/views/compensation_views.py:309 -#: compensation/views/eco_account_views.py:330 ema/views.py:272 +#: compensation/views/compensation_views.py:321 +#: compensation/views/eco_account_views.py:333 ema/views.py:275 msgid "State added" msgstr "Zustand hinzugefügt" -#: compensation/views/compensation_views.py:328 -#: compensation/views/eco_account_views.py:349 ema/views.py:291 +#: compensation/views/compensation_views.py:340 +#: compensation/views/eco_account_views.py:352 ema/views.py:294 msgid "Action added" msgstr "Maßnahme hinzugefügt" -#: compensation/views/compensation_views.py:347 -#: compensation/views/eco_account_views.py:368 ema/views.py:310 +#: compensation/views/compensation_views.py:359 +#: compensation/views/eco_account_views.py:371 ema/views.py:313 msgid "Deadline added" msgstr "Frist/Termin hinzugefügt" -#: compensation/views/compensation_views.py:366 +#: compensation/views/compensation_views.py:378 msgid "State removed" msgstr "Zustand gelöscht" -#: compensation/views/compensation_views.py:385 +#: compensation/views/compensation_views.py:397 msgid "Action removed" msgstr "Maßnahme entfernt" @@ -1064,25 +1068,25 @@ msgstr "Ökokonto {} hinzugefügt" msgid "Eco-Account {} edited" msgstr "Ökokonto {} bearbeitet" -#: compensation/views/eco_account_views.py:237 +#: compensation/views/eco_account_views.py:240 msgid "Eco-account removed" msgstr "Ökokonto entfernt" -#: compensation/views/eco_account_views.py:264 +#: compensation/views/eco_account_views.py:267 msgid "Deduction removed" msgstr "Abbuchung entfernt" -#: compensation/views/eco_account_views.py:307 ema/views.py:249 -#: intervention/views.py:477 +#: compensation/views/eco_account_views.py:310 ema/views.py:252 +#: intervention/views.py:487 msgid "{} unrecorded" msgstr "{} entzeichnet" -#: compensation/views/eco_account_views.py:307 ema/views.py:249 -#: intervention/views.py:477 +#: compensation/views/eco_account_views.py:310 ema/views.py:252 +#: intervention/views.py:487 msgid "{} recorded" msgstr "{} verzeichnet" -#: compensation/views/eco_account_views.py:443 intervention/views.py:459 +#: compensation/views/eco_account_views.py:455 intervention/views.py:469 msgid "Deduction added" msgstr "Abbuchung hinzugefügt" @@ -1126,11 +1130,11 @@ msgstr "Ersatzzahlungsmaßnahme" msgid "EMA {} added" msgstr "EMA {} hinzugefügt" -#: ema/views.py:202 +#: ema/views.py:205 msgid "EMA {} edited" msgstr "EMA {} bearbeitet" -#: ema/views.py:232 +#: ema/views.py:235 msgid "EMA removed" msgstr "EMA entfernt" @@ -1157,6 +1161,7 @@ msgstr "Bauvorhaben XY; Flur ABC" #: intervention/forms/forms.py:51 #: intervention/templates/intervention/detail/view.html:35 #: intervention/templates/intervention/report/report.html:16 +#: intervention/utils/quality.py:82 msgid "Process type" msgstr "Verfahrenstyp" @@ -1167,12 +1172,14 @@ msgstr "Mehrfachauswahl möglich" #: intervention/forms/forms.py:85 #: intervention/templates/intervention/detail/view.html:48 #: intervention/templates/intervention/report/report.html:29 +#: intervention/utils/quality.py:46 msgid "Registration office" msgstr "Zulassungsbehörde" #: intervention/forms/forms.py:117 #: intervention/templates/intervention/detail/view.html:52 #: intervention/templates/intervention/report/report.html:33 +#: intervention/utils/quality.py:39 msgid "Registration office file number" msgstr "Aktenzeichen Zulassungsbehörde" @@ -1183,6 +1190,7 @@ msgstr "" #: intervention/forms/forms.py:141 #: intervention/templates/intervention/detail/view.html:64 #: intervention/templates/intervention/report/report.html:45 +#: intervention/utils/quality.py:52 msgid "Intervention handler" msgstr "Eingriffsverursacher" @@ -1193,6 +1201,7 @@ msgstr "Wer führt den Eingriff durch" #: intervention/forms/forms.py:154 #: intervention/templates/intervention/detail/view.html:96 #: intervention/templates/intervention/report/report.html:83 +#: intervention/utils/quality.py:73 msgid "Registration date" msgstr "Datum Zulassung bzw. Satzungsbeschluss" @@ -1302,34 +1311,6 @@ msgstr "" "Das Ökokonto {} hat für eine Abbuchung von {} m² nicht ausreichend " "Restfläche. Es stehen noch {} m² zur Verfügung." -#: intervention/models.py:326 -msgid "Registration office file number missing" -msgstr "Aktenzeichen Zulassungsbehörde fehlt" - -#: intervention/models.py:329 -msgid "Conservation office file number missing" -msgstr "Aktenzeichen Naturschutzbehörde fehlt" - -#: intervention/models.py:332 -msgid "Responsible data missing" -msgstr "Daten zu Verantwortlichen fehlen" - -#: intervention/models.py:346 -msgid "Revocation exists" -msgstr "Widerspruch liegt vor" - -#: intervention/models.py:349 -msgid "Registration date missing" -msgstr "Datum Zulassung bzw. Satzungsbeschluss fehlt" - -#: intervention/models.py:352 -msgid "Binding on missing" -msgstr "Datum Bestandskraft fehlt" - -#: intervention/models.py:354 -msgid "Legal data missing" -msgstr "Rechtliche Daten fehlen" - #: intervention/tables.py:45 #: intervention/templates/intervention/detail/includes/revocation.html:8 #: intervention/templates/intervention/detail/includes/revocation.html:57 @@ -1404,61 +1385,80 @@ msgstr "Abbuchungen von Ökokonten" msgid "Exist" msgstr "Vorhanden" -#: intervention/views.py:79 +#: intervention/utils/quality.py:55 +msgid "Responsible data" +msgstr "Daten zu den verantwortlichen Stellen" + +#: intervention/utils/quality.py:70 +msgid "Revocation exists" +msgstr "Widerspruch liegt vor" + +#: intervention/utils/quality.py:76 +msgid "Binding date" +msgstr "Datum Bestandskraft" + +#: intervention/utils/quality.py:79 +msgid "Laws" +msgstr "Gesetze" + +#: intervention/utils/quality.py:84 +msgid "Legal data" +msgstr "Rechtliche Daten" + +#: intervention/utils/quality.py:98 +msgid "No compensation of any type found (Compensation, Payment, Deduction)" +msgstr "Kein Ausgleich jeglicher Art gefunden (Kompensation, Ersatzzahlung, Abbuchung)" + +#: intervention/utils/quality.py:110 intervention/utils/quality.py:112 +#: konova/forms.py:246 templates/form/collapsable/form.html:45 +msgid "Geometry" +msgstr "Geometrie" + +#: intervention/views.py:80 msgid "Intervention {} added" msgstr "Eingriff {} hinzugefügt" -#: intervention/views.py:221 +#: intervention/views.py:231 msgid "This intervention has a revocation from {}" msgstr "Es existiert ein Widerspruch vom {}" -#: intervention/views.py:237 -msgid "" -"Remember: This data has not been shared with you, yet. This means you can " -"only read but can not edit or perform any actions like running a check or " -"recording." -msgstr "" -"Beachten Sie: Diese Daten sind für Sie noch nicht freigegeben worden. Das " -"bedeutet, dass Sie nur lesenden Zugriff hierauf haben und weder bearbeiten, " -"noch Prüfungen durchführen oder verzeichnen können." - -#: intervention/views.py:264 +#: intervention/views.py:274 msgid "Intervention {} edited" msgstr "Eingriff {} bearbeitet" -#: intervention/views.py:296 +#: intervention/views.py:306 msgid "{} removed" msgstr "{} entfernt" -#: intervention/views.py:317 +#: intervention/views.py:327 msgid "Revocation removed" msgstr "Widerspruch entfernt" -#: intervention/views.py:343 +#: intervention/views.py:353 msgid "{} has already been shared with you" msgstr "{} wurde bereits für Sie freigegeben" -#: intervention/views.py:348 +#: intervention/views.py:358 msgid "{} has been shared with you" msgstr "{} ist nun für Sie freigegeben" -#: intervention/views.py:355 +#: intervention/views.py:365 msgid "Share link invalid" msgstr "Freigabelink ungültig" -#: intervention/views.py:376 +#: intervention/views.py:386 msgid "Share settings updated" msgstr "Freigabe Einstellungen aktualisiert" -#: intervention/views.py:395 +#: intervention/views.py:405 msgid "Check performed" msgstr "Prüfung durchgeführt" -#: intervention/views.py:415 +#: intervention/views.py:425 msgid "Revocation added" msgstr "Widerspruch hinzugefügt" -#: intervention/views.py:482 +#: intervention/views.py:492 msgid "There are errors on this intervention:" msgstr "Es liegen Fehler in diesem Eingriff vor:" @@ -1499,10 +1499,6 @@ msgstr "Löschen" msgid "You are about to remove {} {}" msgstr "Sie sind dabei {} {} zu löschen" -#: konova/forms.py:246 templates/form/collapsable/form.html:45 -msgid "Geometry" -msgstr "Geometrie" - #: konova/forms.py:322 msgid "Are you sure?" msgstr "Sind Sie sicher?" @@ -1653,6 +1649,16 @@ msgid "This data is not shared with you" msgstr "Diese Daten sind für Sie nicht freigegeben" #: konova/utils/message_templates.py:16 +msgid "" +"Remember: This data has not been shared with you, yet. This means you can " +"only read but can not edit or perform any actions like running a check or " +"recording." +msgstr "" +"Beachten Sie: Diese Daten sind für Sie noch nicht freigegeben worden. Das " +"bedeutet, dass Sie nur lesenden Zugriff hierauf haben und weder bearbeiten, " +"noch Prüfungen durchführen oder verzeichnen können." + +#: konova/utils/message_templates.py:17 msgid "You need to be part of another user group." msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!" @@ -3113,219 +3119,4 @@ msgstr "" #: venv/lib/python3.7/site-packages/fontawesome_5/fields.py:16 msgid "A fontawesome icon field" -msgstr "" - -#~ msgid "After" -#~ msgstr "Nach" - -#~ msgid "Total interventions" -#~ msgstr "Insgesamt" - -#~ msgid "Amount total" -#~ msgstr "Anzahl insgesamt" - -#~ msgid "Amount checked" -#~ msgstr "Anzahl geprüft" - -#~ msgid "Amount recorded" -#~ msgstr "Anzahl verzeichnet" - -#~ msgid "Funding by..." -#~ msgstr "Gefördert mit..." - -#~ msgid "Invalid input" -#~ msgstr "Eingabe fehlerhaft" - -#~ msgid "Map" -#~ msgstr "Karte" - -#~ msgid "Where does the intervention take place" -#~ msgstr "Wo findet der Eingriff statt" - -#~ msgid "Which intervention type is this" -#~ msgstr "Welcher Eingriffstyp" - -#~ msgid "Based on which law" -#~ msgstr "Basiert auf welchem Recht" - -#~ msgid "Data provider" -#~ msgstr "Datenbereitsteller" - -#~ msgid "Who provides the data for the intervention" -#~ msgstr "Wer stellt die Daten für den Eingriff zur Verfügung" - -#~ msgid "Organization" -#~ msgstr "Organisation" - -#~ msgid "Data provider details" -#~ msgstr "Datenbereitsteller Details" - -#~ msgid "Further details" -#~ msgstr "Weitere Details" - -#~ msgid "Files" -#~ msgstr "Dateien" - -#~ msgid "Transfer note" -#~ msgstr "Verwendungszweck" - -#~ msgid "Note for money transfer" -#~ msgstr "Verwendungszweck für Überweisung" - -#~ msgid "Transfer comment" -#~ msgstr "Verwendungszweck" - -#~ msgid "Edit {}" -#~ msgstr "Bearbeite {}" - -#~ msgid "Delete {}" -#~ msgstr "Lösche {}" - -#~ msgid "Actions" -#~ msgstr "Aktionen" - -#~ msgid "Missing surfaces: " -#~ msgstr "Fehlende Flächen: " - -#~ msgid "This will remove '{}'. Are you sure?" -#~ msgstr "Hiermit wird '{}' gelöscht. Sind Sie sicher?" - -#~ msgid "Your own" -#~ msgstr "Eigene" - -#~ msgid "Quickstart" -#~ msgstr "Schnellstart" - -#~ msgid "Logged in as" -#~ msgstr "Eingeloggt als" - -#~ msgid "Last login on" -#~ msgstr "Zuletzt eingeloggt am" - -#~ msgid "Add new eco account" -#~ msgstr "Neues Ökokonto hinzufügen" - -#~ msgid "Delete EMA" -#~ msgstr "Lösche EMA" - -#~ msgid "Menu" -#~ msgstr "Menü" - -#~ msgid "Process" -#~ msgstr "Vorgang" - -#~ msgid "Process management" -#~ msgstr "Vorgangsverwaltung" - -#~ msgid "New process" -#~ msgstr "Neuer Vorgang" - -#~ msgid "Intervention management" -#~ msgstr "Eingriffsverwaltung" - -#~ msgid "Show intervention" -#~ msgstr "Zeige Eingriffe" - -#~ msgid "Eco-account management" -#~ msgstr "Ökokontoverwaltung" - -#~ msgid "Show eco-accounts" -#~ msgstr "Zeige Ökokonten" - -#~ msgid "You are currently working as " -#~ msgstr "Sie arbeiten gerade als " - -#~ msgid "Change..." -#~ msgstr "Ändern..." - -#~ msgid "" -#~ "Interventions must be part of a process. Please fill in the missing data " -#~ "for the process" -#~ msgstr "" -#~ "Eingriffe müssen zu einem Vorgang gehören. Bitte geben SIe die fehlenden " -#~ "Daten für den Vorgang ein." - -#~ msgid "You are working as" -#~ msgstr "Sie arbeiten gerade als " - -#~ msgid "Role changed" -#~ msgstr "Rolle geändert" - -#~ msgid "Official" -#~ msgstr "Amtlich" - -#~ msgid "Company" -#~ msgstr "Firma" - -#~ msgid "NGO" -#~ msgstr "NGO" - -#~ msgid "Licencing Authority" -#~ msgstr "Zulassungsbehörde" - -#~ msgid "Proper title of the process" -#~ msgstr "Titel des Vorgangs" - -#~ msgid "Which process type is this" -#~ msgstr "Welcher Vorgangstyp" - -#~ msgid "Licencing document identifier" -#~ msgstr "Aktenzeichen Zulassungsbehörde" - -#~ msgid "Comment licensing authority" -#~ msgstr "Kommentar Zulassungsbehörde" - -#~ msgid "Registration document identifier" -#~ msgstr "Aktenzeichen Eintragungsstelle" - -#~ msgid "Edit process" -#~ msgstr "Vorgang bearbeiten" - -#~ msgid "private" -#~ msgstr "privat" - -#~ msgid "accessible" -#~ msgstr "bereitgestellt" - -#~ msgid "licensed" -#~ msgstr "genehmigt" - -#~ msgid "official" -#~ msgstr "bestandskräftig" - -#~ msgid "" -#~ "A process is based on an intervention. Please fill in the missing data " -#~ "for this intervention" -#~ msgstr "" -#~ "Ein Vorgang basiert immer auf einem Eingriff. Bitte geben Sie die " -#~ "fehlenden Daten für diesen Eingriff ein" - -#~ msgid "{} status changed from {} to {}" -#~ msgstr "{} Status von {} auf {} geändert" - -#~ msgid "Process {} added" -#~ msgstr "Vorgang {} hinzugefügt" - -#~ msgid "Current role" -#~ msgstr "Aktuelle Rolle" - -#~ msgid "Object title" -#~ msgstr "Objekt Titel" - -#~ msgid "Object identifier" -#~ msgstr "Objekt Identifikator" - -#~ msgid "Open process" -#~ msgstr "Vorgang öffnen" - -#~ msgid "Delete process" -#~ msgstr "Vorgang löschen" - -#~ msgid "Licensing authority document identifier" -#~ msgstr "Aktenzeichen Zulassungsbehörde" - -#~ msgid "Registration office document identifier" -#~ msgstr "Aktenzeichen Eintragungsstelle" - -#~ msgid "You have been logged out" -#~ msgstr "Sie wurden ausgeloggt" +msgstr "" \ No newline at end of file -- 2.38.5 From 4c7efdb8009f0e4dae2a15e34e68a2b90f8d120a Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 25 Oct 2021 13:21:27 +0200 Subject: [PATCH 2/7] #36 Quality checks * moves geometry check logic to upper class --- intervention/utils/quality.py | 13 ------------- konova/utils/quality.py | 12 ++++++++++++ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/intervention/utils/quality.py b/intervention/utils/quality.py index 72ed2a7..7896000 100644 --- a/intervention/utils/quality.py +++ b/intervention/utils/quality.py @@ -97,16 +97,3 @@ class InterventionQualityChecker(AbstractQualityChecker): self.messages.append( _("No compensation of any type found (Compensation, Payment, Deduction)") ) - - def _check_geometry(self): - """ Checks on the geometry - - Returns: - - """ - try: - geometry_obj = self.obj.geometry - if geometry_obj.geom.empty: - self._add_missing_attr_name(_("Geometry")) - except AttributeError: - self._add_missing_attr_name(_("Geometry")) diff --git a/konova/utils/quality.py b/konova/utils/quality.py index b59c327..adf76d4 100644 --- a/konova/utils/quality.py +++ b/konova/utils/quality.py @@ -32,3 +32,15 @@ class AbstractQualityChecker: missing = _('missing') self.messages.append(f"{attr_name} {missing}") + def _check_geometry(self): + """ Checks on the geometry + + Returns: + + """ + try: + geometry_obj = self.obj.geometry + if geometry_obj.geom.empty: + self._add_missing_attr_name(_("Geometry")) + except AttributeError: + self._add_missing_attr_name(_("Geometry")) -- 2.38.5 From 619f2110e47091aa77579675014d49083e228f04 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 25 Oct 2021 13:44:54 +0200 Subject: [PATCH 3/7] #36 Quality checks * adds quality check logic for Compensations with CompensationQUalityChecker * adds compensation quality checking to checking routine of RunCheckModalForm.is_valid() * adds/updates translations --- compensation/models.py | 34 +++++++++++- compensation/utils/quality.py | 48 +++++++++++++++++ ema/utils/quality.py | 20 +++++++ intervention/forms/modalForms.py | 10 +++- locale/de/LC_MESSAGES/django.mo | Bin 26682 -> 26776 bytes locale/de/LC_MESSAGES/django.po | 90 +++++++++++++++++-------------- 6 files changed, 159 insertions(+), 43 deletions(-) create mode 100644 compensation/utils/quality.py create mode 100644 ema/utils/quality.py diff --git a/compensation/models.py b/compensation/models.py index d2d18be..5367b2e 100644 --- a/compensation/models.py +++ b/compensation/models.py @@ -19,6 +19,7 @@ from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES CODELIST_COMPENSATION_FUNDING_ID from compensation.managers import CompensationStateManager, EcoAccountDeductionManager, CompensationActionManager, \ EcoAccountManager, CompensationManager +from compensation.utils.quality import CompensationQualityChecker from intervention.models import Intervention, ResponsibilityData, LegalData from konova.models import BaseObject, BaseResource, Geometry, UuidModel, AbstractDocument, \ generate_document_file_upload_path @@ -163,13 +164,42 @@ class AbstractCompensation(BaseObject): class Meta: abstract = True - def get_surface(self) -> float: + def get_surface_after_states(self) -> float: """ Calculates the compensation's/account's surface Returns: sum_surface (float) """ - return self.after_states.all().aggregate(Sum("surface"))["surface__sum"] + return self._calc_surface(self.after_states.all()) + + def get_surface_before_states(self) -> float: + """ Calculates the compensation's/account's surface + + Returns: + sum_surface (float) + """ + return self._calc_surface(self.before_states.all()) + + def _calc_surface(self, qs: QuerySet): + """ Calculates the surface sum of a given queryset + + Args: + qs (QuerySet): The queryset containing CompensationState entries + + Returns: + + """ + return qs.aggregate(Sum("surface"))["surface__sum"] or 0 + + def quality_check(self) -> CompensationQualityChecker: + """ Performs data quality check + + Returns: + checker (CompensationQualityChecker): Holds validity data and error messages + """ + checker = CompensationQualityChecker(self) + checker.run_check() + return checker class Compensation(AbstractCompensation): diff --git a/compensation/utils/quality.py b/compensation/utils/quality.py new file mode 100644 index 0000000..0e3c2cf --- /dev/null +++ b/compensation/utils/quality.py @@ -0,0 +1,48 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 25.10.21 + +""" +from django.utils.translation import gettext_lazy as _, pgettext_lazy as _con +from konova.utils.quality import AbstractQualityChecker + + +class CompensationQualityChecker(AbstractQualityChecker): + def run_check(self): + """ Perform all defined data checks + + Returns: + + """ + self._check_states() + self._check_actions() + self._check_geometry() + self.valid = len(self.messages) == 0 + + def _check_states(self): + """ Checks data quality for related CompensationState objects + + Returns: + + """ + after_states = self.obj.get_surface_after_states() + before_states = self.obj.get_surface_before_states() + if after_states != before_states: + self.messages.append( + _("States unequal") + ) + if before_states == 0: + self._add_missing_attr_name(_("States before")) + if after_states == 0: + self._add_missing_attr_name(_("States after")) + + def _check_actions(self): + """ Checks data quality for related CompensationState objects + + Returns: + + """ + if not self.obj.actions.all(): + self._add_missing_attr_name(_con("Compensation", "Actions")) diff --git a/ema/utils/quality.py b/ema/utils/quality.py new file mode 100644 index 0000000..8c57f51 --- /dev/null +++ b/ema/utils/quality.py @@ -0,0 +1,20 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 25.10.21 + +""" +from konova.utils.quality import AbstractQualityChecker + + +class EmaQualityChecker(AbstractQualityChecker): + def run_check(self): + """ Perform all defined data checks + + Returns: + + """ + + self._check_geometry() + self.valid = len(self.messages) == 0 diff --git a/intervention/forms/modalForms.py b/intervention/forms/modalForms.py index 4f8fa75..6942596 100644 --- a/intervention/forms/modalForms.py +++ b/intervention/forms/modalForms.py @@ -214,6 +214,14 @@ class RunCheckModalForm(BaseModalForm): "checked_intervention", msg ) + comps = self.instance.compensations.all() + for comp in comps: + checker = comp.quality_check() + for msg in checker.messages: + self.add_error( + "checked_comps", + f"{comp.identifier}: {msg}" + ) return super_result and checker.valid def save(self): @@ -336,7 +344,7 @@ class NewDeductionModalForm(BaseModalForm): return False # Calculate valid surface - sum_surface = acc.get_surface() + sum_surface = acc.get_surface_after_states() sum_surface_deductions = acc.get_deductions_surface() rest_surface = sum_surface - sum_surface_deductions form_surface = float(self.cleaned_data["surface"]) diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index a992cbb136e1f7e893caa5e4795d15c90460558b..f84bd1867b5720a30a73b2e0f99650fce62d0e7e 100644 GIT binary patch delta 8100 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 F{{b&OhfM$g delta 8015 zcmY+}33yId9>?+XBAY~nh(xwGiVz_Yv5Q@zc7oWKh^@7zqr`fxwNx#AM{8?KwNb5V zQB@48rgUm=(~a6XmZ9ySqeVxV?=SawX68Qq`F+nAa84#sbV`e27Qp;6%?4$yn>nhwwyn3o zvedg_I1WMepNJZN5o*3w#dXJ+H|>oNunad2AuBVdQ7b=(iFgY&KqQrtn26d*P1Hnb zsDU$4<78t+9D+eO8MV;a=#M@OVSclQLTTKj2Hb8vfd15vVQu^p$+q!ScXwD71E|+S z{xKQ+Q3;2kHZT*lu*KF_F@XAZ)W-Ipqa7WmpozanrRqBB!H1|bEMLQIuY=k_CPrXy z)DFj@c03OQ@I}jK&k_#p^XVe@zgSEm0HqL}g@z zy+0O}xo5Ey&O+^MK59X$PzxzUEo3JK;bGJ~r;^CO2KS)%X zcC;Cl@?Ez51nRRri#ob{sENwda-XY$!PM&@r)e@!86AfFW1Irp@FsSpVK*w3LA-I= zK`1J9k*EdMur@)Zx)ZA3VAMuNVH+He>c0d1@KbyLD60P#7^Cn1ECo$?*WP%5`n>#7 z+yR47_rp*tk3gj^2{lkUhG2%ZJt~7a7>OfL{br&TxBxZY(qcJ(ABFBTtipPD19jHk zRAU-oO^nA}Ou$*Fmv#echX+s#IE|X{JnATZLmfqM9rws8V;Sm=P?^iZ0Db>`DQHEx z))AKDKyj#}tBv};8=#J=H7XPBQP1bt z`Y?MxAJxAA^}I9BHoSm(a5YxILR2R9VmKa0FJ8h|(L;VU;d)fcH=!o{2>A^%hf&Y{ zf?BYDL)VI^j3*-FJElGbP23JOU{6$P`lANUvra_4O!H9#F1PLLQ48IM{0(gmVR^ic zI>HC2m(;(JyW`TRcPAYEncqZF&`Q15bYzpJ9V%5bPy;W*iufKz;$e)!^VkCKqJ9?| zHa4ai_ChVxhwX49D&;?-j{FXmW`6TK1+CbxiTk!jp(aW}Eg%y$P?Fc)j#64VjywjQ%yz~Zj}wIF|96!nWjwI@5a(8Av6f!fIk>m<}y@Eq#1c^Nf8 zAu4mbQK|e3>Sg={wX?IRonEl@Yt|oa`%Tol;oP-1O0{$c473KLQX7iOOeIXkW~j`J zMZHvuQ2kb-QoJ5p^WO_w@f`Krt@v%gldbtJ!O3mh|4vA6%de-t|2Y(TbE9#lG5c@@ zR>rPb{L2RBqf)m9b(ULD6YWHOC5P<&GpNk`WbZ#hEx1fO_b;nvsH5zI%G9LdcE^}y zw!_=@#;2%`=TQrJfcoC!pL8c|fR(6s#t0mVI?EZT&u|5*e<3F0e$>KlpkB^DP)Amx zJ^h&91X9qMC!o%{4r*tuP^s;MnjjB#wv%mrnspfl(Z138u5}mcs19NxoR+k4p6t48k?21-^kglAWmjN3b*&p>}owm7y!B3_U_U7tzrj zHxZ+$x9Q0F>#ZI{Lunj~T1bI)IclP}FbVfyJYGhfVaZPJTON!4)T^Qvl#E(HBh*CM zsLYMUK+LyJ?L_{y;<+>^HH++x^{4?hqmJef>IlBH_pe!RVNcrc<0|aZ*&XK^>dYTv zFqZ4$W*`o=pcK?X+B>$8jY@HU>u}pX9*Z-AO678UzYvwN_fbc<7ybC`E@24uYhB$1 z-$7+Cu$%jQH0rrJs0}+!DQKtJsENkd4)ah8T82vfYSci7Fb%&#?J%G_UjRm<2A+d@ zXI?;k4Qo*oy^qS^5!Bap7Riib?o-f%e%bs6U>IuP4yXkTw2s68>iMWlOhFypGSq}C zQNM^AQT+;0XTB91;&u$h8>kH3$1vtM{yp3qkyxG^iKq!0qZZH=HDF)Vgt@5icqH)~r{U@R}^1Ss`RR3+L=RZO%^cXstxQK#Mbp`cSUPrb6g4%J(9M>RJ zzp|*eIvi`F7gMkU>IkNwCY+91;9S(_x)Ak)v;j5Fz8w4gAEZG$KZW|-uAox%E0)7j zz1?@DBI>Lwqwc5LdUMo*I$;;=gLHB80h4uv!de_$4- z_A{m~PC_kgGio7wuq7TxO%&SSJ*p^-rd}DfkPK8N+hQd4Mg3ytqcXW1weZ(bN8@a# zptIVAO6`7(z+LlqN1KMN9SW@}XvgzW@4`CN8J)o9cpf!iT&}yrWYjNMJ=AlpFdqA06`YKkU@dAx zTTq!fh&qzbQO}=4Cx*fe3RJD>%Dtn-I;9v>di2A#s5S99Es0HlBl6b_nA4T>5 z3boU3?fpxrg48U|-Z;INW(}IG|xP!eh7z3#1p#~gn+b5s~oQRrms%@W*>Nnrk z7o$?W6szGH)Gyt~=*3&8&pK>WaX-g+DX1YCJ@^Un67hg2O+z%Hv)8qh(Ep6+iaErO zL|f_&aU!9Kx>0`-bMW!ikMaU4^9g-%&rtsg?`f$IDezafY392h<#qm`lxH99Wqp#i z%9QmHKE5W|d&_7Dq5Q7BF&rmS??j~AK0n)gb8J1us^%_~N29)zIv(@1iLp1MP+$Kw zB9_Rfu3z+)m_Q66G6^O5f3I^?_^mF!KI6|@wyf`}G5wPWeuK>wpC`JCGnCqI)EW?L z30);<%O!?VoZ*xV@mX7sv{tw3FFsvesaGL-_{PRY#*Lzs?%ptQl>1QbjsC>%K2HF4Ad5kHOT26}SEOj~cXhC#Dk)5lZwV9$(=U3W(vfHNz+H5w^x4+wZT`-z0R6 zr0vfbVejQr?!sT>cjF>F2YhAXt7OjNPKdg4wIOEMo)szAqr3%cq28wvcmh8rYEv#C zni77#XXCxjL0X?6{!UCICUZyEOw7Yg#WiF8jeYFBvudOKG*OqRM>SV%T>o@26=`oo z%%t8Nb!{YmC8kktKy1*j-*Fl`6E}&=L~mjiQHSVHr@J^8b&bbtVk_lDBGtCHzy#`t zh{MF=>js6}wi1ffiQUBO#B81k^Y~u$Mte^A-t|^byGrBZt0{#6bZB84{H^D)KJB_L z`TP>RPI+5X%Ttt7@I#_K=#58GH+Y5)KL diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index 5adae75..a299554 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-25 12:54+0200\n" +"POT-Creation-Date: 2021-10-25 13:37+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -44,7 +44,7 @@ msgstr "Bis" #: ema/templates/ema/report/report.html:16 intervention/forms/forms.py:101 #: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/report/report.html:37 -#: intervention/utils/quality.py:49 +#: intervention/utils/quality.py:51 msgid "Conservation office" msgstr "Eintragungsstelle" @@ -209,7 +209,7 @@ msgstr "Abbuchungen" #: compensation/templates/compensation/detail/eco_account/includes/states-before.html:36 #: ema/templates/ema/detail/includes/states-after.html:36 #: ema/templates/ema/detail/includes/states-before.html:36 -#: intervention/forms/modalForms.py:274 +#: intervention/forms/modalForms.py:282 msgid "Surface" msgstr "Fläche" @@ -272,7 +272,7 @@ msgid "Type" msgstr "Typ" #: analysis/templates/analysis/reports/includes/old_data/amount.html:24 -#: intervention/forms/modalForms.py:285 intervention/forms/modalForms.py:292 +#: intervention/forms/modalForms.py:293 intervention/forms/modalForms.py:300 #: intervention/tables.py:88 #: intervention/templates/intervention/detail/view.html:19 #: konova/templates/konova/home.html:11 templates/navbars/navbar.html:22 @@ -282,7 +282,7 @@ msgstr "Eingriff" #: analysis/templates/analysis/reports/includes/old_data/amount.html:34 #: compensation/tables.py:224 #: compensation/templates/compensation/detail/eco_account/view.html:19 -#: intervention/forms/modalForms.py:258 intervention/forms/modalForms.py:265 +#: intervention/forms/modalForms.py:266 intervention/forms/modalForms.py:273 #: konova/templates/konova/home.html:88 templates/navbars/navbar.html:34 msgid "Eco-account" msgstr "Ökokonto" @@ -376,7 +376,7 @@ msgstr "Zusätzlicher Kommentar" #: ema/templates/ema/report/report.html:20 intervention/forms/forms.py:129 #: intervention/templates/intervention/detail/view.html:60 #: intervention/templates/intervention/report/report.html:41 -#: intervention/utils/quality.py:42 +#: intervention/utils/quality.py:44 msgid "Conservation office file number" msgstr "Aktenzeichen Eintragungsstelle" @@ -482,7 +482,7 @@ msgstr "Biotoptyp" msgid "Select the biotope type" msgstr "Biotoptyp wählen" -#: compensation/forms/modalForms.py:155 intervention/forms/modalForms.py:276 +#: compensation/forms/modalForms.py:155 intervention/forms/modalForms.py:284 msgid "in m²" msgstr "" @@ -592,38 +592,38 @@ msgstr "Geben Sie die Daten der neuen Maßnahme ein" msgid "Added action" msgstr "Maßnahme hinzugefügt" -#: compensation/models.py:82 +#: compensation/models.py:83 msgid "cm" msgstr "" -#: compensation/models.py:83 +#: compensation/models.py:84 msgid "m" msgstr "" -#: compensation/models.py:84 +#: compensation/models.py:85 msgid "km" msgstr "" -#: compensation/models.py:85 +#: compensation/models.py:86 msgid "m²" msgstr "" -#: compensation/models.py:86 +#: compensation/models.py:87 msgid "ha" msgstr "" -#: compensation/models.py:87 +#: compensation/models.py:88 msgid "Pieces" msgstr "Stück" -#: compensation/models.py:329 +#: compensation/models.py:359 msgid "" "Deductable surface can not be larger than existing surfaces in after states" msgstr "" "Die abbuchbare Fläche darf die Gesamtfläche der Zielzustände nicht " "überschreiten" -#: compensation/models.py:336 +#: compensation/models.py:366 msgid "" "Deductable surface can not be smaller than the sum of already existing " "deductions. Please contact the responsible users for the deductions!" @@ -978,7 +978,7 @@ msgstr "Keine Flächenmenge für Abbuchungen eingegeben. Bitte bearbeiten." #: intervention/templates/intervention/detail/view.html:63 #: intervention/templates/intervention/detail/view.html:95 #: intervention/templates/intervention/detail/view.html:99 -msgid "missing" +msgid "Missing" msgstr "fehlt" #: compensation/templates/compensation/detail/eco_account/view.html:70 @@ -1013,6 +1013,10 @@ msgstr "In LANIS öffnen" msgid "Deductions for" msgstr "Abbuchungen für" +#: compensation/utils/quality.py:35 +msgid "States unequal" +msgstr "Ungleiche Zustandsflächenmengen" + #: compensation/views/compensation_views.py:77 msgid "Compensation {} added" msgstr "Kompensation {} hinzugefügt" @@ -1161,7 +1165,7 @@ msgstr "Bauvorhaben XY; Flur ABC" #: intervention/forms/forms.py:51 #: intervention/templates/intervention/detail/view.html:35 #: intervention/templates/intervention/report/report.html:16 -#: intervention/utils/quality.py:82 +#: intervention/utils/quality.py:84 msgid "Process type" msgstr "Verfahrenstyp" @@ -1172,14 +1176,14 @@ msgstr "Mehrfachauswahl möglich" #: intervention/forms/forms.py:85 #: intervention/templates/intervention/detail/view.html:48 #: intervention/templates/intervention/report/report.html:29 -#: intervention/utils/quality.py:46 +#: intervention/utils/quality.py:48 msgid "Registration office" msgstr "Zulassungsbehörde" #: intervention/forms/forms.py:117 #: intervention/templates/intervention/detail/view.html:52 #: intervention/templates/intervention/report/report.html:33 -#: intervention/utils/quality.py:39 +#: intervention/utils/quality.py:41 msgid "Registration office file number" msgstr "Aktenzeichen Zulassungsbehörde" @@ -1190,7 +1194,7 @@ msgstr "" #: intervention/forms/forms.py:141 #: intervention/templates/intervention/detail/view.html:64 #: intervention/templates/intervention/report/report.html:45 -#: intervention/utils/quality.py:52 +#: intervention/utils/quality.py:54 msgid "Intervention handler" msgstr "Eingriffsverursacher" @@ -1201,7 +1205,7 @@ msgstr "Wer führt den Eingriff durch" #: intervention/forms/forms.py:154 #: intervention/templates/intervention/detail/view.html:96 #: intervention/templates/intervention/report/report.html:83 -#: intervention/utils/quality.py:73 +#: intervention/utils/quality.py:75 msgid "Registration date" msgstr "Datum Zulassung bzw. Satzungsbeschluss" @@ -1279,23 +1283,23 @@ msgstr "" "Ich, {} {}, bestätige, dass die notwendigen Kontrollschritte durchgeführt " "wurden:" -#: intervention/forms/modalForms.py:260 +#: intervention/forms/modalForms.py:268 msgid "Only recorded accounts can be selected for deductions" msgstr "Nur verzeichnete Ökokonten können für Abbuchungen verwendet werden." -#: intervention/forms/modalForms.py:287 +#: intervention/forms/modalForms.py:295 msgid "Only shared interventions can be selected" msgstr "Nur freigegebene Eingriffe können gewählt werden" -#: intervention/forms/modalForms.py:300 +#: intervention/forms/modalForms.py:308 msgid "New Deduction" msgstr "Neue Abbuchung" -#: intervention/forms/modalForms.py:301 +#: intervention/forms/modalForms.py:309 msgid "Enter the information for a new deduction from a chosen eco-account" msgstr "Geben Sie die Informationen für eine neue Abbuchung ein." -#: intervention/forms/modalForms.py:334 +#: intervention/forms/modalForms.py:342 msgid "" "Eco-account {} is not recorded yet. You can only deduct from recorded " "accounts." @@ -1303,7 +1307,7 @@ msgstr "" "Ökokonto {} ist noch nicht verzeichnet. Abbuchungen können nur von " "verzeichneten Ökokonten erfolgen." -#: intervention/forms/modalForms.py:347 +#: intervention/forms/modalForms.py:355 msgid "" "The account {} has not enough surface for a deduction of {} m². There are " "only {} m² left" @@ -1385,34 +1389,31 @@ msgstr "Abbuchungen von Ökokonten" msgid "Exist" msgstr "Vorhanden" -#: intervention/utils/quality.py:55 +#: intervention/utils/quality.py:57 msgid "Responsible data" msgstr "Daten zu den verantwortlichen Stellen" -#: intervention/utils/quality.py:70 +#: intervention/utils/quality.py:72 msgid "Revocation exists" msgstr "Widerspruch liegt vor" -#: intervention/utils/quality.py:76 +#: intervention/utils/quality.py:78 msgid "Binding date" msgstr "Datum Bestandskraft" -#: intervention/utils/quality.py:79 +#: intervention/utils/quality.py:81 msgid "Laws" msgstr "Gesetze" -#: intervention/utils/quality.py:84 +#: intervention/utils/quality.py:86 msgid "Legal data" msgstr "Rechtliche Daten" -#: intervention/utils/quality.py:98 +#: intervention/utils/quality.py:100 msgid "No compensation of any type found (Compensation, Payment, Deduction)" -msgstr "Kein Ausgleich jeglicher Art gefunden (Kompensation, Ersatzzahlung, Abbuchung)" - -#: intervention/utils/quality.py:110 intervention/utils/quality.py:112 -#: konova/forms.py:246 templates/form/collapsable/form.html:45 -msgid "Geometry" -msgstr "Geometrie" +msgstr "" +"Kein Ausgleich jeglicher Art gefunden (Kompensation, Ersatzzahlung, " +"Abbuchung)" #: intervention/views.py:80 msgid "Intervention {} added" @@ -1499,6 +1500,11 @@ msgstr "Löschen" msgid "You are about to remove {} {}" msgstr "Sie sind dabei {} {} zu löschen" +#: konova/forms.py:246 konova/utils/quality.py:44 konova/utils/quality.py:46 +#: templates/form/collapsable/form.html:45 +msgid "Geometry" +msgstr "Geometrie" + #: konova/forms.py:322 msgid "Are you sure?" msgstr "Sind Sie sicher?" @@ -1674,6 +1680,10 @@ msgstr "Schauen Sie rein" msgid "{} has been checked successfully by user {}! {}" msgstr "{} wurde erfolgreich vom Nutzer {} geprüft! {}" +#: konova/utils/quality.py:32 +msgid "missing" +msgstr "fehlt" + #: konova/views.py:115 msgid "Deadline removed" msgstr "Frist gelöscht" @@ -3119,4 +3129,4 @@ msgstr "" #: venv/lib/python3.7/site-packages/fontawesome_5/fields.py:16 msgid "A fontawesome icon field" -msgstr "" \ No newline at end of file +msgstr "" -- 2.38.5 From 26c1cee27e613e505f58976433ff83d6674cfb3c Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 25 Oct 2021 14:36:58 +0200 Subject: [PATCH 4/7] #36 Quality checks * adds quality check logic for EcoAccount with EcoAccountQualityChecker * adds/updates translations * adds quality check logic for EMA with EmaQualityChecker --- compensation/models.py | 14 ++++---- compensation/utils/quality.py | 56 +++++++++++++++++++++++++++++++ ema/models.py | 15 ++++----- ema/utils/quality.py | 22 ++++++++---- konova/forms.py | 9 +++-- locale/de/LC_MESSAGES/django.mo | Bin 26776 -> 26933 bytes locale/de/LC_MESSAGES/django.po | 57 ++++++++++++++++++-------------- 7 files changed, 124 insertions(+), 49 deletions(-) diff --git a/compensation/models.py b/compensation/models.py index 5367b2e..c672714 100644 --- a/compensation/models.py +++ b/compensation/models.py @@ -19,7 +19,7 @@ from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES CODELIST_COMPENSATION_FUNDING_ID from compensation.managers import CompensationStateManager, EcoAccountDeductionManager, CompensationActionManager, \ EcoAccountManager, CompensationManager -from compensation.utils.quality import CompensationQualityChecker +from compensation.utils.quality import CompensationQualityChecker, EcoAccountQualityChecker from intervention.models import Intervention, ResponsibilityData, LegalData from konova.models import BaseObject, BaseResource, Geometry, UuidModel, AbstractDocument, \ generate_document_file_upload_path @@ -447,17 +447,15 @@ class EcoAccount(AbstractCompensation): y, ) - def quality_check(self) -> list: + def quality_check(self) -> EcoAccountQualityChecker: """ Quality check Returns: - ret_msgs (list): Holds error messages + ret_msgs (EcoAccountQualityChecker): Holds validity and error messages """ - ret_msgs = [] - - # ToDo: Add check methods! - - return ret_msgs + checker = EcoAccountQualityChecker(self) + checker.run_check() + return checker def get_documents(self) -> QuerySet: """ Getter for all documents of an EcoAccount diff --git a/compensation/utils/quality.py b/compensation/utils/quality.py index 0e3c2cf..28002db 100644 --- a/compensation/utils/quality.py +++ b/compensation/utils/quality.py @@ -46,3 +46,59 @@ class CompensationQualityChecker(AbstractQualityChecker): """ if not self.obj.actions.all(): self._add_missing_attr_name(_con("Compensation", "Actions")) + + +class EcoAccountQualityChecker(CompensationQualityChecker): + def run_check(self): + """ Checks on data quality for an EcoAccount + + Returns: + + """ + self._check_deductable_surface() + self._check_responsible_data() + self._check_legal_data() + super().run_check() + + def _check_legal_data(self): + """ Checks the data quality for LegalData + + Returns: + + """ + try: + legal = self.obj.legal + if legal.registration_date is None: + self._add_missing_attr_name(_("Agreement date")) + except AttributeError: + self._add_missing_attr_name(_("Legal data")) + + def _check_deductable_surface(self): + """ Checks the quality of the deductable surface value + + Returns: + + """ + surface = self.obj.deductable_surface + if surface is None or surface == 0: + self._add_missing_attr_name(_("Available Surface")) + after_state_surface = self.obj.get_state_after_surface_sum() + if surface > after_state_surface: + self.messages.append( + _("Deductable surface can not be larger than state surface") + ) + + def _check_responsible_data(self): + """ Checks on responsible data quality + + Returns: + + """ + try: + resp = self.obj.responsible + if resp.conservation_office is None: + self._add_missing_attr_name(_("Conservation office")) + if resp.conservation_file_number is None or len(resp.conservation_file_number) == 0: + self._add_missing_attr_name(_("Conservation office file number")) + except AttributeError: + self._add_missing_attr_name(_("Responsible data")) diff --git a/ema/models.py b/ema/models.py index e8d31c4..a0b5f5e 100644 --- a/ema/models.py +++ b/ema/models.py @@ -6,8 +6,9 @@ from django.db.models import QuerySet from compensation.models import AbstractCompensation from ema.managers import EmaManager +from ema.utils.quality import EmaQualityChecker from konova.models import AbstractDocument, generate_document_file_upload_path -from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE, EMA_DOC_PATH +from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE from user.models import UserActionLogEntry @@ -80,17 +81,15 @@ class Ema(AbstractCompensation): y, ) - def quality_check(self) -> list: + def quality_check(self) -> EmaQualityChecker: """ Quality check Returns: - ret_msgs (list): Holds error messages + ret_msgs (EmaQualityChecker): Holds validity error messages """ - ret_msgs = [] - - # ToDo: Add check methods! - - return ret_msgs + checker = EmaQualityChecker(self) + checker.run_check() + return checker def get_documents(self) -> QuerySet: """ Getter for all documents of an EMA diff --git a/ema/utils/quality.py b/ema/utils/quality.py index 8c57f51..dc7b07c 100644 --- a/ema/utils/quality.py +++ b/ema/utils/quality.py @@ -5,16 +5,26 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 25.10.21 """ -from konova.utils.quality import AbstractQualityChecker +from django.utils.translation import gettext_lazy as _ +from compensation.utils.quality import CompensationQualityChecker -class EmaQualityChecker(AbstractQualityChecker): +class EmaQualityChecker(CompensationQualityChecker): def run_check(self): - """ Perform all defined data checks + super().run_check() + self._check_responsible_data() + + def _check_responsible_data(self): + """ Checks on responsible data quality Returns: """ - - self._check_geometry() - self.valid = len(self.messages) == 0 + try: + resp = self.obj.responsible + if resp.conservation_office is None: + self._add_missing_attr_name(_("Conservation office")) + if resp.conservation_file_number is None or len(resp.conservation_file_number) == 0: + self._add_missing_attr_name(_("Conservation office file number")) + except AttributeError: + self._add_missing_attr_name(_("Responsible data")) diff --git a/konova/forms.py b/konova/forms.py index 74e5389..83cf720 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -472,13 +472,16 @@ class RecordModalForm(BaseModalForm): """ super_val = super().is_valid() - msgs = self.instance.quality_check() or [] - for msg in msgs: + if self.instance.recorded: + # If user wants to unrecord an already recorded dataset, we do not need to perform custom checks + return super_val + checker = self.instance.quality_check() + for msg in checker.messages: self.add_error( "confirm", msg ) - return super_val and (len(msgs) == 0) + return super_val and checker.valid def save(self): with transaction.atomic(): diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index f84bd1867b5720a30a73b2e0f99650fce62d0e7e..817362f26e53b00788a39b311366b260d21ca839 100644 GIT binary patch delta 8448 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 delta 8410 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 diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index a299554..88d2ad0 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-25 13:37+0200\n" +"POT-Creation-Date: 2021-10-25 14:13+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -40,11 +40,11 @@ msgstr "Bis" #: analysis/forms.py:47 compensation/forms/forms.py:93 #: compensation/templates/compensation/detail/eco_account/view.html:58 #: compensation/templates/compensation/report/eco_account/report.html:16 -#: ema/templates/ema/detail/view.html:42 +#: compensation/utils/quality.py:100 ema/templates/ema/detail/view.html:42 #: ema/templates/ema/report/report.html:16 intervention/forms/forms.py:101 #: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/report/report.html:37 -#: intervention/utils/quality.py:51 +#: intervention/utils/quality.py:49 msgid "Conservation office" msgstr "Eintragungsstelle" @@ -372,11 +372,11 @@ msgstr "Zusätzlicher Kommentar" #: compensation/forms/forms.py:109 #: compensation/templates/compensation/detail/eco_account/view.html:62 #: compensation/templates/compensation/report/eco_account/report.html:20 -#: ema/templates/ema/detail/view.html:46 +#: compensation/utils/quality.py:102 ema/templates/ema/detail/view.html:46 #: ema/templates/ema/report/report.html:20 intervention/forms/forms.py:129 #: intervention/templates/intervention/detail/view.html:60 #: intervention/templates/intervention/report/report.html:41 -#: intervention/utils/quality.py:44 +#: intervention/utils/quality.py:42 msgid "Conservation office file number" msgstr "Aktenzeichen Eintragungsstelle" @@ -414,7 +414,7 @@ msgstr "Neue Kompensation" msgid "Edit compensation" msgstr "Bearbeite Kompensation" -#: compensation/forms/forms.py:290 +#: compensation/forms/forms.py:290 compensation/utils/quality.py:84 msgid "Available Surface" msgstr "Verfügbare Fläche" @@ -424,6 +424,7 @@ msgstr "Die für Abbuchungen zur Verfügung stehende Menge" #: compensation/forms/forms.py:302 #: compensation/templates/compensation/detail/eco_account/view.html:66 +#: compensation/utils/quality.py:72 msgid "Agreement date" msgstr "Vereinbarungsdatum" @@ -804,6 +805,7 @@ msgstr "Dokument löschen" #: compensation/templates/compensation/detail/compensation/includes/states-after.html:8 #: compensation/templates/compensation/detail/eco_account/includes/states-after.html:8 +#: compensation/utils/quality.py:39 #: ema/templates/ema/detail/includes/states-after.html:8 msgid "States after" msgstr "Zielzustand" @@ -840,6 +842,7 @@ msgstr "Zustand entfernen" #: compensation/templates/compensation/detail/compensation/includes/states-before.html:8 #: compensation/templates/compensation/detail/eco_account/includes/states-before.html:8 +#: compensation/utils/quality.py:37 #: ema/templates/ema/detail/includes/states-before.html:8 msgid "States before" msgstr "Ausgangszustand" @@ -1013,10 +1016,24 @@ msgstr "In LANIS öffnen" msgid "Deductions for" msgstr "Abbuchungen für" -#: compensation/utils/quality.py:35 +#: compensation/utils/quality.py:34 msgid "States unequal" msgstr "Ungleiche Zustandsflächenmengen" +#: compensation/utils/quality.py:74 intervention/utils/quality.py:84 +msgid "Legal data" +msgstr "Rechtliche Daten" + +#: compensation/utils/quality.py:88 +msgid "Deductable surface can not be larger than state surface" +msgstr "" +"Die abbuchbare Fläche darf die Gesamtfläche der Zielzustände nicht " +"überschreiten" + +#: compensation/utils/quality.py:104 intervention/utils/quality.py:55 +msgid "Responsible data" +msgstr "Daten zu den verantwortlichen Stellen" + #: compensation/views/compensation_views.py:77 msgid "Compensation {} added" msgstr "Kompensation {} hinzugefügt" @@ -1165,7 +1182,7 @@ msgstr "Bauvorhaben XY; Flur ABC" #: intervention/forms/forms.py:51 #: intervention/templates/intervention/detail/view.html:35 #: intervention/templates/intervention/report/report.html:16 -#: intervention/utils/quality.py:84 +#: intervention/utils/quality.py:82 msgid "Process type" msgstr "Verfahrenstyp" @@ -1176,14 +1193,14 @@ msgstr "Mehrfachauswahl möglich" #: intervention/forms/forms.py:85 #: intervention/templates/intervention/detail/view.html:48 #: intervention/templates/intervention/report/report.html:29 -#: intervention/utils/quality.py:48 +#: intervention/utils/quality.py:46 msgid "Registration office" msgstr "Zulassungsbehörde" #: intervention/forms/forms.py:117 #: intervention/templates/intervention/detail/view.html:52 #: intervention/templates/intervention/report/report.html:33 -#: intervention/utils/quality.py:41 +#: intervention/utils/quality.py:39 msgid "Registration office file number" msgstr "Aktenzeichen Zulassungsbehörde" @@ -1194,7 +1211,7 @@ msgstr "" #: intervention/forms/forms.py:141 #: intervention/templates/intervention/detail/view.html:64 #: intervention/templates/intervention/report/report.html:45 -#: intervention/utils/quality.py:54 +#: intervention/utils/quality.py:52 msgid "Intervention handler" msgstr "Eingriffsverursacher" @@ -1205,7 +1222,7 @@ msgstr "Wer führt den Eingriff durch" #: intervention/forms/forms.py:154 #: intervention/templates/intervention/detail/view.html:96 #: intervention/templates/intervention/report/report.html:83 -#: intervention/utils/quality.py:75 +#: intervention/utils/quality.py:73 msgid "Registration date" msgstr "Datum Zulassung bzw. Satzungsbeschluss" @@ -1389,27 +1406,19 @@ msgstr "Abbuchungen von Ökokonten" msgid "Exist" msgstr "Vorhanden" -#: intervention/utils/quality.py:57 -msgid "Responsible data" -msgstr "Daten zu den verantwortlichen Stellen" - -#: intervention/utils/quality.py:72 +#: intervention/utils/quality.py:70 msgid "Revocation exists" msgstr "Widerspruch liegt vor" -#: intervention/utils/quality.py:78 +#: intervention/utils/quality.py:76 msgid "Binding date" msgstr "Datum Bestandskraft" -#: intervention/utils/quality.py:81 +#: intervention/utils/quality.py:79 msgid "Laws" msgstr "Gesetze" -#: intervention/utils/quality.py:86 -msgid "Legal data" -msgstr "Rechtliche Daten" - -#: intervention/utils/quality.py:100 +#: intervention/utils/quality.py:98 msgid "No compensation of any type found (Compensation, Payment, Deduction)" msgstr "" "Kein Ausgleich jeglicher Art gefunden (Kompensation, Ersatzzahlung, " -- 2.38.5 From 1c3ab898cc2923782393278f167ebd698304a49f Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 25 Oct 2021 17:01:02 +0200 Subject: [PATCH 5/7] #36 Quality checks * refactors toggling of recorded status into RecordableMixin --- compensation/models.py | 4 ++-- ema/models.py | 4 ++-- intervention/models.py | 5 ++--- konova/forms.py | 18 +----------------- konova/models.py | 31 +++++++++++++++++++++++++++++++ 5 files changed, 38 insertions(+), 24 deletions(-) diff --git a/compensation/models.py b/compensation/models.py index c672714..27fb963 100644 --- a/compensation/models.py +++ b/compensation/models.py @@ -22,7 +22,7 @@ from compensation.managers import CompensationStateManager, EcoAccountDeductionM from compensation.utils.quality import CompensationQualityChecker, EcoAccountQualityChecker from intervention.models import Intervention, ResponsibilityData, LegalData from konova.models import BaseObject, BaseResource, Geometry, UuidModel, AbstractDocument, \ - generate_document_file_upload_path + generate_document_file_upload_path, RecordableMixin from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE from user.models import UserActionLogEntry @@ -310,7 +310,7 @@ class CompensationDocument(AbstractDocument): pass -class EcoAccount(AbstractCompensation): +class EcoAccount(AbstractCompensation, RecordableMixin): """ An eco account is a kind of 'prepaid' compensation. It can be compared to an account that already has been filled with some kind of currency. From this account one is able to deduct currency for current projects. diff --git a/ema/models.py b/ema/models.py index a0b5f5e..1fa8501 100644 --- a/ema/models.py +++ b/ema/models.py @@ -7,12 +7,12 @@ from django.db.models import QuerySet from compensation.models import AbstractCompensation from ema.managers import EmaManager from ema.utils.quality import EmaQualityChecker -from konova.models import AbstractDocument, generate_document_file_upload_path +from konova.models import AbstractDocument, generate_document_file_upload_path, RecordableMixin from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE from user.models import UserActionLogEntry -class Ema(AbstractCompensation): +class Ema(AbstractCompensation, RecordableMixin): """ EMA = Ersatzzahlungsmaßnahme (compensation actions from payments) diff --git a/intervention/models.py b/intervention/models.py index 7fbb922..6bd042f 100644 --- a/intervention/models.py +++ b/intervention/models.py @@ -10,7 +10,6 @@ import shutil from django.contrib.auth.models import User from django.contrib.gis.db import models from django.db.models import QuerySet -from django.utils.translation import gettext_lazy as _ from codelist.models import KonovaCode from codelist.settings import CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID, CODELIST_LAW_ID, \ @@ -18,7 +17,7 @@ from codelist.settings import CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVA from intervention.managers import InterventionManager from intervention.utils.quality import InterventionQualityChecker from konova.models import BaseObject, Geometry, UuidModel, BaseResource, AbstractDocument, \ - generate_document_file_upload_path + generate_document_file_upload_path, RecordableMixin from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE, LANIS_ZOOM_LUT from konova.utils import generators from user.models import UserActionLogEntry @@ -172,7 +171,7 @@ class LegalData(UuidModel): revocation = models.OneToOneField(Revocation, null=True, blank=True, help_text="Refers to 'Widerspruch am'", on_delete=models.SET_NULL) -class Intervention(BaseObject): +class Intervention(BaseObject, RecordableMixin): """ Interventions are e.g. construction sites where nature used to be. """ diff --git a/konova/forms.py b/konova/forms.py index 83cf720..cf86818 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -486,21 +486,5 @@ class RecordModalForm(BaseModalForm): def save(self): with transaction.atomic(): if self.cleaned_data["confirm"]: - if self.instance.recorded: - # unrecord! - unrecord_action = UserActionLogEntry.objects.create( - user=self.user, - action=UserAction.UNRECORDED - ) - # Do not delete the old .recorded attribute, since it shall stay in the .log list! - self.instance.recorded = None - self.instance.log.add(unrecord_action) - else: - record_action = UserActionLogEntry.objects.create( - user=self.user, - action=UserAction.RECORDED - ) - self.instance.recorded = record_action - self.instance.log.add(record_action) - self.instance.save() + self.instance.toggle_recorded(self.user) return self.instance \ No newline at end of file diff --git a/konova/models.py b/konova/models.py index f9f8758..2d34a4b 100644 --- a/konova/models.py +++ b/konova/models.py @@ -313,3 +313,34 @@ class Geometry(BaseResource): """ from konova.settings import DEFAULT_SRID geom = MultiPolygonField(null=True, blank=True, srid=DEFAULT_SRID) + + +class RecordableMixin: + """ Mixin to be combined with BaseObject class + + Provides functionality related to un/recording of data + + """ + def toggle_recorded(self, user: User): + """ Un/Record intervention + + Args: + user (User): Performing user + + Returns: + + """ + if not self.recorded: + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.RECORDED + ) + self.recorded = action + else: + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.UNRECORDED + ) + self.recorded = None + self.save() + self.log.add(action) -- 2.38.5 From 4a4c9ad049f633c8d4cdfc98c2c2eb4ac377c668 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 25 Oct 2021 17:39:39 +0200 Subject: [PATCH 6/7] #36 Quality checks * adds unchecking/unrecording of interventions in case of post-check|post-record editing --- compensation/models.py | 22 +++---- intervention/forms/forms.py | 4 ++ intervention/models.py | 10 ++-- intervention/views.py | 7 ++- konova/models.py | 93 ++++++++++++++++++++++++++---- konova/utils/message_templates.py | 4 +- locale/de/LC_MESSAGES/django.mo | Bin 26933 -> 27052 bytes locale/de/LC_MESSAGES/django.po | 41 +++++++------ 8 files changed, 137 insertions(+), 44 deletions(-) diff --git a/compensation/models.py b/compensation/models.py index 27fb963..3755012 100644 --- a/compensation/models.py +++ b/compensation/models.py @@ -221,11 +221,12 @@ class Compensation(AbstractCompensation): def save(self, *args, **kwargs): if self.identifier is None or len(self.identifier) == 0: - # Create new identifier - new_id = self.generate_new_identifier() - while Compensation.objects.filter(identifier=new_id).exists(): - new_id = self.generate_new_identifier() - self.identifier = new_id + # Create new identifier is none was given + self.identifier = self.generate_new_identifier() + + # Before saving, make sure a given identifier has not been taken already in the meanwhile + while Compensation.objects.filter(identifier=self.identifier).exclude(id=self.id).exists(): + self.identifier = self.generate_new_identifier() super().save(*args, **kwargs) def get_LANIS_link(self) -> str: @@ -368,11 +369,12 @@ class EcoAccount(AbstractCompensation, RecordableMixin): def save(self, *args, **kwargs): if self.identifier is None or len(self.identifier) == 0: - # Create new identifier - new_id = self.generate_new_identifier() - while EcoAccount.objects.filter(identifier=new_id).exists(): - new_id = self.generate_new_identifier() - self.identifier = new_id + # Create new identifier if none was given + self.identifier = self.generate_new_identifier() + + # Before saving, make sure the given identifier is not used, yet + while EcoAccount.objects.filter(identifier=self.identifier).exclude(id=self.id).exists(): + self.identifier = self.generate_new_identifier() super().save(*args, **kwargs) @property diff --git a/intervention/forms/forms.py b/intervention/forms/forms.py index 2236458..67a58a4 100644 --- a/intervention/forms/forms.py +++ b/intervention/forms/forms.py @@ -355,5 +355,9 @@ class EditInterventionForm(NewInterventionForm): self.instance.modified = user_action self.instance.save() + # Uncheck and unrecord intervention due to changed data + self.instance.set_unchecked(user) + self.instance.set_unrecorded(user) + return self.instance diff --git a/intervention/models.py b/intervention/models.py index 6bd042f..46cc095 100644 --- a/intervention/models.py +++ b/intervention/models.py @@ -17,7 +17,7 @@ from codelist.settings import CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVA from intervention.managers import InterventionManager from intervention.utils.quality import InterventionQualityChecker from konova.models import BaseObject, Geometry, UuidModel, BaseResource, AbstractDocument, \ - generate_document_file_upload_path, RecordableMixin + generate_document_file_upload_path, RecordableMixin, CheckableMixin from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE, LANIS_ZOOM_LUT from konova.utils import generators from user.models import UserActionLogEntry @@ -171,7 +171,7 @@ class LegalData(UuidModel): revocation = models.OneToOneField(Revocation, null=True, blank=True, help_text="Refers to 'Widerspruch am'", on_delete=models.SET_NULL) -class Intervention(BaseObject, RecordableMixin): +class Intervention(BaseObject, RecordableMixin, CheckableMixin): """ Interventions are e.g. construction sites where nature used to be. """ @@ -273,11 +273,11 @@ class Intervention(BaseObject, RecordableMixin): """ if self.identifier is None or len(self.identifier) == 0: - # No identifier given + # No identifier given by the user self.identifier = self.generate_new_identifier() - # Before saving, make sure the set identifier is not used, yet - while Intervention.objects.filter(identifier=self.identifier).exists(): + # Before saving, make sure the given identifier is not used in the meanwhile + while Intervention.objects.filter(identifier=self.identifier).exclude(id=self.id).exists(): self.identifier = self.generate_new_identifier() super().save(*args, **kwargs) diff --git a/intervention/views.py b/intervention/views.py index c58b03a..6c2f524 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -15,7 +15,7 @@ from konova.sub_settings.django_settings import DEFAULT_DATE_FORMAT from konova.utils.documents import remove_document, get_document from konova.utils.generators import generate_qr_code from konova.utils.message_templates import INTERVENTION_INVALID, FORM_INVALID, IDENTIFIER_REPLACED, \ - DATA_UNSHARED_EXPLANATION + DATA_UNSHARED_EXPLANATION, CHECKED_RECORDED_RESET from konova.utils.user_checks import in_group @@ -270,8 +270,13 @@ def edit_view(request: HttpRequest, id: str): if request.method == "POST": if data_form.is_valid() and geom_form.is_valid(): # The data form takes the geom form for processing, as well as the performing user + # Save the current state of recorded|checked to inform the user in case of a status reset due to editing + i_rec = intervention.recorded is not None + i_check = intervention.checked is not None intervention = data_form.save(request.user, geom_form) messages.success(request, _("Intervention {} edited").format(intervention.identifier)) + if i_check or i_rec: + messages.info(request, CHECKED_RECORDED_RESET) return redirect("intervention:detail", id=intervention.id) else: messages.error(request, FORM_INVALID, extra_tags="danger",) diff --git a/konova/models.py b/konova/models.py index 2d34a4b..830916f 100644 --- a/konova/models.py +++ b/konova/models.py @@ -321,6 +321,40 @@ class RecordableMixin: Provides functionality related to un/recording of data """ + def set_unrecorded(self, user: User): + """ Perform unrecording + + Args: + user (User): Performing user + + Returns: + + """ + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.UNRECORDED + ) + self.recorded = None + self.save() + self.log.add(action) + + def set_recorded(self, user: User): + """ Perform recording + + Args: + user (User): Performing user + + Returns: + + """ + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.RECORDED + ) + self.recorded = action + self.save() + self.log.add(action) + def toggle_recorded(self, user: User): """ Un/Record intervention @@ -331,16 +365,55 @@ class RecordableMixin: """ if not self.recorded: - action = UserActionLogEntry.objects.create( - user=user, - action=UserAction.RECORDED - ) - self.recorded = action + self.set_recorded(user) else: - action = UserActionLogEntry.objects.create( - user=user, - action=UserAction.UNRECORDED - ) - self.recorded = None + self.set_unrecorded(user) + + +class CheckableMixin: + """ Mixin to be combined with BaseObject class + + Provides functionality related to un/checking of data + + """ + def set_unchecked(self, user: User): + """ Perform unrecording + + Args: + + Returns: + + """ + self.checked = None + self.save() + + def set_checked(self, user: User): + """ Perform checking + + Args: + user (User): Performing user + + Returns: + + """ + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.CHECKED + ) + self.checked = action self.save() self.log.add(action) + + def toggle_checked(self, user: User): + """ Un/Record intervention + + Args: + user (User): Performing user + + Returns: + + """ + if not self.checked: + self.set_checked(user) + else: + self.set_unchecked(user) diff --git a/konova/utils/message_templates.py b/konova/utils/message_templates.py index 502030c..ae29853 100644 --- a/konova/utils/message_templates.py +++ b/konova/utils/message_templates.py @@ -14,4 +14,6 @@ INTERVENTION_INVALID = _("There are errors in this intervention.") IDENTIFIER_REPLACED = _("The identifier '{}' had to be changed to '{}' since another entry has been added in the meanwhile, which uses this identifier") DATA_UNSHARED = _("This data is not shared with you") DATA_UNSHARED_EXPLANATION = _("Remember: This data has not been shared with you, yet. This means you can only read but can not edit or perform any actions like running a check or recording.") -MISSING_GROUP_PERMISSION = _("You need to be part of another user group.") \ No newline at end of file +MISSING_GROUP_PERMISSION = _("You need to be part of another user group.") + +CHECKED_RECORDED_RESET = _("Status of Checked and Recorded reseted") \ No newline at end of file diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 817362f26e53b00788a39b311366b260d21ca839..e4d126ba2b2836ab814a5a7cd93fbda07dad22ce 100644 GIT binary patch delta 8570 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 delta 8445 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 U&m?Y$+q^j~GG+6f>`ev#4{#K6oB#j- diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index 88d2ad0..f850b34 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-25 14:13+0200\n" +"POT-Creation-Date: 2021-10-25 17:10+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -41,7 +41,8 @@ msgstr "Bis" #: compensation/templates/compensation/detail/eco_account/view.html:58 #: compensation/templates/compensation/report/eco_account/report.html:16 #: compensation/utils/quality.py:100 ema/templates/ema/detail/view.html:42 -#: ema/templates/ema/report/report.html:16 intervention/forms/forms.py:101 +#: ema/templates/ema/report/report.html:16 ema/utils/quality.py:26 +#: intervention/forms/forms.py:101 #: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/report/report.html:37 #: intervention/utils/quality.py:49 @@ -373,7 +374,8 @@ msgstr "Zusätzlicher Kommentar" #: compensation/templates/compensation/detail/eco_account/view.html:62 #: compensation/templates/compensation/report/eco_account/report.html:20 #: compensation/utils/quality.py:102 ema/templates/ema/detail/view.html:46 -#: ema/templates/ema/report/report.html:20 intervention/forms/forms.py:129 +#: ema/templates/ema/report/report.html:20 ema/utils/quality.py:28 +#: intervention/forms/forms.py:129 #: intervention/templates/intervention/detail/view.html:60 #: intervention/templates/intervention/report/report.html:41 #: intervention/utils/quality.py:42 @@ -1030,7 +1032,8 @@ msgstr "" "Die abbuchbare Fläche darf die Gesamtfläche der Zielzustände nicht " "überschreiten" -#: compensation/utils/quality.py:104 intervention/utils/quality.py:55 +#: compensation/utils/quality.py:104 ema/utils/quality.py:30 +#: intervention/utils/quality.py:55 msgid "Responsible data" msgstr "Daten zu den verantwortlichen Stellen" @@ -1044,7 +1047,7 @@ msgstr "Kompensation {} bearbeitet" #: compensation/views/compensation_views.py:216 #: compensation/views/eco_account_views.py:290 ema/views.py:178 -#: intervention/views.py:447 +#: intervention/views.py:448 msgid "Log" msgstr "Log" @@ -1098,16 +1101,16 @@ msgid "Deduction removed" msgstr "Abbuchung entfernt" #: compensation/views/eco_account_views.py:310 ema/views.py:252 -#: intervention/views.py:487 +#: intervention/views.py:488 msgid "{} unrecorded" msgstr "{} entzeichnet" #: compensation/views/eco_account_views.py:310 ema/views.py:252 -#: intervention/views.py:487 +#: intervention/views.py:488 msgid "{} recorded" msgstr "{} verzeichnet" -#: compensation/views/eco_account_views.py:455 intervention/views.py:469 +#: compensation/views/eco_account_views.py:455 intervention/views.py:470 msgid "Deduction added" msgstr "Abbuchung hinzugefügt" @@ -1436,39 +1439,43 @@ msgstr "Es existiert ein Widerspruch vom {}" msgid "Intervention {} edited" msgstr "Eingriff {} bearbeitet" -#: intervention/views.py:306 +#: intervention/views.py:275 +msgid "Status of Checked and Recorded reseted" +msgstr "'Geprüft' und 'Verzeichnet' sind zurückgesetzt worden" + +#: intervention/views.py:307 msgid "{} removed" msgstr "{} entfernt" -#: intervention/views.py:327 +#: intervention/views.py:328 msgid "Revocation removed" msgstr "Widerspruch entfernt" -#: intervention/views.py:353 +#: intervention/views.py:354 msgid "{} has already been shared with you" msgstr "{} wurde bereits für Sie freigegeben" -#: intervention/views.py:358 +#: intervention/views.py:359 msgid "{} has been shared with you" msgstr "{} ist nun für Sie freigegeben" -#: intervention/views.py:365 +#: intervention/views.py:366 msgid "Share link invalid" msgstr "Freigabelink ungültig" -#: intervention/views.py:386 +#: intervention/views.py:387 msgid "Share settings updated" msgstr "Freigabe Einstellungen aktualisiert" -#: intervention/views.py:405 +#: intervention/views.py:406 msgid "Check performed" msgstr "Prüfung durchgeführt" -#: intervention/views.py:425 +#: intervention/views.py:426 msgid "Revocation added" msgstr "Widerspruch hinzugefügt" -#: intervention/views.py:492 +#: intervention/views.py:493 msgid "There are errors on this intervention:" msgstr "Es liegen Fehler in diesem Eingriff vor:" -- 2.38.5 From da23761f889ab939c3892818ccaf850d56df5a5d Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Tue, 26 Oct 2021 07:47:53 +0200 Subject: [PATCH 7/7] #36 Quality checks * adds check on recording of intervention in case of invalid compensations --- konova/forms.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/konova/forms.py b/konova/forms.py index cf86818..a2c1c0c 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -481,8 +481,27 @@ class RecordModalForm(BaseModalForm): "confirm", msg ) + # Special case: Intervention + # Add direct checks for related compensations + if isinstance(self.instance, Intervention): + self._are_compensations_valid() return super_val and checker.valid + def _are_compensations_valid(self): + """ Runs a special case for intervention-compensations validity + + Returns: + + """ + comps = self.instance.compensations.all() + for comp in comps: + checker = comp.quality_check() + for msg in checker.messages: + self.add_error( + "confirm", + f"{comp.identifier}: {msg}" + ) + def save(self): with transaction.atomic(): if self.cleaned_data["confirm"]: -- 2.38.5