From 9f6cf12a807469736934f584efb20099da727ca8 Mon Sep 17 00:00:00 2001 From: Rachael Booth Date: Tue, 23 Apr 2024 10:49:44 +0100 Subject: [PATCH] Doc --- app/models/validations/.yardoc/checksums | 15 + app/models/validations/.yardoc/complete | 0 app/models/validations/.yardoc/object_types | Bin 0 -> 15580 bytes .../validations/.yardoc/objects/root.dat | Bin 0 -> 184445 bytes app/models/validations/.yardoc/proxy_types | Bin 0 -> 4 bytes .../doc/Validations/DateValidations.html | 360 +++ .../doc/Validations/FinancialValidations.html | 915 ++++++++ .../doc/Validations/HouseholdValidations.html | 1243 ++++++++++ .../LocalAuthorityValidations.html | 182 ++ .../doc/Validations/PropertyValidations.html | 435 ++++ .../Sales/FinancialValidations.html | 843 +++++++ .../Sales/HouseholdValidations.html | 702 ++++++ .../Sales/PropertyValidations.html | 312 +++ .../Sales/SaleInformationValidations.html | 1445 ++++++++++++ .../Validations/Sales/SetupValidations.html | 417 ++++ .../Validations/Sales/SoftValidations.html | 1996 +++++++++++++++++ .../doc/Validations/SetupValidations.html | 679 ++++++ .../doc/Validations/SharedValidations.html | 853 +++++++ .../doc/Validations/SoftValidations.html | 1516 +++++++++++++ .../doc/Validations/TenancyValidations.html | 584 +++++ app/models/validations/doc/_index.html | 246 ++ app/models/validations/doc/class_list.html | 51 + app/models/validations/doc/css/common.css | 1 + app/models/validations/doc/css/full_list.css | 58 + app/models/validations/doc/css/style.css | 497 ++++ app/models/validations/doc/file_list.html | 51 + app/models/validations/doc/frames.html | 22 + app/models/validations/doc/index.html | 246 ++ app/models/validations/doc/js/app.js | 314 +++ app/models/validations/doc/js/full_list.js | 216 ++ app/models/validations/doc/js/jquery.js | 4 + app/models/validations/doc/method_list.html | 1179 ++++++++++ .../validations/doc/top-level-namespace.html | 100 + 33 files changed, 15482 insertions(+) create mode 100644 app/models/validations/.yardoc/checksums create mode 100644 app/models/validations/.yardoc/complete create mode 100644 app/models/validations/.yardoc/object_types create mode 100644 app/models/validations/.yardoc/objects/root.dat create mode 100644 app/models/validations/.yardoc/proxy_types create mode 100644 app/models/validations/doc/Validations/DateValidations.html create mode 100644 app/models/validations/doc/Validations/FinancialValidations.html create mode 100644 app/models/validations/doc/Validations/HouseholdValidations.html create mode 100644 app/models/validations/doc/Validations/LocalAuthorityValidations.html create mode 100644 app/models/validations/doc/Validations/PropertyValidations.html create mode 100644 app/models/validations/doc/Validations/Sales/FinancialValidations.html create mode 100644 app/models/validations/doc/Validations/Sales/HouseholdValidations.html create mode 100644 app/models/validations/doc/Validations/Sales/PropertyValidations.html create mode 100644 app/models/validations/doc/Validations/Sales/SaleInformationValidations.html create mode 100644 app/models/validations/doc/Validations/Sales/SetupValidations.html create mode 100644 app/models/validations/doc/Validations/Sales/SoftValidations.html create mode 100644 app/models/validations/doc/Validations/SetupValidations.html create mode 100644 app/models/validations/doc/Validations/SharedValidations.html create mode 100644 app/models/validations/doc/Validations/SoftValidations.html create mode 100644 app/models/validations/doc/Validations/TenancyValidations.html create mode 100644 app/models/validations/doc/_index.html create mode 100644 app/models/validations/doc/class_list.html create mode 100644 app/models/validations/doc/css/common.css create mode 100644 app/models/validations/doc/css/full_list.css create mode 100644 app/models/validations/doc/css/style.css create mode 100644 app/models/validations/doc/file_list.html create mode 100644 app/models/validations/doc/frames.html create mode 100644 app/models/validations/doc/index.html create mode 100644 app/models/validations/doc/js/app.js create mode 100644 app/models/validations/doc/js/full_list.js create mode 100644 app/models/validations/doc/js/jquery.js create mode 100644 app/models/validations/doc/method_list.html create mode 100644 app/models/validations/doc/top-level-namespace.html diff --git a/app/models/validations/.yardoc/checksums b/app/models/validations/.yardoc/checksums new file mode 100644 index 000000000..556d95ee7 --- /dev/null +++ b/app/models/validations/.yardoc/checksums @@ -0,0 +1,15 @@ +sales/financial_validations.rb 6add021f45e5e9c88d0afec093421b0063212292 +sales/household_validations.rb 3a1cb5ed2c2d1ce2a1ce0cf15cee1f9f3b6b5f9d +sales/property_validations.rb 20246b8f4746379f02de744d5e946f2859174b93 +sales/sale_information_validations.rb 23d52b47f67fc5ef728e0d82b80e8d6f748d5205 +sales/setup_validations.rb ef71ce4e95490183dca7893b908f46afb003e91b +sales/soft_validations.rb 80f3e430dda865cf4256db8bb966f9fcd47773c9 +date_validations.rb 8a8d0c5640e5426441a46db20c82f8bbff864250 +financial_validations.rb a3996355854dfb5df4a39357ee074783c7f8e17e +household_validations.rb 3b54050ed5cfb80be6f4d920bb48780eff4e646f +local_authority_validations.rb a83a049b3b8ea90de2b629c071b5832705b6f0c1 +property_validations.rb f5f2ffe3e2d7c9a5deb31ba2618ad2641598d148 +setup_validations.rb 75dba754f71e631fd35c216cf5610a8cb13d8b6e +shared_validations.rb 5d408ca2ede983dd0e38a6dbfc1136b18c099ea9 +soft_validations.rb af5a959f496c7f509d784528896171abd7d726ee +tenancy_validations.rb 954d3c4bad2304cf656295a5e7a79d87f37a225e diff --git a/app/models/validations/.yardoc/complete b/app/models/validations/.yardoc/complete new file mode 100644 index 000000000..e69de29bb diff --git a/app/models/validations/.yardoc/object_types b/app/models/validations/.yardoc/object_types new file mode 100644 index 0000000000000000000000000000000000000000..fa49e9f5c80ca49ad1c2fd71afe39343a4692b5d GIT binary patch literal 15580 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 L_1Tg+XbR>3>ASAZ literal 0 HcmV?d00001 diff --git a/app/models/validations/.yardoc/objects/root.dat b/app/models/validations/.yardoc/objects/root.dat new file mode 100644 index 0000000000000000000000000000000000000000..5d3e6caa54fb89344d20323c3dd7d7a09b77be43 GIT binary patch literal 184445 zcmeFa3y`J9bsmNpkc-6vBtQ}m0tCq)cY(zWIJlUZePQnfc6YEliyd-b++8dI4VRa9 z?)_)x5_j$$-pB3^7E4(VOO|C9Ez7R5T#+BLU5aAKQe>;5$Yr{uROG}e#Yx#w#j&DF zR8l!5$(6*9#3jXXzH|EVclY1@KW1j}pok*Cx&3#a?mn+Refsq25AD4@@msa~2mSu2 zU#q;iaQSqtcBXSm}4qHizrC@2l-&kbw1(+vw}jlSBU4c{^_0Xm-c()!IiCWLc;F(A7Qo zxAu{f&2FbTjEA@HsXcgdZO|WY4wvu2XjePknEv|g$<}y)iH;gn(pYZ}8?FAv1`38} zYWq(1nj3Nbp4!Jw4*TN)#y#5FjDf}R%2w^+lQ%lU&Pu1-8Ew@b*c`8PJ1w*rHP;C4 z!zbJQ)({iwtx?|(B|kB_M+8bws~VMi9;oeEyjp(}4L^Ev5U(~Ql>0IK?otK#`^?qa zlPAZ$K|JhtZ^Z2eD#aLfE1t!?`b)P4xY2#)*!F|cG>N#;>48G=9OL9+%y9r3jpD&@dC&5F zOO*!(ajQRQ)7RPhCq&u)A-_SGM`T7R_msM}5bvHIggnEIz~ z-&21IlmB$(8^)L;^o=PGqh1`hqftLviK7;Xh9A#qP%m#b*Ww28((&i0&S2b&`n?F) ziM!FTc_ZG}9~jlmI>YhGMrRZ?htbWr+x;j;%7ghV1{5v5ha(}J)t{cNS5AJi_9?}( z;7Ul-Fop@4BegDbFAPVuVO-NN|bQMf4Byg!R`8Oup@oJ=zE7@U6(0zJe6b<6hc+iW+ zJrI3}U&IepSuHwnK$Ucx#*g88a{#eoB{p2|Y&M3i^>`ybv5(<(;~Py@5pfr!ekFRg zv#j9h7HANSH_PL}yj^+V8ddy~gGMVlWtOouDy1ZI7|K5|3`i zaqq;`>`ZiQwlO<9OVgr>Sp%uYP4sy?dS|tRalNB@hzEoIU|4Oo+Yx`5iE91vXxPDU zx}tM2c0q|5aPV*l{;Wkyb1(I(qp6BSEvbvDmKlk_Y6hsvbaV&fjJv~Rx@w+{UVjA1 zl_SWV^-H@s>mKmEi!%>^Q?u{2_ko33J3VxA*jei}!Hw}!<>@T0(4z_pE^^Y-UUTD&!YN#NIRbVZ0FJXBWFCSZ{DN&?s?GCKqns+I$*j!)47Lawtnzx z{ZL3o=ZnecydjpmA*1ur?#t->A4?gvXZ>v>L2aCG@B(q4(Zv=_3blF-e^>Bvq^_+mc+EOdKi7qE|||- zlhs&uL+;(d9hWQe4j1Gb@qjiOf*W9av>O}ETaDHJK(16}mt_sBPmnzT)$&wuan|qz zE~Dd-5cj(_ZQHKc#p&CC6&jLNnl!+45m^Xpf)nL6!A5^DT7%V@Pa9Kk;|1=_-Jh%(KmGSdukW3)W<-*&}OiC2qhzEoeQe=D>eq9IC>`co?_YCX|A& zJ{+jN9S`~^ltD$Ls$`BmOruNNp;2$N-rZ_+V|WnO``vb<1;JX2hq*+X6+}yRfE)b) zsNz(-;!^SNIG70ZkV95%TWC%*Io5x00##xKqLNKn3D!fvgXM-Drs&toQxsdS7F;{D z8(-;<*Vae8Em<4H@GA@&qxB{>W=R!VKG=}2XIamO1g#gefEo~rc2b-RnhqCC{+S62 zpWEo%Vi3>H87{ldK+MEg@41vQL|f!Urp?;N)w*p|7W>$gdP!>JaU$1jHHYx5RnxQG z7!O%9Wzw`V6RnK5K=EGxCT;nLH8s$$^*h+-Z^G9H$3=W1IuTX4Cj2}7o3xLpL^WBY zN`@8MoMX#pYN_+PMU*i6w|0yD4j0JE$+d3I2+5z%ko+{%;u3$ymH4SViBI>YkO%4U zdV>wlHH4NXz|Ck~Gyj>JWywv7 z;1-RYq9~ekN{D+wt_n@?7&;@G1z>fC^2ph0KYz{yLm4}W%p+Kh3sN~g*v zWT#aLYT6J$W7VYfv`R~7bo`YF>*m1_mrF2y{z@HRh}qLIuNX8NZ#4VVN+c(>6Sxjn z9##!WQYZ`5-%2(SJp-65lc zGPkch<|VCS@RopQ6twy{rsZ>K;!kO)5o0sD=$LQui?1(TeY0_S;lgW+R~oOr*?4nt z;c|5~9<|mL6MKQoM5hX$1Y@*yv~KZQWj3YOri1%u_qP%4az zEN4jo&`!3HiCBnLjK{!xsOSZ?vKixInW2>y0arMRlC59yZ}G&}Tp7p?9S}gO%ukW$3ggKCDKhZ=>=grw&@OX1rd3&p$< z-zI2q6!VGg>lUAKu005U%MF;o6eD-Ku#Se!jTj*j=|@3K!r(S_@yE>X^g#y6Aq?al zp^-o32a=(A_w-dn<5dJd)@u0gJ_K*U&CW4z9Fs?WWpqa|m81C92!SJy&LSF+Ocey~ zEmaJZE^ssY2fpI!)Xbg!)Wyhm}dI`l)^O(-uwYi%gFCndLnv zC%#44{}l)Ozv5v3f<&1!PPM^viirkJ5s~4TNd!I>3QlOsX+Et;5r|IaFk>0c{BaQl z3I?C}Zh^QbEvsDF^^CMn))$;$&wC#5Mm$aYQx113Bb~LHw_lzLVx}g3-1`}OgWJF# zcEIz|E64e7{GvbS4_B*456|#&esGpb=4O+UxtH8Jb4T1d^M~9z2j{3ngSj)a?@o1f z5XW!xK{W&x=Gqv+Y!iR-eKV*!N#t3B%70o?*}DfTN#)<#29>@2YAS!z`&m)hriV*a zm!>X7U3xmyJjiS#iEGle{`sZKJ512`sQ)8~*1sRogZntRoUaQ!R)4_!@gRPD4`H&ekuF1g{C%o}2*+>^B z*^O@J2F}jOYoLO&vk7o=@b)EDOiwbF z%*3xIySUlub_q3fzr+kh;?IpfE-r8lI$V~uH2TujM>qQ!)p^BM4um9FzlN>|bf@Rv zNoxMD>WcIiZoY`V++mTJjAP;G?hSEIi*7mbflGKd3wU#PdkmSq&%Z0ZJDWEd0a8S!=b)rev7I zua)O;MCc501BZg{;Bv&ZD%(j>fYqNCtp0*#^&F5Tcz!C)^IiKKDyOe9%&+cw8HJ`*z4lZEU-sWls^8HJmpDWM zE!junYukgjMqQ<&j`=7!0Y{R?t0{eZ8DSDs0rO01G_b1|XPy1gI!r!e7CYzN5v)m0#*gcS9N<~Z_v(%Hs0x;v%8A|BFddeFdoV^ko zeKv7IZsJ`J!tp~D&|L?G?y|yzl{zfiO$mK=B(2Z>?T16CE!w|Acaa7Dz0z?GWddqW z1dI6eoJsCLW3J+B>(PYy7c{DjygLgG~;lDn6uspRT33J z*NaDRAm9*(K#l9q@mHJ^9hah=0zd>k3X zoiQk{V)79*Pe+S3h|Xo43CvejjGHXYQidRr%>{WK5>4&ik}EV!ce!BD=CVNl9zM() z0XGSbfpJ{rk?@5GdkmzmnE)o6Kb_`XP*pahbxhEW+wInhZlh2UjEAiaos{jcYYdW* zOpe1KTFw~m62TNch;5P)IA(w9CPLZ8M=AgCTKnd%>?Olm?fT@hGynBV0Lk6w#FK84J;>SZJhG7-94ac3p(%d}X?-@3> z;G0^D2L;sDS6#=QA5sZbbvdo7{*~=V_jjT20xrsR+!c}A0&0%^PK`P81_d-0zRbzx zJlT)Mu>a^fXh=0Ho&lAKnH=3pUo#&Gb9AyAGSc?d=_kv24w8ysXSDY#)-?GVLJ(JY*gNjPCQuOVK>ysxjw87yqP_+od<$d z$P(jD3#fsw3pJ4B_HaOykpHiy<^Lag9QSP7^YF?DzGT82pQVRY#j-bt1;iH}nw)0I z1zJo$v9fufXe`P*2vom?tG7@Mbat0Wk5=_u-?>~eM=~88+WhVgZNAjd=FNLA&b4Fn zkl0R5;qZu}qnDLAGHt1_ZJwYs_dAh z5aEIP)cz8g2pLoIIZ8Au39Er()Q*~@I9wKHm@M9aL9d2M=AefsIK2!}z9ES6nINzo zljOTylAypL2?q@ZM^KO;>7c>l5X0msZvM&MG%W}6gTR{rp;wu(qMg-Eeuv2rj^mEAc|h(=(h6QWy~8fUG(NeFB};~7S@IVQ zb*E)&;!g@fKAxx#1!Knq`+1jOC~ydN%8)m3rs^8&d9rg6woCGxL)R}^q3diMq-S7* z31j;BHZYxDe6sQULjuo_CZiM(c8ul!%EdAY94s%`Sk@L|f>SS!?dt&?rRR>mD287z zjA4`V8KP?{t8B#oS%LVOf`E5SkALRU0|gE}VxmXE@z@xKf_nDm@~P;J=&}{SV^Y#s zb@=}OwmOo+LgC1;C5?Dw{1O4lFi|Nwmp)%aY^qIQ4 zpW_~5is86r-*^e1wHX`d6w*fBR4T7~fsxU-*%6b=5}b`*@)F(UI>9d{XxJ_XidouPEC=WmSoiYPlkM z6zCU9E6|m=jSMjjL^7^WB;YFILfU!RG$-$!?0iC~!$cE%0hLgG4@^qi#87^1$7Sjp zt3nDy-+N+0d`Ne4wDO_DI_ZF^kPM9DCi>8EjpkA7~$eg!S0 z{rbsEX$!BM`AS2$JN9c)i=ODLrJL8T)_`qvY0Du+tK?{fq zuS5qq&D+peDYMQR12*?g@RXzgIw*rVRtNo!cL8sKjvYiAdf2|GmdoW*IeWCm=M4p; z_r6zxIw;W^c&!OpvJtnOuPIJWzB<`?QfPqWUake8gw%iDBlSI7>MhWDk{;ip85m5b zxY}l1S*@_ViuwfwNmSNi^e)S*=$*Af0eMx3cqN)+c?~J7ogg5QhdGfo`CXSovtI{4 zh8Wrxx4mo^7Cr9~RuR!tZUKGo7}1Q_Owo2Dd&y=&oDzaKtu5LNa3#d@4Ubs^^M2KKfrk50 zr~+4cT>)x6F?ly5DSQA5Bgg>Jj^PZ%gOG_^!E}y=#-iR+iE!CQ8lI|%E@INj;(W$8 z%DwBIqr#5Sb`7~XN5*fG4TgVAN-PKaj*#pN6I`AN(E{B zJ@_pK+|#fk6aAAqO5ON8WH}YWvsZ!^)=B1exs)}Fx1o@;2hYGTF~kJet%5u18dsZL zq-Bs?QDC7xE>zVCKojrPmhPm41{--a*iYFStaSGZ-yxyj9mQr1>qMw8O$5F#ZfHIA zA=FSwaiS-gx&?I*=^mwrJlco!4LZh|bRku8chrT2KypxwV^dG0rcg|X6<%5WS}4%E zp%@@BAWQyz3bJOZS!9zQzJ;`vE8_;gV~~?jIi*2AI4E)KvoBbx&@&Bv0bSF_)JjTX z!y5A9wdBR?QW|mv4=uHz3&rDN^iX;M6?jglK*PPCf>J`qeXmEy{iMCcNRLvXB%~iU zXex$2G1<^4ChNuCX@nk%rbg;;o1Tgj5kp9C%wZqN!_wvnj~E1Al*B)*Po!;TKH|Z3 z3hok2GF8{Hu;Gx6A2q`}+Q@Vtx5N7pn&__f;&Awk#o=Lkg<04e$$q7P%SsrL%?(N( zRDgL??{JvyOR(*q^RVqnn{7?Vc?`Qdt1kCQtSY){demGac#6E`ZzUZMl&Ksq1hME}}FW$b9}w=}p-Ly%Y@GR#S5x2p^h?5$qH zE5Jzd^^7O55(-1mXkLPk{)&f>j@l-k0a(pGr1y-fu9^$%@k%ltI;OK_v!7QYO53hB zo~%;Icyj-_xgPhTgUn2LX9;gD9h}3z!fWH!jqnODYfSe81EKetUh;m9qN9hsA4I!D z-fvNK*xwoHIJCeqhdbrO>@*Q^+^xsmd6d4wrVjGALu zdu-d3QafBWt=T*-phV;?!NinGLn)z4e%hl;p0agG8oojanAPh9Dybj>P*lH$R$?3( zzq?J_6zleTZJb%F*e}zvQqaV{h@xl?9%&q!6=IBCoBA$&KHX-d0`VGjT`i(eh`Y0G z<4Fk-RfB++MovWtttuCTPlUA-!>$Z?cI-Be-=*N2-%_G&P=veL`S&yK?h?{$54vr? zY825fn<=VrfkfCCt#ut7q=N+^+E@+gsCvklu& zFA7U{SCzPWBkc;cVF&NXi*+Sb0Wir86{>+Lg0EIa&J=)+bUr!E6-7bD}|p z{Z4|jBd8w4wF|cCO4rKXYlXZE`zHs8l*VbF603SS{2dn zKPou=bDGmLA(mkI-|(>f57{iA*;Ov@(^i_CZf%466-2^@H1(8Ajq$?u8*{U>rm1H( zB2Px}q0j_GnLQQvSv5Opz~~$`-ok_MVRxEYe^+~R_Ay5-?p3{d*-23(tf#+Pl8yZ< zjbDI^F!O&Rn0c-Y+!8GPJ06z)H}??&%XFyF7}BIz=htB#+B+4CFk+ea>T*?&TC-oF z%wf4UO6?OX<@-%}qV)+EuORwN%R1GP`y*vR$;ruA`a&Bd-#Jg2gYb~0p`}ppx5a4Y z(U&^5;v+D5KTiY^6x&NFDrf|y0nuStLBtm8vmh|Fu@i^s#3Vjs*MuWxXNPIup+Y-3 zwb87=vZAO!${3U|x7V6?$nfVw>l{%IGpmkxDaads3Fa*ck6K5zykDePp~$xRAjx5z z6ceU!`|rptLbv}I;$2Fry}x~ByK8^ggfj2`7ddD5TOQ$kOc68c=Y<({xGd}vrqsXo zm{Rvh8Rk@STSP0-M1k&(xs(cu*&QA0SV_XW^xj%WrahFJbulffsgP>_9W4qi zO1$}PjpbdmZgxk^Jf_ThEoy2hO^lXevL!8)?+B7%j(k9I=rt`C!lp(3S{ODjzPv3D zjp@|1HqH7Rp@>=WtHP{!L6{Z!FiV&d_uQ+pF(fy7XAE;9zca&(@LCG*JFg5+N%(m= z`x^y2mG{FKQ0|twVd7p{1n)CPjDZCkm&J5(u({gizYETm?_inlj4NkK!0j2{*J}eK zNKEY=abx!Vz7YdXNV3uaP-UE)*%ViH#k=epF=l;NBuT85cgqjl5G#{+Tw3aDN_dCjg@}~ zyJ2G*cZI*-7pwUD7C+94Y#cH$U9c0SFsJaksFsuPs(iJi7XTKn2>w+2H*tQh!&r)} z#D5@G;%D<hB-KfBuHD78Dqo%&WAMvOV=ojHR>}Yd5Ktd(lj_I%BcV`&s zXm+vt6tb4s71rHQGYra%!dF34+0lfamHhoQQ}^PeCkj^ylo^Vflu;@eK73E9>-Tz^ zAS%lo4E8y)HuHo^@q1V$oGPgjoCQ^CfW6E2Emc0E!VRc!mP#H#qQG&ptABq~XYb&m z`X`q6EZ@gTh9>?{sEJ1$_!(NE*o!~U-|M{ig94FUep0&(ze=cdI-XLKnTfR^THb@mDQPVSS0I?9lEHxd0CT9mKdtMYlCx9xyXFG?|n3<1@SVvH%>pO_Nzc&ZOr zs09|p+q7q5JQq5MulCp0x^cDH?e=ftJ{T48y(_YtIH-NKGZ^BfzXZ2fbp|8OiHP?m zlhs;v)416*Qa_8Zy{!Mn?arvVg8V?Mty=81c%=mhw-9MrtGEs! zf-3#wBv>gDtYq90$pTn{tHvI#s(i>cX|uXgnA!yflL7Y%RX2OI%Qi8FTx&w%sg!dC zRE#%o8;NSXlM!X~F(3apXR=SxTCDkB+ z#x>;ORBf$)WBis-+ogvBYr8*KDK%w(6UGG5lypA+4@$(Sn8xZ|<_Dwi4<1W2Z!|kd z`2Yii@|0$>g#qmafvTYikPFv+gvryyXc4`v-%?Twr&Nue z72E@=(P?L`=bjc-rT2xRvzJj`Me)#*9D`EA#sA;aVWzm0Q`hb|JiWbF>N_wrzuL=0 ziNA?f=PD*7%)AH4WrIb;HIXz^8&^y{7_2%ftRPQ2t*|C?Litptcv6Y<qMc*Rrjn)7U*0GlqZp%);EzVVR z-gINTo%l@vH%Vc^35zYifL+lJdf{YFSz`{9$)5_&-NJjp$M@E!n;i|en266=wX@_bA>AFBIq6RknO7UZsxWvLAjqwQ*QDsZ;^9*0rixJ z44O&2h=D{=Yj82Dazm7;3avBM;b^crg0p0*vj28gJvce4c(xPfQMdDUd?$ML)#%wb z;qNHIG=2$}+hqWte^mMv_8&X$7Oe~DZjon@E8v@~#%Fu6$$)kaSs467h2jByFFsxI<| z<&`~S0%eKnlEPjBpQmLzSD}P;>V-n)it=$~Ia8!s4V*BsJMt}|W~YmQ%h0sNPL6-U zJvl~!JUQ0KO%p#s=qoZDYdg+iBAyM!?(dMntc+I#4DbnbnW2V>?$68R8b8K%Vuy6^ z3%bt~gt%kU|Ef!R6r@Q1hivdBPROh|7Nq_MVmE5A)Jxkyf#fPa_J;u`LA zf)wf#?@$Z_zMC-&T(BDv2@c}WJf)Ap8{p`oZo^z@48Cp^h4uIN*9j&7Q?iT_bEu1@d@k@)R8%q~XT|B?o zxV&)TwZ$uqD+}iquY~aR0ESk7a@maq_&@F?4*6I2)}L9b_zzj_f!AsoeKU_9TB=O^ zenur2)3;$4&PA^rk1lS;y(^=^xHYQw;+s=E?Tt>ahWyX7vur-jXI7g-J+5{zyPAS_ zIJ4Tksy17s+MVj^AdcS_k7<1#lm7K@ziD~T;!hfUoSenmY_h-8!y~ux9A3<8b{2&|=;hghv(bw`k!u*fA}pTw0(Yix%zx0<>Vc*(ojNL$q)Q z5vIj!Mb;&(N{D>`uXq{5Lz8Jill|EZcTAh3E^SbdqRo#Hi)IfbKqF(B+7)umAsS3z z&?X%FnX^Y2CZPWa$5CupbUC+o+>kdfn=26R#%gDEwB^%pFADlqGTZH#d}mzpp}-~I zIigk$hT~2``N5LNbQ zC%?hbm4P87a$y;9sx%)5GPi| z`cHvVZJ+ShrSNCA+c9^xUG7AI%bjnL@MjJq;V5b8sEH9ja!X{lFj&VP9agPEQ_ph?z^$r*ql>=jKE9&qI zEVJ~!nu$`j5B;;)Aud&x728N%N^?DaZQWoqeIb)NGxxxc8q?1$6@qeDPj`Fw?=~|tcd~A<5O6yy1|B5QAey{ z26zH|fX5tt8s-avBrg^RvSTv+h)X6ExMZ66heW61gG$kkn*t{$#prKEEBtwbU+<%et?zi^s?$Qmsdy8S zx6k}AqK^Z{9%pvVmh;GUnIr&m_& zJ7H=erM-mun^PSSk$r_}5GpY}AUrJ+Rhmy@+1>dxzkJpULu1=T-}F8)r3Tbcl;oVo z*4q#>TKx+!LiuyrIAh%xffnv-NeZgPAKrb1|EVBHUFgx8k9;?95;qjjIja>8nuJxL zj~`bBKOQL!YsdWg>n?wyz~#@0e?o#>dTe2)qjev4(Xhk&WxaeTOp(S>e=DqEqblk> zA5B5eAOnD^F)bHHy>|Fz9Ty^Tx%nW62x1e&d;M77 z5cILfhG36p^P29M8-CN}1{Ap5ut`YE8%c`xq5-cS@}?(ISu3y?Bt**PaIi|MYiJT` zx=5d4x}3X~T#gT(Iyz>Be32dG!M$?2Z3^p@d$6}vLqVFU0gKS?fxybfdxj=lXw0SF!2EN|IG&o&^;l(@bux^K)HYFC=*uXQE!L7<|f%_<< zRR+$Bh5z0AVduCO1+My;_OOpU7P5Je-<{Ur;8&6mObO+qs_c=5DOqSWQq~RaKd}oP z4A(oH<7FJ<^brca4p9EDZ-i`3T03Q~Mt@6iz|&dnc1-pQF4<9#BKuz@vS$q= zMQbIwu0a8}7ZQOg3xf|;d(qqs1eC7P=~f(YA-^7+i4M&~$J`1B52FO?+cYfrc5K!- zy%gk2%>HC|j_yu&9t_Cd%TCD0=pIUHWl+c6vtIY0{rd>*2{g?2T=NRF-{od+Ev~M1 zaG!8xYl;z*nBFzNFH_uX>o#lR51cg&`u&YzEuvEgUVyqy_M(VA4Arts?@!oc2_y3O zwF2G(5rE-8!WP%5L=Ea@)`(c1_$46|PkI4lpu5-(s^ba+3R1#whcMyoUxs&3gvu1| zup#L%PP6*pN5n^wAc#gd<37em+|y+3OsN`t-U*99G_>o#B2&S3_bqmU%xYbyx1 zHm|MVr?|EPv`{)uzJ`E%DSjaU$1U|}gU8vp4DxahmuBma*0B-VZ-aW=s3)C9N%b$P z+By$t{j$6aLDyx(wHE7g3r4(+%Poj;mzP@}xnhelvr6&1E$E*4K+bVb9mv|w4EOML zAT>W+{3vo`h45B;+QR2)_&|*U<4(){p0M);qiU_@v`rFeYEIl}ehr=^oV_F3CntU1 zQstBEkG+uyy~>{{Z_GR+KgC)Wu%R^IX9%sUBY#v&*(5 z3-@h~%)q1`Tj;yWP4j|hUh3QN=-?3qbdtrfV*&v4@+cyc6vjT2w;wq|p%_-`aF0yC zQc|XG^gAMF0)x!Rq4<|SoKDB7*sh_Wl#tq=@JQ|F@1;dFjRXx}AwaOOViWqDA&)!b z69afLMo|rNL{-nJT98-n`kWJOq^3~0Zl!MWNQJ6dc(R$|P-==wOZ(Mq@>Nl7XVa?* z*R@u|GQn;w@+HVrf>BL~Y&B{P94WQoWskqYaSL&bE87PA7X zlxn!!H&u2x6;RzKi=j>STMM-ANQswMiLfK(NTw3; z8KVW%$SXpPJmG7ep-77D`oHDw`cWWv{d%8qg*W{fmNYnedG0WsTH@cM*O4i%)kVa% zvb2{g!UnHgx4bIsu<}jH!832-F&J|bkDtya9wobxTmoQ{U3h&}^}UV#H*86@|2}Q+ zSea6-PX3Nysu#}GtNr?md+W1j z>T`JYW4`kM`J#SXyBL0!4`DS@0{B)EE0#9(EEV3nLR{yV-$7f6d+{m~5Hc%pwk}+V z>$0a$8Yd%Nsu#l0f}B*HiE6z*g;{G}lkp2PpfNuV;kR8imsJy3RTGThR`yG(iy2{i zc727WrN_VXK{)^mjm$X?upgW**&G!A?Z#X`Pt9hkrq- z2!T-6a)r_-1qJwCK1lLOy?!KPEWzm?^>F$h?Xzt31g^o`+M8W9lIF!u4Iq;Z5kma2T!t&@j0H#fVT7QetC&$Bp+vWkGT zHpQN?j6@MqKH;57IJvcmRJs2(s3i3O^EG_#{-J%_uPq0TaikbyBDK9uW0j?Sxr20_HK)b3lJ(I9QdQzm%Ef$|f zuZS-)bUR^NR*7->bTF(o+wFulNa$f6kolY-df};E`wOrMPqqP!J4(?1V*>Fpb z&s9q{xLsjJMc})tm+WyTXeg_gY&g3ze^WENbBR} zXlz{(+eE&GW-o%0h*mpsm;Do1uLm(jkI_@o#EuctRZ2NDgp%FW4B6aCwQ~faaeP^{^dksJ*y4z7R{8M=>V-<`Fc@pND=`k4)xF z8Be-YQw`HK-_^E1J?8>s{ko9t$J327s9Nka>ZLu-Ej|>;)2PJB_5CdR>E0DaKzw=n zjTFy1Z?2@DH`jr^jCiZabO>_*t`|u~He{=1&Y_DL{9V^Tr!h3=5PoD$t^0j@vSiO5)e`VHbHF7r1Vh4x1WtI||(GJytz-EWD-&;Fy@$jLe}y!QG}Bmuje2 z6O6vu8zK_{ZiFgtA-VLIB}d7IGm7h4>tYbst2hN{HAjj?=`1f^r@OG?yRnl`q#V@Cj1GX`E0 zWwX)jHP^Kh9LGZ>tQu~15E}bcW87aw%n`&oqAf~QfaTht;XFgI`j6vtFDv~Hwy7qz~>>J1q(}t)B+}DI|2y~-Hv@3mJcZ9h< zonw`$E-^wfv-t5Ji3uFNLQDi56Sk7@uqk3%QA!Z{7mLc2)tH{fEz@`onO*VmewShbyWHLZh2w&@F4+lvG_x z;n^OmpvZgG9*5Z;y;gkdC@qsB%I@!qRsT^Cx5Lr#vTX?!hZ}<_75A9EXOut<#paFG zhbPKi_K9p#s*qF+i82z-^wh?3&jKi_VvB^u4EsYggYq1X0PES#vT}Z=y`YH)R18>n zHo!-njqwI^K1l;caO&*B<<}M)=NH~sI=|4kw0ODkrNzZBRNI}kDbaE!x^(&CwWZVe za`nwii_6xyuFpgl78g%np)ZYV3+G;6yrT9D6r4Gv@nWCA%w(SIx&twd8>z*XYl4}* z{#r3K`%{j-P_x12lm*H{gdC!%!=^`qnhOi(F)P_4&!pIKrx^Y=ObzY>`=AkVkYtp6 zEVFaEx;}=fgm;3cT1_lkkc78moXgV-R6<8t)N62n31*r_;bL%2f{KYJ+?}C!&1O_h z(jl$c6!l13an>>%rOE65MR$p0A-W3JAh=Monk&R4P^gKGzfGdxr-e*a^k%lV6d_Jr0`tk? zQqsHx-v446@00)jev2U!xQZtk&7<)E#`mg1xDF9iC(Nj193*f?WfepVHxup}v?%OV zTw3Q#)U?JWeL?x1YhH%Jxm-Bk3H2d1naFga#?@_#BFc243(d4ANtd!MmJO`Ax-Mxf z{HBkrTY1X3&cTGTR^6QCv%)@OUd?oK9a&?{T*p3gDl5s)+}7$%eh^w#f59kC?}<+g zBpjh5!NWp9mA=KumvH*`a z2hbPU`wIb>YL);DUMmE)+bjVTe*IAkcW%VtY_SgPHYGX}Nz@u0DAgkP(bY?I(e1;d zPLf}=6QeH?IV!qNx8 zj74c84>Vud!RhoWPStxY@fv&Z4j`^ICx@xhyGVE5RJO1O#I@#}K0Mo+Zx~a=YV*ha zQu8l~-JE@?`F>n#-beEEi+fbww5A!PS^LF%3^Bo*S zaiql^wr)I@iFc@S0)FkRITiPaJkykIYxa^(X44e6f;{Fi5cZI9## z+#m_6?JOUa+ zRHu)TuY5s#ztWB4O*%Xr^v7%KqU8_mrK%3yPS zfEyz3sOG)+=2Yd&UtU=L%5tsQ-CS?hu3vwC|7}t0j#c{QFMk)@GNRjBZRxcO7cVcK zg0M|TcV_lY^8`K*-u~wMabT|3k?%8K%_W|@)QTj)F+aqLLk)x!BKgz^2|-wmGYW#M z`^ibDDcp3X%p~)2b;r>HE6;4Wo)sO>LkwGk4ib{Y2nF84**ygTP}D)Yk5Gbjm>X_B zkpfM40wQg||K?jGKZ`Z;v-TSK-`jy1MW&+^xmYsgVk8>UDs_;bfS1J_q}Xq@#+$+$ zBIB2F=tOTB911OG;bwV@S-2%4bgP)uj{I}`g5%{_gbP9X^Z`S&GO zktQ6+jy2W4{DbQye%V%k(5@n2LsAR-3>@ack%5ct?HExZ^qQ;@GsfoYpxM>#Q!@k% zVDR>MJm?`D9WT}PhA?$Sw2jxyz*j)ZLyYb*V}#Q6;q8UYhx|UM7RR8ZCZJ6eFqrq) zog=>3nV)*ghdfA$!(U8*Q|iwW+H$nCSPY=65p1h2mPi{)(vUpYJDsy&8;ZV>>Pyep zFv*U4OtNe}r39PRh*#sq*)ZFCG-xPa%KxR0 zdXkO657`?56SA7KAiDfjHEY23<)=6#(X3D6{zUtPd4@sR2nRPh!;u!Zke1Um^I2Vi z?DW1i9w2=MNN*`Ip;wF@j5Ex&akn`zbwW2@9S!2O+%d{}c_UQdRNT3Lga&tVZg(%O z6-B~aXy*ma=0cTDh9k`jEbuQg8`iIt;JE*o=D2H?>{(+_(*sk;$6YiQeD!7`JRoM^ zjo+2ZY#}T;ulU+=q&bM=cd!s)uQKWsK;B6q!$}w^Rwn3Z14s$9e&jwCW0eT&cE=&z@T16E<|2T6_R8kr3OV)u6J;SLa1s^HBVQq z+ImrtxoSdzA2K<|94vO<5!JeKe#x9SRneQg6LJKtByM`+jaoDp?1g5L+XX5)@WB*> zIbSzg6Ui%Pz=TE)4>E-T!%|_S;tI%-fXdt+R`|GP?yeyv13V$a5MDbXGRVDQ&3E~l z84+1XfPqqE7=k&1Ykry#M7(j4Rr$P7hs!18_ER3Y{f52EkTcI1njy$j^PIX&r?*KM zTf`~?N)kf0IbK1cC74CM_EZI5uoD(42y$>oTAU6R0*zI2oOF9LK9M?yRp@}!hmiDn zJ37LF$L2*54MoPK&%D&Be$3hIf@TqV#oJ>F`FY);K@lw@x)fT54fU{|@nMlDq7{sH z;6B3Vja{^n!}scgyMw8Wt^|hYzxbCm3NlH&Y}+M5G=P$jhEQS{)<_q3rjg7XegzDS zuLyPYW(jpP?NLW}yk>-n2XkBs30RZ7Mg?ypDUh5k0cl#~*b%#~)XV_~G#Xd&DMXJ# zGr{?_nOP&-+)1)GW(a|2aCt(MDk|rB@-frbU^{}6tB?NzpI3J9`%Ulzq4;r$Tf?^v*=hA zvfkGs>nu+Jsr4;Kf}KsG1sZb|o4rL_kI1{jfmvhrAhZAxVI>|R;1avKBaOLZ=$HgT zmYta5-0ci5(z3$g|2kEU5Y~xHwBSfT{5CoJnt_?!VO<- z+)MTq@An)3T1`X1X^H$C& zwZigAn;8O}LUf*FrW)YH3ckU92gf3;103$ReMG6&imqYa{(KoTa1h_&ySa15s**7C5o(K|wHZD`F?PC!OQQm4Lt;J}{b5ta)LD znbQY2#L;rTR1PP{{9&WaJHJ(2y1@A}UCk~qLv}XIAI6cMZdH1E9vH!eutxL96E9k2 zyK%EEvQ5t)_G4-o-GY7jNQOhv=e?J`v?d zWqA^nLN8h0e4&N0i+*v-9-c9TWzs4DurEdDIyVSyjI1+*4zNBX9G+=zbh=xj(lNq6 z4!eMbg-yEQi+Nuf^jBD$66ypZlgI*WLQ-)HBDfUmE7nr1gp{sg4!`E`a}I0WJpP`? z-}6{g=dpm!qs}~*#`$BZ$GAu@kY*AKnYzC%nU9@Q_M-x_I@~6r&UB(!PAI)ns9ESO z0yQ3F1glhlGT%Oh@_%UROs?7+asktzjaMOwT86HGH5K24g=G;F3PhG$5nMcBQaHhknF2hAlQP)G*C+!j zXBjK3Gi1+3Q`$zsz-vNO3FTR;f_u&5po|{mCm%~8-J0>bx{dBIN4;8Np%XCq%t3N& z5$=+yLR9Xy7&@P@WP&NdX+P}Yw7nnlOx=WEn(Mkvg9YVWjgnv}`uvM%Uuqg%Ji87AbwPna)w( z(~*cv2jN&hGX)hwST9~Hp%-ycZ3VCQvP&E}38ha# z7_?ZZhMRCS7Yg~F_-A4zKBQOTVxUXt&mZ&X&;P+*sf+b#=+s2(8Bb0KbKX#H5-nUV zoa}Vy(M4RieK`Z(V3_jqX#p87YN0f^M=*QHTVu_-Dw}SYoz2=j_PYq417x=i-w}k9 zmLQa)tXDWVyH$Z(4}>w1Gu=2#C}J-BmJop_y#O*8z1Tw=KY5??&;|-*;z}J<%{cRR zZ}7Zah~+5>-QAiq@r^wa zXV@Px1!Q3*Swk!a4mb#VoZU;EdCf$!(we@j7f+^o)8t5Wr0u0`%r49a$Mg9h zFn&q*`+TYX9!er!soJc{>W90W6Tc^T;i&-F4B8iyzF&2v4+XCDP5cZYF)#wj5@skH zkwI=HIa_Dqyjo6&DB!UwJc~?>q1XaMwF5z}^KqzgDZ&SaUd1_b*c5nnJ(d`CnC$lR zMQ4>BHJD+)5FqrXHH@TqFmoVL_x}{seLUSdgRrhp|MN7(aK%!|v^k`F@l`a?Vk<>6 zEm-{6PI}y`i!d@z8ff!hXW!4~n;eRzW0+X0o-lFxi2jz`6tG0+{}#yoOb}WIj*AJ; zzjTEM1+MU1AW{T};EODC=0y}ZX7csHauCCmDBx&F2A&FvD@BVx6tpl9k%G5lYW#bb z8Ypn7ammJAY7hnKanz*8;j%Ep6gg8^HXJ75^IN*QRf;PApPGV{`E_t(-5WiWOL@}B ze`A-oo&`2XCZvpu7^XO6<9wf#h4zkd{IZK<6u3B!3C9KJU}FtZfcIWcMQ=ox4IwZ= zSrWkc5X`R`$g(?%we0MDJ`0`@So@r%+|MCDZg*jfRCa^TXv_Fyr0@ey zQz`uHoIgP*Ng4|6INB6PGIcaRiFf`lcEwJqbgvhLFNidHwDa zOZ^M-6CNp4K4X8M8FJeCHVu##HD^Qt%RN3~r)1h?ver;V zdlxt!h5g>TN^*`orOMb82r>>U4vbN?!vXbO*}G5}3XWq_YT8QjCF0zbDQ zuARM7Tx*{Ra(78N#z2b5aX|rPVSd(-SftGx^x#U7sNB6WO(% zxV(5~@$%(`bI1aSw_=t~H?E$)6qxfjjDftnsWCrdr5s$UymupEmK15fzHe{cPK$XT zQhx2FlwaSow+>xxzsBpKTdn3pKKFpchu)8LsQ^KU9IS{N13F;wu$y~ue}QV=yd{SX zB73bberO2gz8^Ad_1X1tMCO(9J)hbu(~#@M<0SnLK8n%?p@HbqM{c zBF z7sp$&A|~BwEfCupzw8BT7E(0W5%}-o)C7M0)8b&8yK`Bf3?0hc1IQY(PnvN6Xus*H z;^joJu(S=#po=miSHN^6YZxk}RpxAR2qO@Gsz$~l?lTdzBN(~WL_^8H9EwZVF#N=o zfg4F|a}pG%KD`|eknhVVXN5xhy18Jw!ZPR~v1+P#E- z?Fe3vVoy{gGL9nU<*1o^kquh1BDCb=+O*Y;ODM{}npTt({}XNd(ooezcdlvlKsB)e zQyqjJh*_Th&o7^dW@;)|V3AV$(a=b?jsf1?Odrvy>eySuoH zjXczx1J!_2g1$eKrtjqI_Co0E!JzfHM_H29u7n6eZ<;jLklv9Fu!wNU&IIa?9=zy? zkLv;CB4Bt|dm7Ih63bKhDRSu(=-p8rgA(9C*h;aURlEF=bMO3rh%K8O=k z62Idnlys|!DdZ!zM%2g$l(YC~lgXG&wHRbMMDcE|M30vQN)#-#65X;%a#XCfyUf2s z^t;tc}YBE5CH;$a@h+}@|y*m1!veCZymF3wNj$OY!H#0YX=b0Bd-Gxs? z(Iihc397oNWI0(s6CApv1A9iWUo!nB_-Xo0@N*k}6QEzZIlGMh;%-j#SHwM%>++x( z)+!cLU5Q8IO{2tcZa(R8ZrZzZw{c>@>5Nm9|98x%CiNg^E>)i3S^9Ot*evX z|0CD;>X?cs5Aj9=F?t*gBet%ouy)Sj^@?F>=zi!nxNS$$@)-UnM#cz!I>y_FUSC51 zus+cJ*}Q+6cw6!Yo_ThknWTB-HkT%XZF%VlCkuTBu4WifoJST z&A}+4tOzOgIc+hU#QxK*aL4^BuD?~^#^Q_Dhuh7q=yTYmRq@A==kL*Oy0Kryv7{hv ziyRlOxX=ap(K?=UnLC7eZ4DdERTTL)Zqt_T(=ddLDrOHaNA?abEd2e!8eVS3(=s@M z$Xk^C zP$mZwknk}Ql{QCHl>`)|yy68$A3WfgIFhlK6EI~)Bp%SWLsMW5Ku?^MZsdJ#Z5#ymZR(5)Apk>HY z*QiRdloHv=K!m2hi!_i+1&`QfQ+_unZ>8~n_e@m3C+zuF?cv%LJutkze>@OzkfO^h9;p|{grud0Q?<4JjqzJz!P@cAgc@))UgpUBO&C*R0To+C&)g3Lv`#K7BB4eH zxel;$vYMuE4l#GO;s^R{*tE(Sf?YXl z{de^wOi12e;Y`kct;R%v+WUm}bzd<2KebwTU+1yS;GCzOC@-r8wtDjUl_U-=2V{vI z;lKCn2>&}f4lSoMg($2(*;aWGZ;#>YY_?&?(S3fQ*i70q*p;9Xh+8HdWh1*ffN_sl+98h{ts;!sn~7bB*ceocV4 zKsdLpu52*79Tw;9DPc!I^DbAmS=gvBCejxf&Oal=Gi0{EUrlPlbUgm(y$;IQ;&f4KyL*XH) z@sKhW{p5SEoDS7&!&E+0P|Hy`Z9&h~B|+XKd6;Tjg07FG={otkt+y0ZHAhfX6*byp zzG$rXIED{hR~H;0b%$zsfP9E}Vu#cU62{>s`X<5!gjd$HGg8fX(KqVnoJ0z*i)sx2 zhw4Y3GkSU&;vpa?%T60nvq}9O^+T=}Lw(q(xYXbjy22dvdO;47GoWxWWXFYjnw}X{ z-3$#170@7W3KlyGw<860BN9TOCm(nT9;|qH@FANA3wNu~2&VI|qC9?D9v#O%msd5K zkPTU)j$au^eXk49EZNw=cOK`6e*JBIYUq@ubW7tU%wF@Q*sB2VGzIS@0iIJSrdb{Di{ZljwLq&S`?#pIv2Wpo<@P)JUs)i}j^tFzf?Z}ts^CH>J^ zW+)Ull3+A@YjzSD@7SzOtcn})*JNtJP8cEgFOHQG#Ttw$_QKiLo;AfOU=?r*haWSy z_|$~`Mu2}XDZnNRD$;oQpReAX$maj7!&j+2?or7mz|Vc==laC=m0-$qX{Ma`JES18 z`UbCo$0gB zR%-U>!z5YE77bwL6c%yScLRTt8tRMDGMBWfjh;amRzX}C;}UdLUE~eRD}crX%2L&( zg}ub_!z~OwU-h|HIN0ELHCwA%jveLGNqkIFr3OFN~=ToEe#ML~rF zxxg~$;NBDeo-~3d_wYiO+lzr@Iu@pg3Pgz9?749auo{Kksoj~p%=mmvDts=>PpKtE zh3)u#+J?BY1KmVIaQa>=Vjt0+kB-!1`)BX6JbiR`j?mtRwA& zKdB9wqj30~sfb$q385CB@U<_Y3BT#lgnx_U(0zbESjvx8#rsI>dHpV$fxTb9qga#Z z?L@KKf-0OPwxC+a%wgHgu^~wW)CzB@PjMPtL`;8L+K@S*N=WRFdn9&iuToYS!`;5{ zQjCEF?B&w;+}3G#@YX0ByYDxd|F*YuN?2N6-q~IK=k3C0T6!xQv6oqqPurQY-w?~0 zyuVSR2i3i&?QBH!9#QDBDil;y)4Pn_-HLdGpv;>YTwYR2w4F5M-*d=c7S(zcUdLa{J{VG7imdgm$V&d3ypq=^ejsC^E_Md@ zU%F>-C~(iycdg7*T$O$=kvdoda=Y(^XI;P6urWyTsN=29VI zdf75j14YRBzY4?bb8^@@5O+-Tf9%p61u2^UltJ^H0i~(#ZIDNIZ=({FKU#joVcLH_ zoA${n;9>A`#Qz;B%Rjhdy8a87t|&;+^^e#z=S&oQbepA$(uDQQw$N?L4AFKLV}#h~ zoUg@O!2qM9QKWj2ZL~*6-#0gO1iwgDkc0{cVOBX;lvTV8UXEG*ccCfdrG6q{4$vJl z)gQP_g#wqUChz4K=meuVgHkw6mI-fzGMwcF;2H-W-YV3t9Cy`h3G?=lP+j37%wP74 zM5%*R({u`4B$R6qzkK%zvwovVpJwSrJiB~_%Ztbhl%k`wuS9p&-R` z&oIvw7>+gM1|DWM+cZ|l#J5VC!G+4IwoZ|Gv6cp^n z8z>U)tc0$HwvFU~2!4~v0VnU!G#JOpUE8I~UgX-Pfl}>gVZ;t8t~QOPJGO=Vx_Gaw`Lm;sgI!;_DA zD;{VDT%!}zPb!d+G_0S6F|9Q`bBOi;ia>-n zOjv73ai%bIowS>YLuf@=$(Y{t?2FI|I3C8;QLBgxAw-^$#+^{svhj~TMRMd9^=dVI-e9eE6GvdfGDB2PJ8s$XY35C z4sd0HvU=fcU7Yz`)%rS8EsBS%;$~|-YWJgeRM9)kJ^bLbyhyCRR55qThM4?r-bz)L zg01Ux+Sln+NB`c$9iZx)#P~>VS#qcJPzY7#wCVS8IUSKwGO60UWmm=TmsQo$ zLrnQW?cAh_0VEqMHVF%e{YY~G0U3_soV3IzCm|i56VmadUU=2WsC^01xa<*)XYCgV zOvq}&z^i1YU62bJG84*VjhzbuYkctjwz!_h!z()=XkNpe{MK6y!L@S5HwC&w`PRY7 z$R;sBuXwJcg&Q}`))rt)@o;DbY)8-I$*0-r=-DV?c*21y$7(gJWkUDOHC~SR!SQqt z+_5H#v1;k|op$E(E2&)V#dy&I&nvBudu=RQqjfA>j0d^Ei%|CT07$bLQ&cN1_1Ph$ z?5Cv}Mni;D(gVCFhg87Bs41ENV^Mr-6Um5sqXNr#LJJ z>oqb4=-$p+JjhA@ponpEy^m~@__cz>$u=F-2xiL+!S}L&>PrzGFGHldBIQj)6#q~E z#lNidQYpS9ION}oH_|nXCwKdUzi#SU14@Po5L25$zOJsmVBT~w%`^Sr7PzK>i0o0c z4(!s<4ZwG8@G^A{C%$_B4&7Ol_{>{lr$E}Du+ni38&YdjerlltD(8w&InU(-E1_`S z@hF^2yzkBL#!xqk0c_QRm8`I`5fDhOVFdcYmDDoozrAzFXhBU=A8i!8VY5;5}qSHC|C$RtAg1&^^vx_G#ymp z9hVph3gth%+rnF??!0*W)iD z@Xng*AvFLJ96-D+45^wVvQ!3)hXb^4Cf7=Hti zGGUhx^1tj6@^#+xW%eMKPC7SHBQ?ZSpHNiUbp}pHo@z=fBi=`9%+Jmr;BFcu!IlNpM#CVNq|LxwL3ZBoo1J1)3 z9Oy`E3B1F{I>)T;eg!WJH+N6?w|$-_qZ|LyWWGI&0rAU^vLnt^7w|7|@JMNdhdJ}b z9L^+VA^7ry$%h|No;1ygCTAL4xFxvoVFOME&lQVF{m=F}d0|i>!$0&NE3< z^s{=rV19O>k?IsC^g}WMAFl$U&e${>j7fVt<_2e$&zx1mV%>Eyw8D;VZY`<0MNg8{D#FmldALeD}^!4V?&FQJBcL{Xl zqcU^)>M@bvkSm^-(*q?ZE2pOgUeI%xqexE9FW9HMp7_%g*m4;;kL2)sdhL*!kCS43 zjMoox(XMy+Y--lfb`w9y++1JD;K^b-?$=x$hXPl}agyWoXu*(JP~-^3TATc)@QKQ$ zifP*Lp2^ZlwvJ5boc5JSuMs4!tDRfeY4Q<9<0jSgOF}Uq^jN^OsjIq$Hp^q>I z{Pvkfda%YJTn&f#!%mx?)s6+XmvNp-Duf%#4RWT2O3@mlZ4%;Nff8_*{`fRd&UO3>) z&?FzgIOyE^XP2MFmC57eJosyKn3_9$yLZ+A@LLray(zj?3sJCw?8aPwUB%JJwT zTpCwkjJ8HNCBHev(<7wG52 zBS%e$N9HvQf_PZ}B8bNh3xEeR0ltJb$q*0G&t!;)^e+Z@OaMHT36KVn06ch9gJ6v4 zUj*=w9O2GGRgD^Uy=ZiW&%895#`VkJ*G6kxr2!CpzJU& zWkNiB$V6f$#Q9kX@mMxQ3@RZDFmKY?#^O;)me~>j4`-2OZuXFv^jtPb8;_2-*khEl zzEfQt#PQqg@u`0v;`(Rq{f=0AbR!yyUz)V(F%4euCCy=Pd|(P2S&& zDIyAw;^SIa(RWjRU?2w9WL?3#p5spjS; zf_M29Vu?B42vimFW};9HvD`OrO`AJm_M#;t3Xx%#Xsfm@KH7ddgSNWej%oWDm$oP< zPFp>WcbB%xPz%#mP`}eFMq51%wtl^|b>fyCx#j$dfTFq$OYD9@)u#e2c1+I~TzaCw zrRU@Y_ICz`kRs&@RV2}rQV2KgIG*BC_Ji|@4IFYYNh$+n3B*p}T=O!TUZzKes;eEm z4zaQ|g*tqSD-U^aP}lF$sSP$n@{Lk*ql-L(-DXYvu@bk3HAM2ahja*tNMoGC;$Fl!MQc!@^gIoI&==wSQgtnNsb@NgT1ntn6K*pK6{Rf(gXe_qE1|alFYK7L zaM;C@_9=`Py{x5M?3lG)c3BGrDc1U@9@f%B`1WHhIJ<}|Ext0iMBShw>7jZ!Pc&qr zRy)7&M&s4R(^pt1Jp9PX3N-VoB@MNOJIm8k2$Gkx6+k)<)4e3iV#;ad;crdbu8Ov_zaV&hszB=<^ZgfGzDI$}_Y*(B=1=}y zK%b|L`I4_QnJBSIv)gSTxrtblS0b_Dp_@Z5ku5bfSFM^g zrmN`V1mCWdVJFtj#bJDlV_K%I)yS#>Zt+xU$D?MaJ8baviU!$NaTB*GSqYt(>Is%I z??_58qCq9UKV4A;M>vNeA{~mM_zKBMm?OVXm?JYatcMeqg}Nd_6w}f>=D=Gn2cp2` zz=?lAa$R^#?+)YTaTP}4uz`41q$p-J`PB&vtBRH&&|_D>bg}W~;=<)CI8AAsUU;+Y zIm!4qnUJbC1=h&eW&t57+7375>a@zsQY#r%j{Hr|H)OO`i(1*fAx4+NC54 zQk48@qGVtMpr86;kt#tstS+6FPFKDA6y!~r>d%L0uT(nW$hJ;1{m|>3HA?D2RzV-R z6R_&tQsKy^i6%phpD|pgzLptubWgJXewsi{qEAi_pp#KU`(gAxH98Sh#Kn(+JChlK{lQD{g}{@hYCC5{}2iTcd#xiO+@`WniKok#mZlMCsm_H1jICvOiG5*nUw?vE_=Re_vo?hrrp$gb(WT25 zuPvR%x2tbnT3ohwFhRQb&>b6+gK!ET`geeGpGP z;Cy@;+aC@QLC_fNLY6RGrr%E@FMA4!jaR|Fl4*8q=76;KpA+8@q8Mc~+p#SEhAWFG zNXg>cEQ=Y#0M>0`RCRYt8Wp?`tT-Me8HY^1=hCP!xl7`xz(EIC>Qj}|Nr?QQir`*W zE?`3<_1Az%K0_j@D(#|74#%6UpF$uVnf#`d$&6+@mdW3BWfBD`ncNcVV|er_nN&mG zEtypCKG-t(lDqD{2MeSm;x37#qKhk%s@xDsRpb{*{WVJ@Ri%*pq`V9he@%$cOP9`G zUbwP&rEzZQ3ybI8Y+Stvr^)H1QwvuY8;fr&UAek+;kCx)#f2*uFEps|wTqYEWYO}( z-Uh-_|E=MOxR$jt*J|4sjB-^>{^N;lv<7vSA)=MjaSNv|`~-&ln{pJ=m&@_$crA{_ zkA>k@cf29~e*LWh(o)I~;zy^6=x=JYFxc1 zu4r){iS44{W>fX{YG)0Zm~f_qySsyt8f|l9Q&k^#B|gp|eWMx?(tzM%^bm(UqU3bk zq#Riip)t}$$wrr&sMwC0H=7dlr9lT5G)2|3{UPTQ#jopbXyad)_zrnM&i5mE(kkU! zLZuwvh8#l0ytep8NyYLX4aM^1T~{n(NJ_m-{MNQ-1s!u4dCqQaR>wVv3Pr(e0~Rhj zZ_@4N&GiA~>Kz4=g6}I|{_@K5SC(td?&f;)`t|4c-xihb=)xLGQ3+R5#7JtjrPnT8 zyu5e{svozYXZB6=JmHs~_=yk5SiKuR=SddF0|TWAr6Y3iZosuQ!gjh5-|9dkBk@5C zzRI=!V9OVBF!3vbwPy-~*s<~X|95xwF>+m3J#+VCc6KMNRJ8;*sBG=FI3=L0NuB07 zjjtoyiHqa9_PTW%MU&at+1;VLJIj1Hbs(w$2_%BlrobOmEgzKt6^f{kkf4aD0x3lx zls|wm5kK4@?xK;FV|&xx$pB>z?1TPs z5KX3q;a&M(9~vV^I7aXxhmn^EBl*d3`2NK_%Wfqvpo#OE2Z1Uc3z;#dyqME)Og*W8 zeedeYr&QV8B>VDC^#$OwY6zGY7U(#2$$Ove>teNp>6yBi`ew-s5A94u)2%S)L9ml=B z=#<3CbhN)pFZs!X>HS?N^8le<=-!{;*pGQbo3Z{UnVbx$9+-^Y1I)q(Vp#xu;@g z(=q4h{A4wQVK)fWcva)^O@)IZ$gCEzxWG9QA95V|8|*mzh2M5`BY(%kWtNzOs^q6J zJ;NS^m`9@ia*Gic*OrF2QOg8+hwANHZK-M)yuOc8!NWZ&d#*}l=2-G88kKkD!5kWg z*EtUHf#dK|I+Og|$Jw%pciAUmx_7uC1eFU}0aWop$AfwXG{V1Icx&CEl8^|}kGrWA zS?$38Ngw$47K1zV!4LSs;{!kV%g(_Ewp0-TYxlVrxW6XMVob!NI)>0Y`rW>EZBtV5 zcHg7@*BWV$0s=X*|5uF#vek%ZLZA+fhG#h%@PVVD@sD(7kyRYeHbG2)Jwk7JVn?Zv z>{qZ6Ld@ci(XX#?dDO+Ta6)<*7DD!lDXB-3A%e#kk5U#Zuo;ac01vI6^oYdVAPSG& z-Ec91$fzh}Nkykr za$;0EkW-bRmJ}l+$|g^RC?qJLRG}y+++wL2l2}#9ndnsSg$Vnt&pi3~>UF0!r2do2 zjeT?ZJ`BxM?@1zXY8gUeNxf#$r{W?B8Nirw)lBbLk#%PBxl0uztxhJz4905xu&aQr zlcy!{+R3UsCGKcwruwcNghTVuCpaJB1Lvd07f9UZ=5~=%gLB;KOPmqReVemFkRn|; zM1)#wuAL;(bpNI(#INY2-mymaV^FMW%itNWTU!SI^lHnb#a&J{K4;2{=r(}lQkDbj#* z!?R9$2+dIuLD&=Y*oQogsNX~#i}V;I-0yEsb`(Ymn?PMSdbj=gjr3tnT0>?x#q>TZFaY$LflQc6ctx%=*pgMH9zcUl+`OvSz`!@o{YW@^Pf==#g z`B7l$&s|erk{q3pAc9IqWf^b3FQfQ4r$H_EN8Mc%6;O|b16+o(vUpCnsVWAHhrI!Q zOs^l~%qPVc+O`ARqv`f$o~#Djy&Pb>O`q*%UdAopMCUN!Ty)Npv8%Vn!?Ws%?_5?@ zPjS`r^-5fL`&s&`$I>1mQ}L`cr%_`C3}%U~n9DbAC6`lUsnK44b3o4zDl+)nv=V)! z4uj|BslnT?26+4F+Ps}xfj#MrN6fw5SBko+p*2K|g0(ed|DX8!J6HvO+wt|Kx_n(o zXvHk;zx`j2n8>&g4ThWWM;p_ml1;4C^8K1?-YNs({5*Dx4Zwr z4)y9#Q32cdxPqy9nqTLtL9RjK-w2TS&?oU~bK3LEv`xwNtN4wym9^IXwn<7b^oJ&Ma334E( zxVM+ouaQK3H|aRjrXw(gP1*|eB{N7>HQe!*Q8gLg>F#&XU8F;057FRO#q0duvMSLd zj9rTYLwCwG3s!Rdy7;H(*OdZaP&2$j$!k^H`&2(y?)%ggatH%VR^4;;zHRzmFh!@*(|YB zitFtXnl^*n{2G&_2r<+yp=ks~i<04_c$RBezSnrxi4@PblbT5-QhcJ#H7klo^f%v^ zg$c9ZyK^Iy;%&?Ppo#|~`wgzT9(66DVk1(VUFK@BeDHYEKak?ea`LdVI26<@9%&z7 zc5H`rDV|_anadO8V;(pZkx_eEkE){@b4&51 zCC(~^V~3;d?*3q`O14Vz&r94oDI5qs*+x2xJ02Mts*@{~|B~YCOO-b;7=Zyc(Nw6T z7#CIjT3qlKuER2c6t8b3*PQbK!xavKx<^7@XQw+xb>01~0Ywc_>(B#r3XnMx*Ox+XoHiIX{9z!^AB6xa^q+G7m^6vPGoIS-C^`%yFu_~z2b^S|=D?`3R zmq5mNDZD!bcPhKd(hv^nn=K~WE}IGp-a@aOJAdxVl`|JnS_4(JE}ZSGKYm$?pIS=Z z;r%QyHk0k6F%q?UQoO)LdUOGn|cd~XPGMU})eqiAD^$(_gW z>;BGgH*5y#$H_{NX)BoOY)J9BMaC{6C|Ok!Qy7IRqCAEseHYJNy?P1%L9H()k9(M$ z366ejjf>(UJFpP6?5yfbLi+cyrhs}vz}<$8Uf z{ofbaB_Tf8rXH)(*0=^PGA&awTH8%)9s9&YiaVRhmD2OgPQ+MVlw+@6uA{wxg=Jp6 zNpW{GdC%cMx=Gkl+|x{Yv%#a9@Gh+4H9yd-b&xPa@~vn{F& zQ-%7|nV)Ym-%A_>BosDjuQ;v1K$uu8T!dnVt%RE0P^p%Yui zLrY9eo(FmFQ}(p8-Aw#aFXsuQ8c~`u(Yt%Y>Hb8DFE21E3BgH{bB|xX_?{=w3-{{! zne}U^O(wPLF8&y zR}X};M=&dKn*de4xWMf1t5mHf*DI)?(RAnP85qw}{M#H8{$VJ`baTfw_8=R}`0rW( zPUHbB&vOq-a3ARkyobYBz>!+xPjvYBz*+t^;|I{atYEV3eguZo>Pxfg20f zv03q0$LhW_&MjkHar|ZR?~Jm4E93)I6Ob#as<6kjBDhaztBM9i>bHM@`NBN2y$euuFdgAwfT07#A8^8e1OrYLG_dB@ug-JtYw z6j@TwrgS-bDgJAoyD-Bm+XfkcCSYZuj6F4l+e@3QA$w$@nn1yr$qpLu8m*b*fY&Wl zJ0=HL8EGi2*_VYl^EWRfm#YxQ#`I=?wAR^$*@VM+W<(x0>iL;Lrj$$oysr+x6BPiS zuBOk9L2dVNX&}*Ockb--(gJgj6)*siqcu35T3|P?f-wbxf3Q#>3b;EHIH87oxc3-d zaDxK+s(gK}K&h9*nmjY?kVOTvZF{Z&*@aN7PuhtbX~Xbv(6Rh zMm|0sEO}v$-9ap(IGD1S$tUM3qRbwF6NciElTXjFn_khP>>0;h?7u(9uCPVmDm(38 znq$5b3lZqOkoC57q=RcF6Gq@HCLxE~kII)tG%Up_QJ_pKfbD+>LJw_;joJKe!L!By zgG|{9pvXm}{M4yMPY!qWlmU4eB6+{FuS^|Q0BnT|DeY9_f`zBp`<6)dXN3!`F;c}j z$5@2cuBpET!scipAkF&jTKcSseLGOYqya}X|aN6g(zUos@sL#??e1EQDCrDfN0m% zA@7&kymzEu6v@*yi4>vu-Uned`}^0=$|;Be>%cjUFN?&D^;F@m@C0f?RSO_L$$to* z9#@J;J&B9Kq8;2ZH{%hxz+Ga8qR~Vf{2Ob5)fsH1CYUQFrTCvlSieT0Q-^LyZlrzT^#xtH=z|n1g82*0 zZlkbt-1CSCoAW{EG6aXV&ivR}hH#Wk`Jq|4po^xH%NW5$$KN2F3%3!O9)J`^%Ck{1LVSw@MOed{F0c$7B z{q-gs=jh9T9KuG}hK(PIA_V1!P;ik;*a++1AQ*!uH~<4Nll?~co>>AZjegir#fR%0 zlUY#;1cGn^4?-4#`Di0-%LP}(!Nfu!zt#vl#)5#egEQO=k@tIz@HMXlfIX%^ZGR4~!rFy|+971)$rmT6!__$(9k ze{_o5Rc?l1@?=OT)}5hC(E>_End~6!P02a(xv=pNhpg#Wlbvk*beP5CAh1#78j&tk zK2+sZBBzHkT*;{<8@~`X^(w*5e3#ZXBmWSxE-3N`*q;iU0zudmaB+J5Xzo2N8=nme z+#(oUx*18*_><~OK`8dU*DkC-(YbQw(xYe*^~e*dA+>D$RUH^-&z(PW?c#dJgC!e( F_kVnv8e0GW literal 0 HcmV?d00001 diff --git a/app/models/validations/.yardoc/proxy_types b/app/models/validations/.yardoc/proxy_types new file mode 100644 index 0000000000000000000000000000000000000000..beefda1ae32c2cef8eb53a4f3c8407a532a22b51 GIT binary patch literal 4 LcmZSKsAd2F0U`j1 literal 0 HcmV?d00001 diff --git a/app/models/validations/doc/Validations/DateValidations.html b/app/models/validations/doc/Validations/DateValidations.html new file mode 100644 index 000000000..aedff3786 --- /dev/null +++ b/app/models/validations/doc/Validations/DateValidations.html @@ -0,0 +1,360 @@ + + + + + + + Module: Validations::DateValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::DateValidations + + + +

+
+ + + + + + +
+
Includes:
+
SharedValidations
+
+ + + + + + +
+
Defined in:
+
date_validations.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + #validate_property_major_repairs(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+
+
# File 'date_validations.rb', line 4
+
+def validate_property_major_repairs(record)
+  date_valid?("mrcdate", record)
+  if record["startdate"].present? && record["mrcdate"].present? && record["startdate"] < record["mrcdate"]
+    record.errors.add :mrcdate, I18n.t("validations.property.mrcdate.before_tenancy_start")
+  end
+
+  if is_rsnvac_first_let?(record) && record["mrcdate"].present?
+    record.errors.add :mrcdate, I18n.t("validations.property.mrcdate.not_first_let")
+  end
+
+  if record["mrcdate"].present? && record["startdate"].present? && record["startdate"].to_date - record["mrcdate"].to_date > 3650
+    record.errors.add :mrcdate, I18n.t("validations.property.mrcdate.ten_years_before_tenancy_start")
+  end
+end
+
+
+ +
+

+ + #validate_property_void_date(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+
+
# File 'date_validations.rb', line 19
+
+def validate_property_void_date(record)
+  if record["voiddate"].present? && record["startdate"].present? && record["startdate"].to_date - record["voiddate"].to_date > 3650
+    record.errors.add :voiddate, I18n.t("validations.property.void_date.ten_years_before_tenancy_start")
+  end
+
+  if record["voiddate"].present? && record["startdate"].present? && record["startdate"].to_date < record["voiddate"].to_date
+    record.errors.add :voiddate, I18n.t("validations.property.void_date.before_tenancy_start")
+  end
+
+  if record["voiddate"].present? && record["mrcdate"].present? && record["mrcdate"].to_date < record["voiddate"].to_date
+    record.errors.add :voiddate, :after_mrcdate, message: I18n.t("validations.property.void_date.after_mrcdate")
+    record.errors.add :mrcdate, I18n.t("validations.property.mrcdate.before_void_date")
+  end
+end
+
+
+ +
+

+ + #validate_startdate(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+
+
# File 'date_validations.rb', line 34
+
+def validate_startdate(record)
+  return unless record.startdate && date_valid?("startdate", record)
+
+  if record["voiddate"].present? && record.startdate < record["voiddate"]
+    record.errors.add :startdate, I18n.t("validations.setup.startdate.after_void_date")
+  end
+
+  if record["mrcdate"].present? && record.startdate < record["mrcdate"]
+    record.errors.add :startdate, I18n.t("validations.setup.startdate.after_major_repair_date")
+  end
+
+  if record["voiddate"].present? && record["startdate"].to_date - record["voiddate"].to_date > 3650
+    record.errors.add :startdate, I18n.t("validations.setup.startdate.ten_years_after_void_date")
+  end
+
+  if record["mrcdate"].present? && record["startdate"].to_date - record["mrcdate"].to_date > 3650
+    record.errors.add :startdate, I18n.t("validations.setup.startdate.ten_years_after_mrc_date")
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/FinancialValidations.html b/app/models/validations/doc/Validations/FinancialValidations.html new file mode 100644 index 000000000..a73ca9e12 --- /dev/null +++ b/app/models/validations/doc/Validations/FinancialValidations.html @@ -0,0 +1,915 @@ + + + + + + + Module: Validations::FinancialValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::FinancialValidations + + + +

+
+ + + + + + +
+
Includes:
+
ChargesHelper, MoneyFormattingHelper, SharedValidations
+
+ + + + + + +
+
Defined in:
+
financial_validations.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
EMPLOYED_STATUSES = + +
+
[1, 0].freeze
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #no_known_benefits?(record) ⇒ Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+
+
# File 'financial_validations.rb', line 108
+
+def no_known_benefits?(record)
+  return true unless record.collection_start_year
+
+  if record.collection_start_year <= 2021
+    record.benefits_unknown? ||
+      record.receives_no_benefits? ||
+      record.receives_universal_credit_but_no_housing_benefit?
+  else
+    record.benefits_unknown? ||
+      record.receives_no_benefits? ||
+      record.tenant_refuses_to_say_benefits?
+  end
+end
+
+
+ +
+

+ + #validate_care_home_charges(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+
+
# File 'financial_validations.rb', line 158
+
+def validate_care_home_charges(record)
+  if record.is_carehome?
+    period = record.form.get_question("period", record).label_from_value(record.period).downcase
+    # NOTE: This is a temporary change to allow `ccharge` values despite `is_carehome` being true. This value
+    # is going to be moved to a soft validation in CLDC-2074, so we can safely do this.
+    if record.chcharge.blank?
+      # record.errors.add :is_carehome, I18n.t("validations.financial.carehome.not_provided", period:)
+      # record.errors.add :chcharge, I18n.t("validations.financial.carehome.not_provided", period:)
+    elsif !weekly_value_in_range(record, "chcharge", 10, 5000)
+      max_chcharge = record.weekly_to_value_per_period(5000)
+      min_chcharge = record.weekly_to_value_per_period(10)
+      message = I18n.t("validations.financial.carehome.out_of_range", period:, min_chcharge:, max_chcharge:)
+
+      record.errors.add :period, message
+      record.errors.add :chcharge, :out_of_range, message:
+    end
+  end
+end
+
+
+ +
+

+ + #validate_negative_currency(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+93
+94
+95
+96
+97
+98
+99
+100
+
+
# File 'financial_validations.rb', line 93
+
+def validate_negative_currency(record)
+  t = %w[earnings brent scharge pscharge supcharg]
+  t.each do |x|
+    if record[x].present? && record[x].negative?
+      record.errors.add x.to_sym, I18n.t("validations.financial.negative_currency")
+    end
+  end
+end
+
+
+ +
+

+ + #validate_net_income(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+
+
# File 'financial_validations.rb', line 27
+
+def validate_net_income(record)
+  if record.ecstat1 && record.hhmemb && record.weekly_net_income && record.startdate && record.form.start_date.year >= 2023
+    if record.weekly_net_income > record.applicable_income_range.hard_max
+      frequency = record.form.get_question("incfreq", record).label_from_value(record.incfreq).downcase
+      hard_max = format_as_currency(record.applicable_income_range.hard_max)
+      record.errors.add(
+        :earnings,
+        :over_hard_max,
+        message: I18n.t("validations.financial.earnings.over_hard_max", hard_max:),
+      )
+      record.errors.add(
+        :hhmemb,
+        :over_hard_max,
+        message: I18n.t("validations.financial.hhmemb.earnings.over_hard_max", earnings: format_as_currency(record.earnings), frequency:),
+      )
+      (1..record.hhmemb).each do |n|
+        record.errors.add(
+          "ecstat#{n}",
+          :over_hard_max,
+          message: I18n.t("validations.financial.ecstat.over_hard_max", earnings: format_as_currency(record.earnings), frequency:),
+        )
+        next unless record["ecstat#{n}"] == 9
+
+        record.errors.add(
+          "age#{n}",
+          :over_hard_max,
+          message: I18n.t("validations.financial.age.earnings_over_hard_max", earnings: format_as_currency(record.earnings), frequency:),
+        )
+      end
+    end
+
+    if record.weekly_net_income < record.applicable_income_range.hard_min
+      hard_min = format_as_currency(record.applicable_income_range.hard_min)
+      frequency = record.form.get_question("incfreq", record).label_from_value(record.incfreq).downcase
+      record.errors.add(
+        :earnings,
+        :under_hard_min,
+        message: I18n.t("validations.financial.earnings.under_hard_min", hard_min:),
+      )
+      record.errors.add(
+        :hhmemb,
+        :under_hard_min,
+        message: I18n.t("validations.financial.hhmemb.earnings.under_hard_min", earnings: format_as_currency(record.earnings), frequency:),
+      )
+      (1..record.hhmemb).each do |n|
+        record.errors.add(
+          "ecstat#{n}",
+          :under_hard_min,
+          message: I18n.t("validations.financial.ecstat.under_hard_min", earnings: format_as_currency(record.earnings), frequency:),
+        )
+        # N.B. It is not possible for a change to an age field to increase the hard min
+      end
+    end
+  end
+
+  if record.earnings.present? && record.incfreq.blank?
+    record.errors.add :incfreq, I18n.t("validations.financial.earnings.freq_missing")
+    record.errors.add :earnings, I18n.t("validations.financial.earnings.freq_missing")
+  end
+
+  if record.incfreq.present? && record.earnings.blank?
+    record.errors.add :earnings, I18n.t("validations.financial.earnings.earnings_missing")
+    record.errors.add :incfreq, I18n.t("validations.financial.earnings.earnings_missing")
+  end
+end
+
+
+ +
+

+ + #validate_net_income_uc_proportion(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+
+
# File 'financial_validations.rb', line 15
+
+def validate_net_income_uc_proportion(record)
+  (1..8).any? do |n|
+    economic_status = record["ecstat#{n}"]
+    is_employed = EMPLOYED_STATUSES.include?(economic_status)
+    relationship = record["relat#{n}"]
+    is_partner_or_main = relationship == "P" || (relationship.nil? && economic_status.present?)
+    if is_employed && is_partner_or_main && record.benefits&.zero?
+      record.errors.add :benefits, I18n.t("validations.financial.benefits.part_or_full_time")
+    end
+  end
+end
+
+
+ +
+

+ + #validate_outstanding_rent_amount(record) ⇒ Object + + + + + +

+
+ +

Validations methods need to be called ‘validate_<page_name>’ to run on model save or ‘validate_’ to run on submit as well

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+10
+11
+12
+
+
# File 'financial_validations.rb', line 7
+
+def validate_outstanding_rent_amount(record)
+  if !record.has_housing_benefit_rent_shortfall? && record.tshortfall.present?
+    record.errors.add :tshortfall, :no_outstanding_charges, message: I18n.t("validations.financial.tshortfall.outstanding_amount_not_expected")
+    record.errors.add :hbrentshortfall, :no_outstanding_charges, message: I18n.t("validations.financial.hbrentshortfall.outstanding_amount_not_expected")
+  end
+end
+
+
+ +
+

+ + #validate_rent_amount(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+
+
# File 'financial_validations.rb', line 122
+
+def validate_rent_amount(record)
+  if record.wtshortfall
+    if record.wrent && (record.wtshortfall > record.wrent)
+      record.errors.add :tshortfall, :more_than_rent, message: I18n.t("validations.financial.tshortfall.more_than_rent")
+      record.errors.add :brent, I18n.t("validations.financial.rent.less_than_shortfall")
+    elsif record.wtshortfall < 0.01
+      record.errors.add :tshortfall, :must_be_positive, message: I18n.t("validations.financial.tshortfall.must_be_positive")
+    end
+  end
+
+  if record.tcharge.present? && weekly_value_in_range(record, "tcharge", 0, 9.99)
+    record.errors.add :tcharge, :under_10, message: I18n.t("validations.financial.tcharge.under_10")
+  end
+
+  answered_questions = [record.tcharge, record.chcharge].concat(record.household_charge && record.household_charge == 1 ? [record.household_charge] : [])
+  if answered_questions.count(&:present?) > 1
+    record.errors.add :tcharge, :complete_1_of_3, message: I18n.t("validations.financial.charges.complete_1_of_3") if record.tcharge.present?
+    record.errors.add :chcharge, I18n.t("validations.financial.charges.complete_1_of_3") if record.chcharge.present?
+    record.errors.add :household_charge, I18n.t("validations.financial.charges.complete_1_of_3") if record.household_charge.present?
+  end
+
+  validate_charges(record)
+  validate_rent_range(record)
+end
+
+
+ +
+

+ + #validate_rent_period(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+
+
# File 'financial_validations.rb', line 147
+
+def validate_rent_period(record)
+  if record.managing_organisation.present? && record.managing_organisation.rent_periods.present? &&
+      record.period && !record.managing_organisation.rent_periods.include?(record.period)
+    record.errors.add :period, :wrong_rent_period, message: I18n.t(
+      "validations.financial.rent_period.invalid_for_org",
+      org_name: record.managing_organisation.name,
+      rent_period: record.form.get_question("period", record).label_from_value(record.period).downcase,
+    )
+  end
+end
+
+
+ +
+

+ + #validate_tshortfall(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+102
+103
+104
+105
+106
+
+
# File 'financial_validations.rb', line 102
+
+def validate_tshortfall(record)
+  if record.has_housing_benefit_rent_shortfall? && no_known_benefits?(record)
+    record.errors.add :tshortfall, I18n.t("validations.financial.hbrentshortfall.outstanding_no_benefits")
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/HouseholdValidations.html b/app/models/validations/doc/Validations/HouseholdValidations.html new file mode 100644 index 000000000..d3e28583e --- /dev/null +++ b/app/models/validations/doc/Validations/HouseholdValidations.html @@ -0,0 +1,1243 @@ + + + + + + + Module: Validations::HouseholdValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::HouseholdValidations + + + +

+
+ + + + + + +
+
Includes:
+
SharedValidations
+
+ + + + + + +
+
Defined in:
+
household_validations.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
PHRASES_INDICATING_HOMELESSNESS = + +
+
[
+  "Homeless",
+  "Homelessness",
+  "Temporary accommodation",
+  "Temp accommodation",
+  "TA",
+  "Sleeping rough",
+  "Rough sleeping",
+].freeze
+ +
PHRASES_INDICATING_HOMELESSNESS_REGEX = + +
+
Regexp.union(
+  PHRASES_INDICATING_HOMELESSNESS.map { |phrase| Regexp.new("\\A[^[:alpha:]]*#{phrase}[^[:alpha:]]*\\Z", Regexp::IGNORECASE) },
+)
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + #validate_armed_forces(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+46
+47
+48
+49
+50
+51
+52
+53
+
+
# File 'household_validations.rb', line 46
+
+def validate_armed_forces(record)
+  if (record.armed_forces_no? || record.armed_forces_refused?) && record.reservist.present?
+    record.errors.add :reservist, I18n.t("validations.household.reservist.injury_not_required")
+  end
+  if !record.armed_forces_regular? && record.leftreg.present?
+    record.errors.add :leftreg, I18n.t("validations.household.leftreg.question_not_required")
+  end
+end
+
+
+ +
+

+ + #validate_combination_of_housing_needs_responses(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+212
+213
+214
+215
+216
+217
+218
+
+
# File 'household_validations.rb', line 212
+
+def validate_combination_of_housing_needs_responses(record)
+  if record.has_housingneeds? && record.housingneeds_type_not_listed? && record.no_or_unknown_other_housing_needs?
+    record.errors.add :housingneeds, I18n.t("validations.household.housingneeds.invalid")
+    record.errors.add :housingneeds_type, I18n.t("validations.household.housingneeds.invalid")
+    record.errors.add :housingneeds_other, I18n.t("validations.household.housingneeds.invalid")
+  end
+end
+
+
+ +
+

+ + #validate_condition_effects(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+132
+133
+134
+135
+136
+137
+
+
# File 'household_validations.rb', line 132
+
+def validate_condition_effects(record)
+  all_options = [record.illness_type_1, record.illness_type_2, record.illness_type_3, record.illness_type_4, record.illness_type_5, record.illness_type_6, record.illness_type_7, record.illness_type_8, record.illness_type_9, record.illness_type_10]
+  if all_options.count(1) >= 1 && household_no_illness?(record)
+    record.errors.add :condition_effects, I18n.t("validations.household.condition_effects.no_choices")
+  end
+end
+
+
+ +
+

+ + #validate_layear(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+190
+191
+192
+193
+194
+195
+196
+197
+
+
# File 'household_validations.rb', line 190
+
+def validate_layear(record)
+  return unless record.layear && record.renewal
+
+  if record.is_renewal? && record.layear == 1
+    record.errors.add :layear, :renewal_just_moved, message: I18n.t("validations.household.renewal_just_moved_to_area.layear")
+    record.errors.add :renewal, I18n.t("validations.household.renewal_just_moved_to_area.renewal")
+  end
+end
+
+
+ +
+

+ + #validate_layear_and_prevloc(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+
+
# File 'household_validations.rb', line 199
+
+def validate_layear_and_prevloc(record)
+  return unless record.layear && record.la && record.prevloc && record.collection_start_year
+
+  if record.la == record.prevloc && record.layear == 1 && record.collection_start_year >= 2023
+    record.errors.add :layear, :renewal_just_moved, message: I18n.t("validations.household.same_la_just_moved_to_area.layear")
+    record.errors.add :la, :renewal_just_moved, message: I18n.t("validations.household.same_la_just_moved_to_area.current_la")
+    record.errors.add :postcode_full, :renewal_just_moved, message: I18n.t("validations.household.same_la_just_moved_to_area.current_la")
+    record.errors.add :uprn, :renewal_just_moved, message: I18n.t("validations.household.same_la_just_moved_to_area.current_la")
+    record.errors.add :ppostcode_full, :renewal_just_moved, message: I18n.t("validations.household.same_la_just_moved_to_area.previous_la")
+    record.errors.add :prevloc, :renewal_just_moved, message: I18n.t("validations.household.same_la_just_moved_to_area.previous_la")
+  end
+end
+
+
+ +
+

+ + #validate_partner_count(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+55
+56
+57
+
+
# File 'household_validations.rb', line 55
+
+def validate_partner_count(record)
+  shared_validate_partner_count(record, 8)
+end
+
+
+ +
+

+ + #validate_person_1_economic(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+
+
# File 'household_validations.rb', line 59
+
+def validate_person_1_economic(record)
+  return unless record.age1 && record.ecstat1 && !record.form.start_year_after_2024?
+
+  if record.age1 < 16 && !economic_status_is_child_other_or_refused?(record.ecstat1)
+    record.errors.add "ecstat1", I18n.t("validations.household.ecstat.child_under_16", person_num: 1)
+    record.errors.add "age1", I18n.t("validations.household.age.child_under_16_ecstat", person_num: 1)
+  end
+  if tenant_is_economic_child?(record.ecstat1) && record.age1 > 16
+    record.errors.add "ecstat1", I18n.t("validations.household.ecstat.child_over_16", person_num: 1)
+    record.errors.add "age1", I18n.t("validations.household.age.child_over_16", person_num: 1)
+  end
+end
+
+
+ +
+

+ + #validate_person_age_and_relationship_matches_economic_status(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+
+
# File 'household_validations.rb', line 104
+
+def validate_person_age_and_relationship_matches_economic_status(record)
+  return unless record.startdate && !record.form.start_year_after_2024?
+
+  (2..8).each do |person_num|
+    age = record.public_send("age#{person_num}")
+    economic_status = record.public_send("ecstat#{person_num}")
+    relationship = record.public_send("relat#{person_num}")
+    next unless age && economic_status && relationship
+
+    age_between_16_19 = age.between?(16, 19)
+    student = tenant_is_fulltime_student?(economic_status)
+    economic_status_refused = tenant_economic_status_refused?(economic_status)
+    child = tenant_is_child?(relationship)
+
+    if age_between_16_19 && !(student || economic_status_refused) && child
+      record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19.must_be_student")
+      record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19.cannot_be_16_19.child_not_student")
+      record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.student_16_19.cannot_be_child.16_19_not_student")
+    end
+
+    next unless !age_between_16_19 && student && child
+
+    record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19.must_be_16_19")
+    record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19.cannot_be_student.child_not_16_19")
+    record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.student_16_19.cannot_be_child.student_not_16_19")
+  end
+end
+
+
+ +
+

+ + #validate_person_age_matches_economic_status(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'household_validations.rb', line 72
+
+def validate_person_age_matches_economic_status(record)
+  (2..8).each do |person_num|
+    age = record.public_send("age#{person_num}")
+    economic_status = record.public_send("ecstat#{person_num}")
+    next unless age && economic_status
+
+    if age < 16 && !economic_status_is_child_other_or_refused?(economic_status) && !record.form.start_year_after_2024?
+      record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.child_under_16", person_num:)
+      record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_under_16_ecstat", person_num:)
+    end
+    if tenant_is_economic_child?(economic_status) && age > 16
+      record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.child_over_16", person_num:)
+      record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_over_16", person_num:)
+    end
+  end
+end
+
+
+ +
+

+ + #validate_person_age_matches_relationship(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+
+
# File 'household_validations.rb', line 89
+
+def validate_person_age_matches_relationship(record)
+  return unless record.startdate && !record.form.start_year_after_2024?
+
+  (2..8).each do |person_num|
+    age = record.public_send("age#{person_num}")
+    relationship = record.public_send("relat#{person_num}")
+    next unless age && relationship
+
+    if age < 16 && !relationship_is_child_other_or_refused?(relationship)
+      record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.child_under_16_lettings", person_num:)
+      record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_under_16_relat_lettings", person_num:)
+    end
+  end
+end
+
+
+ +
+

+ + #validate_previous_housing_situation(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+
+
# File 'household_validations.rb', line 139
+
+def validate_previous_housing_situation(record)
+  if record.is_relet_to_temp_tenant? && !record.previous_tenancy_was_temporary?
+    record.errors.add :prevten, :non_temp_accommodation, message: I18n.t("validations.household.prevten.non_temp_accommodation")
+  end
+
+  if record.age1.present? && record.age1 > 25 && record.previous_tenancy_was_foster_care?
+    record.errors.add :prevten, :over_25_foster_care, message: I18n.t("validations.household.prevten.over_25_foster_care")
+    record.errors.add :age1, I18n.t("validations.household.age.lead.over_25")
+  end
+
+  if record.sex1 == "M" && record.previous_tenancy_was_refuge?
+    record.errors.add :prevten, I18n.t("validations.household.prevten.male_refuge")
+    record.errors.add :sex1, I18n.t("validations.household.gender.male_refuge")
+  end
+
+  # 3  Private Sector Tenancy
+  # 4  Tied housing or rented with job
+  # 7  Direct access hostel
+  # 10 Hospital
+  # 13 Children's home / Foster Care
+  # 14 Bed and breakfast
+  # 19 Rough Sleeping
+  # 23 Mobile home / Caravan
+  # 24 Home Office Asylum Support
+  # 25 Other
+  # 26 Owner Occupation
+  # 27 Owner occupation (low-cost home ownership)
+  # 28 Living with Friends or Family
+  # 29 Prison / Approved Probation Hostel
+  if record.is_internal_transfer? && [3, 4, 7, 10, 13, 14, 19, 23, 24, 25, 26, 27, 28, 29].include?(record.prevten)
+    label = record.form.get_question("prevten", record).present? ? record.form.get_question("prevten", record).label_from_value(record.prevten) : ""
+    record.errors.add :prevten, :internal_transfer_non_social_housing, message: I18n.t("validations.household.prevten.internal_transfer", prevten: label)
+    record.errors.add :referral, :internal_transfer_non_social_housing, message: I18n.t("validations.household.referral.prevten_invalid", prevten: label)
+  end
+end
+
+
+ +
+

+ + #validate_prevloc(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+184
+185
+186
+187
+188
+
+
# File 'household_validations.rb', line 184
+
+def validate_prevloc(record)
+  if record.previous_la_known? && record.prevloc.blank?
+    record.errors.add :prevloc, I18n.t("validations.household.previous_la_known")
+  end
+end
+
+
+ +
+

+ + #validate_reason_for_leaving_last_settled_home(record) ⇒ Object + + + + + +

+
+ +

describe everything this does here

+ + +
+
+
+ + +
+ + + + +
+
+
+
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+
+
# File 'household_validations.rb', line 27
+
+def validate_reason_for_leaving_last_settled_home(record)
+  if record.reason == 32 && record.underoccupation_benefitcap != 4
+    record.errors.add :underoccupation_benefitcap, I18n.t("validations.household.underoccupation_benefitcap.dont_know_required")
+    record.errors.add :reason, I18n.t("validations.household.underoccupation_benefitcap.dont_know_required")
+  end
+  validate_other_field(record, 20, :reason, :reasonother)
+
+  if record.is_reason_permanently_decanted? && record.referral.present? && !record.is_internal_transfer?
+    record.errors.add :referral, I18n.t("validations.household.referral.reason_permanently_decanted")
+    record.errors.add :reason, I18n.t("validations.household.reason.not_internal_transfer")
+  end
+
+  return unless record.form.start_year_after_2024?
+
+  if record.reason == 20 && PHRASES_INDICATING_HOMELESSNESS_REGEX.match?(record.reasonother)
+    record.errors.add :reason, I18n.t("validations.household.reason.other_not_settled")
+  end
+end
+
+
+ +
+

+ + #validate_reasonable_preference(record) ⇒ Object + + + + + +

+
+ +

Validations methods need to be called ‘validate_<page_name>’ to run on model save or ‘validate_’ to run on submit as well

+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+9
+10
+
+
# File 'household_validations.rb', line 6
+
+def validate_reasonable_preference(record)
+  if !record.given_reasonable_preference? && [record.rp_homeless, record.rp_insan_unsat, record.rp_medwel, record.rp_hardship, record.rp_dontknow].any? { |a| a == 1 }
+    record.errors.add :reasonable_preference_reason, I18n.t("validations.household.reasonable_preference_reason.reason_not_required")
+  end
+end
+
+
+ +
+

+ + #validate_referral(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+175
+176
+177
+178
+179
+180
+181
+182
+
+
# File 'household_validations.rb', line 175
+
+def validate_referral(record)
+  return unless record.owning_organisation
+
+  if record.is_internal_transfer? && record.owning_organisation.provider_type == "PRP" && record.is_prevten_la_general_needs?
+    record.errors.add :prevten, :internal_transfer_fixed_or_lifetime, message: I18n.t("validations.household.prevten.la_general_needs.internal_transfer")
+    record.errors.add :referral, :internal_transfer_fixed_or_lifetime, message: I18n.t("validations.household.referral.la_general_needs.internal_transfer")
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/LocalAuthorityValidations.html b/app/models/validations/doc/Validations/LocalAuthorityValidations.html new file mode 100644 index 000000000..5f00227c2 --- /dev/null +++ b/app/models/validations/doc/Validations/LocalAuthorityValidations.html @@ -0,0 +1,182 @@ + + + + + + + Module: Validations::LocalAuthorityValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::LocalAuthorityValidations + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
local_authority_validations.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #validate_previous_accommodation_postcode(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+2
+3
+4
+5
+6
+7
+8
+
+
# File 'local_authority_validations.rb', line 2
+
+def validate_previous_accommodation_postcode(record)
+  postcode = record.ppostcode_full
+  if record.previous_postcode_known? && (postcode.blank? || !postcode.match(POSTCODE_REGEXP))
+    error_message = I18n.t("validations.postcode")
+    record.errors.add :ppostcode_full, :wrong_format, message: error_message
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/PropertyValidations.html b/app/models/validations/doc/Validations/PropertyValidations.html new file mode 100644 index 000000000..bac65d187 --- /dev/null +++ b/app/models/validations/doc/Validations/PropertyValidations.html @@ -0,0 +1,435 @@ + + + + + + + Module: Validations::PropertyValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::PropertyValidations + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
property_validations.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
REFERRAL_INVALID_TMP = +
+
+ +

Validations methods need to be called ‘validate_<page_name>’ to run on model save or ‘validate_’ to run on submit as well

+ + +
+
+
+ + +
+
+
[8, 10, 12, 13, 14, 15].freeze
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #validate_rsnvac(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+
+
# File 'property_validations.rb', line 6
+
+def validate_rsnvac(record)
+  if !record.first_time_property_let_as_social_housing? && record.has_first_let_vacancy_reason?
+    record.errors.add :rsnvac, I18n.t("validations.property.rsnvac.first_let_not_social")
+  end
+
+  if record.first_time_property_let_as_social_housing? && record.rsnvac.present? && !record.has_first_let_vacancy_reason?
+    record.errors.add :rsnvac, I18n.t("validations.property.rsnvac.first_let_social")
+  end
+
+  if record.is_relet_to_temp_tenant? && !record.previous_tenancy_was_temporary?
+    record.errors.add :rsnvac, I18n.t("validations.property.rsnvac.non_temp_accommodation")
+  end
+
+  if record.is_relet_to_temp_tenant? && REFERRAL_INVALID_TMP.include?(record.referral)
+    record.errors.add :rsnvac, I18n.t("validations.property.rsnvac.referral_invalid")
+    record.errors.add :referral, :referral_invalid, message: I18n.t("validations.household.referral.rsnvac_non_temp")
+  end
+
+  if record.renewal.present? && record.renewal.zero? && record.rsnvac == 14
+    record.errors.add :rsnvac, I18n.t("validations.property.rsnvac.not_a_renewal")
+  end
+end
+
+
+ +
+

+ + #validate_shared_housing_rooms(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+
+
# File 'property_validations.rb', line 35
+
+def validate_shared_housing_rooms(record)
+  unless record.unittype_gn.nil?
+    if record.is_bedsit? && record.beds != 1 && record.beds.present? && !record.form.start_year_after_2024?
+      record.errors.add :unittype_gn, I18n.t("validations.property.unittype_gn.one_bedroom_bedsit")
+      record.errors.add :beds, I18n.t("validations.property.unittype_gn.one_bedroom_bedsit")
+    end
+
+    if record.hhmemb == 1 && record.is_shared_housing? &&
+        !record.beds.to_i.between?(1, 3) && record.beds.present?
+      record.errors.add :unittype_gn, I18n.t("validations.property.unittype_gn.one_three_bedroom_single_tenant_shared")
+      record.errors.add :beds, :one_three_bedroom_single_tenant_shared, message: I18n.t("validations.property.unittype_gn.one_three_bedroom_single_tenant_shared")
+    elsif record.is_shared_housing? && record.beds.present? && !record.beds.to_i.between?(1, 7)
+      record.errors.add :unittype_gn, I18n.t("validations.property.unittype_gn.one_seven_bedroom_shared")
+      record.errors.add :beds, I18n.t("validations.property.unittype_gn.one_seven_bedroom_shared")
+    end
+  end
+end
+
+
+ +
+

+ + #validate_unitletas(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+29
+30
+31
+32
+33
+
+
# File 'property_validations.rb', line 29
+
+def validate_unitletas(record)
+  if record.first_time_property_let_as_social_housing? && record.unitletas.present?
+    record.errors.add :unitletas, I18n.t("validations.property.rsnvac.previous_let_social")
+  end
+end
+
+
+ +
+

+ + #validate_uprn(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+53
+54
+55
+56
+57
+58
+59
+
+
# File 'property_validations.rb', line 53
+
+def validate_uprn(record)
+  return unless record.uprn
+
+  return if record.uprn.match?(/^[0-9]{1,12}$/)
+
+  record.errors.add :uprn, I18n.t("validations.property.uprn.invalid")
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/Sales/FinancialValidations.html b/app/models/validations/doc/Validations/Sales/FinancialValidations.html new file mode 100644 index 000000000..9f08e7d18 --- /dev/null +++ b/app/models/validations/doc/Validations/Sales/FinancialValidations.html @@ -0,0 +1,843 @@ + + + + + + + Module: Validations::Sales::FinancialValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::Sales::FinancialValidations + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
sales/financial_validations.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #validate_child_income(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'sales/financial_validations.rb', line 80
+
+def validate_child_income(record)
+  return unless record.income2 && record.ecstat2
+
+  if record.income2.positive? && is_economic_status_child?(record.ecstat2) && record.form.start_date.year >= 2023
+    record.errors.add :ecstat2, I18n.t("validations.financial.income.child_has_income")
+    record.errors.add :income2, I18n.t("validations.financial.income.child_has_income")
+  end
+end
+
+
+ +
+

+ + #validate_combined_income(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+
+
# File 'sales/financial_validations.rb', line 27
+
+def validate_combined_income(record)
+  return unless record.income1 && record.income2 && record.la && record.shared_ownership_scheme?
+
+  combined_income = record.income1 + record.income2
+  relevant_fields = %i[income1 income2 ownershipsch uprn la postcode_full]
+  if record.london_property? && combined_income > 90_000
+    relevant_fields.each { |field| record.errors.add field, :over_combined_hard_max_for_london, message: I18n.t("validations.financial.income.combined_over_hard_max_for_london") }
+  elsif record.property_not_in_london? && combined_income > 80_000
+    relevant_fields.each { |field| record.errors.add field, :over_combined_hard_max_for_outside_london, message: I18n.t("validations.financial.income.combined_over_hard_max_for_outside_london") }
+  end
+end
+
+
+ +
+

+ + #validate_equity_in_range_for_year_and_type(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+
+
# File 'sales/financial_validations.rb', line 89
+
+def validate_equity_in_range_for_year_and_type(record)
+  return unless record.type && record.equity && record.collection_start_year
+
+  ranges = EQUITY_RANGES_BY_YEAR.fetch(record.collection_start_year, DEFAULT_EQUITY_RANGES)
+
+  return unless (range = ranges[record.type])
+
+  if record.equity < range.min
+    record.errors.add :type, I18n.t("validations.financial.equity.under_min", min_equity: range.min)
+    record.errors.add :equity, :under_min, message: I18n.t("validations.financial.equity.under_min", min_equity: range.min)
+  elsif record.equity > range.max
+    record.errors.add :type, I18n.t("validations.financial.equity.over_max", max_equity: range.max)
+    record.errors.add :equity, :over_max, message: I18n.t("validations.financial.equity.over_max", max_equity: range.max)
+  end
+end
+
+
+ +
+

+ + #validate_equity_less_than_staircase_difference(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+
+
# File 'sales/financial_validations.rb', line 105
+
+def validate_equity_less_than_staircase_difference(record)
+  return unless record.equity && record.stairbought && record.stairowned
+  return unless record.saledate && record.form.start_year_after_2024?
+
+  if record.equity > record.stairowned - record.stairbought
+    formatted_equity = sprintf("%g", record.equity)
+    record.errors.add :equity, I18n.t("validations.financial.equity.over_stairowned_minus_stairbought", equity: formatted_equity, staircase_difference: record.stairowned - record.stairbought, buyer_owns: record.joint_purchase? ? "buyers own" : "buyer owns")
+    record.errors.add :stairowned, I18n.t("validations.financial.equity.over_stairowned_minus_stairbought", equity: formatted_equity, staircase_difference: record.stairowned - record.stairbought, buyer_owns: record.joint_purchase? ? "buyers own" : "buyer owns")
+    record.errors.add :stairbought, I18n.t("validations.financial.equity.over_stairowned_minus_stairbought", equity: formatted_equity, staircase_difference: record.stairowned - record.stairbought, buyer_owns: record.joint_purchase? ? "buyers own" : "buyer owns")
+  end
+end
+
+
+ +
+

+ + #validate_income1(record) ⇒ Object + + + + + +

+
+ +

Validations methods need to be called ‘validate_<page_name>’ to run on model save or ‘validate_’ to run on submit as well

+ + +
+
+
+ + +
+ + + + +
+
+
+
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+
+
# File 'sales/financial_validations.rb', line 5
+
+def validate_income1(record)
+  return unless record.income1 && record.la && record.shared_ownership_scheme?
+
+  relevant_fields = %i[income1 ownershipsch uprn la postcode_full]
+  if record.london_property? && !record.income1.between?(0, 90_000)
+    relevant_fields.each { |field| record.errors.add field, :outside_london_income_range, message: I18n.t("validations.financial.income.outside_london_income_range") }
+  elsif record.property_not_in_london? && !record.income1.between?(0, 80_000)
+    relevant_fields.each { |field| record.errors.add field, :outside_non_london_income_range, message: I18n.t("validations.financial.income.outside_non_london_income_range") }
+  end
+end
+
+
+ +
+

+ + #validate_income2(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+
+
# File 'sales/financial_validations.rb', line 16
+
+def validate_income2(record)
+  return unless record.income2 && record.la && record.shared_ownership_scheme?
+
+  relevant_fields = %i[income2 ownershipsch uprn la postcode_full]
+  if record.london_property? && !record.income2.between?(0, 90_000)
+    relevant_fields.each { |field| record.errors.add field, :outside_london_income_range, message: I18n.t("validations.financial.income.outside_london_income_range") }
+  elsif record.property_not_in_london? && !record.income2.between?(0, 80_000)
+    relevant_fields.each { |field| record.errors.add field, :outside_non_london_income_range, message: I18n.t("validations.financial.income.outside_non_london_income_range") }
+  end
+end
+
+
+ +
+

+ + #validate_monthly_leasehold_charges(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+43
+44
+45
+
+
# File 'sales/financial_validations.rb', line 43
+
+def validate_monthly_leasehold_charges(record)
+  record.errors.add :mscharge, I18n.t("validations.financial.monthly_leasehold_charges.not_zero") if record.mscharge&.zero?
+end
+
+
+ +
+

+ + #validate_mortgage(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+39
+40
+41
+
+
# File 'sales/financial_validations.rb', line 39
+
+def validate_mortgage(record)
+  record.errors.add :mortgage, :cannot_be_0, message: I18n.t("validations.financial.mortgage") if record.mortgage_used? && record.mortgage&.zero?
+end
+
+
+ +
+

+ + #validate_percentage_bought_at_least_threshold(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+
+
# File 'sales/financial_validations.rb', line 65
+
+def validate_percentage_bought_at_least_threshold(record)
+  return unless record.stairbought && record.type
+
+  threshold = if [2, 16, 18, 24].include? record.type
+                10
+              else
+                1
+              end
+
+  if threshold && record.stairbought < threshold
+    record.errors.add :stairbought, I18n.t("validations.financial.staircasing.percentage_bought_must_be_at_least_threshold", threshold:)
+    record.errors.add :type, I18n.t("validations.setup.type.percentage_bought_must_be_at_least_threshold", threshold:)
+  end
+end
+
+
+ +
+

+ + #validate_percentage_bought_not_equal_percentage_owned(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+55
+56
+57
+58
+59
+60
+61
+62
+63
+
+
# File 'sales/financial_validations.rb', line 55
+
+def validate_percentage_bought_not_equal_percentage_owned(record)
+  return unless record.stairbought && record.stairowned
+  return unless record.saledate && record.form.start_year_after_2024?
+
+  if record.stairbought == record.stairowned
+    record.errors.add :stairbought, I18n.t("validations.financial.staircasing.percentage_bought_equal_percentage_owned", stairbought: sprintf("%g", record.stairbought), stairowned: sprintf("%g", record.stairowned))
+    record.errors.add :stairowned, I18n.t("validations.financial.staircasing.percentage_bought_equal_percentage_owned", stairbought: sprintf("%g", record.stairbought), stairowned: sprintf("%g", record.stairowned))
+  end
+end
+
+
+ +
+

+ + #validate_percentage_bought_not_greater_than_percentage_owned(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+47
+48
+49
+50
+51
+52
+53
+
+
# File 'sales/financial_validations.rb', line 47
+
+def validate_percentage_bought_not_greater_than_percentage_owned(record)
+  return unless record.stairbought && record.stairowned
+
+  if record.stairbought > record.stairowned
+    record.errors.add :stairowned, I18n.t("validations.financial.staircasing.percentage_bought_must_be_greater_than_percentage_owned", buyer_now_owns: record.joint_purchase? ? "buyers now own" : "buyer now owns")
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/Sales/HouseholdValidations.html b/app/models/validations/doc/Validations/Sales/HouseholdValidations.html new file mode 100644 index 000000000..00e5308c0 --- /dev/null +++ b/app/models/validations/doc/Validations/Sales/HouseholdValidations.html @@ -0,0 +1,702 @@ + + + + + + + Module: Validations::Sales::HouseholdValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::Sales::HouseholdValidations + + + +

+
+ + + + + + +
+
Includes:
+
Validations::SharedValidations
+
+ + + + + + +
+
Defined in:
+
sales/household_validations.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + #validate_buyer1_previous_tenure(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+18
+19
+20
+21
+22
+23
+24
+25
+26
+
+
# File 'sales/household_validations.rb', line 18
+
+def validate_buyer1_previous_tenure(record)
+  return unless record.saledate && record.form.start_year_after_2024?
+  return unless record.discounted_ownership_sale? && record.prevten
+
+  if [3, 4, 5, 6, 7, 9, 0].include?(record.prevten)
+    record.errors.add :prevten, I18n.t("validations.household.prevten.invalid_for_discounted_sale")
+    record.errors.add :ownershipsch, I18n.t("validations.household.prevten.invalid_for_discounted_sale")
+  end
+end
+
+
+ +
+

+ + #validate_buyer_not_child(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+108
+109
+110
+111
+112
+113
+
+
# File 'sales/household_validations.rb', line 108
+
+def validate_buyer_not_child(record)
+  return unless record.saledate && record.form.start_year_after_2024?
+
+  record.errors.add "ecstat1", I18n.t("validations.household.ecstat.buyer_cannot_be_child", buyer_index: "1") if person_is_economic_child?(record.ecstat1)
+  record.errors.add "ecstat2", I18n.t("validations.household.ecstat.buyer_cannot_be_child", buyer_index: "2") if person_is_economic_child?(record.ecstat2) && record.joint_purchase?
+end
+
+
+ +
+

+ + #validate_buyers_living_in_property(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+8
+9
+10
+11
+12
+13
+14
+15
+16
+
+
# File 'sales/household_validations.rb', line 8
+
+def validate_buyers_living_in_property(record)
+  return unless record.form.start_date.year >= 2023
+
+  if record.buyers_will_live_in? && record.buyer_one_will_not_live_in_property? && record.buyer_two_will_not_live_in_property?
+    record.errors.add :buylivein, I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent_setup")
+    record.errors.add :buy1livein, I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent")
+    record.errors.add :buy2livein, I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent")
+  end
+end
+
+
+ +
+

+ + #validate_child_12_years_younger(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+
+
# File 'sales/household_validations.rb', line 91
+
+def validate_child_12_years_younger(record)
+  return unless record.saledate && !record.form.start_year_after_2024?
+
+  (2..6).each do |person_num|
+    buyer_1_age = record.public_send("age1")
+    person_age = record.public_send("age#{person_num}")
+    relationship = record.public_send("relat#{person_num}")
+    next unless buyer_1_age && person_age && relationship
+
+    next unless person_age > buyer_1_age - 12 && person_is_child?(relationship)
+
+    record.errors.add "age1", I18n.t("validations.household.age.child_12_years_younger")
+    record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_12_years_younger")
+    record.errors.add "relat#{person_num}", I18n.t("validations.household.age.child_12_years_younger")
+  end
+end
+
+
+ +
+

+ + #validate_partner_count(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+4
+5
+6
+
+
# File 'sales/household_validations.rb', line 4
+
+def validate_partner_count(record)
+  shared_validate_partner_count(record, 6)
+end
+
+
+ +
+

+ + #validate_person_age_and_relationship_matches_economic_status(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+
+
# File 'sales/household_validations.rb', line 46
+
+def validate_person_age_and_relationship_matches_economic_status(record)
+  return unless record.saledate && !record.form.start_year_after_2024?
+
+  (2..6).each do |person_num|
+    age = record.public_send("age#{person_num}")
+    economic_status = record.public_send("ecstat#{person_num}")
+    relationship = record.public_send("relat#{person_num}")
+    next unless age && economic_status && relationship
+
+    age_between_16_19 = age.between?(16, 19)
+    student = person_is_fulltime_student?(economic_status)
+    economic_status_refused = person_economic_status_refused?(economic_status)
+    child = person_is_child?(relationship)
+
+    if age_between_16_19 && !(student || economic_status_refused) && child
+      record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19.must_be_student")
+      record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19.cannot_be_16_19.child_not_student")
+      record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.student_16_19.cannot_be_child.16_19_not_student")
+    end
+
+    next unless !age_between_16_19 && student && child
+
+    record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19.must_be_16_19")
+    record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19.cannot_be_student.child_not_16_19")
+    record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.student_16_19.cannot_be_child.student_not_16_19")
+  end
+end
+
+
+ +
+

+ + #validate_person_age_matches_economic_status(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+
+
# File 'sales/household_validations.rb', line 74
+
+def validate_person_age_matches_economic_status(record)
+  (2..6).each do |person_num|
+    age = record.public_send("age#{person_num}")
+    economic_status = record.public_send("ecstat#{person_num}")
+    next unless age && economic_status
+
+    if age < 16 && !economic_status_is_child_other_or_refused?(economic_status) && !record.form.start_year_after_2024?
+      record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.child_under_16", person_num:)
+      record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_under_16_ecstat", person_num:)
+    end
+    if person_is_economic_child?(economic_status) && age > 16
+      record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.child_over_16", person_num:)
+      record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_over_16", person_num:)
+    end
+  end
+end
+
+
+ +
+

+ + #validate_person_age_matches_relationship(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+
+
# File 'sales/household_validations.rb', line 28
+
+def validate_person_age_matches_relationship(record)
+  return unless record.saledate && !record.form.start_year_after_2024?
+
+  (2..6).each do |person_num|
+    age = record.public_send("age#{person_num}")
+    relationship = record.public_send("relat#{person_num}")
+    next unless age && relationship
+
+    if age < 16 && !relationship_is_child_other_or_refused?(relationship)
+      record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_under_16_relat_sales", person_num:)
+      record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.child_under_16_sales", person_num:)
+    elsif age >= 20 && person_is_child?(relationship)
+      record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_over_20")
+      record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.child_over_20")
+    end
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/Sales/PropertyValidations.html b/app/models/validations/doc/Validations/Sales/PropertyValidations.html new file mode 100644 index 000000000..3ff4c2d75 --- /dev/null +++ b/app/models/validations/doc/Validations/Sales/PropertyValidations.html @@ -0,0 +1,312 @@ + + + + + + + Module: Validations::Sales::PropertyValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::Sales::PropertyValidations + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
sales/property_validations.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #validate_bedsit_number_of_beds(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+14
+15
+16
+17
+18
+19
+20
+21
+
+
# File 'sales/property_validations.rb', line 14
+
+def validate_bedsit_number_of_beds(record)
+  return unless record.proptype.present? && record.beds.present?
+
+  if record.is_bedsit? && record.beds > 1
+    record.errors.add :proptype, I18n.t("validations.property.proptype.bedsits_have_max_one_bedroom")
+    record.errors.add :beds, I18n.t("validations.property.beds.bedsits_have_max_one_bedroom")
+  end
+end
+
+
+ +
+

+ + #validate_postcodes_match_if_discounted_ownership(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+
+
# File 'sales/property_validations.rb', line 2
+
+def validate_postcodes_match_if_discounted_ownership(record)
+  return unless record.saledate && !record.form.start_year_after_2024?
+  return unless record.ppostcode_full.present? && record.postcode_full.present?
+
+  if record.discounted_ownership_sale? && record.ppostcode_full != record.postcode_full
+    record.errors.add :postcode_full, I18n.t("validations.property.postcode.must_match_previous", buyer_possessive: record.joint_purchase? ? "Buyers’" : "Buyer’s")
+    record.errors.add :ppostcode_full, I18n.t("validations.property.postcode.must_match_previous", buyer_possessive: record.joint_purchase? ? "Buyers’" : "Buyer’s")
+    record.errors.add :ownershipsch, I18n.t("validations.property.postcode.must_match_previous", buyer_possessive: record.joint_purchase? ? "Buyers’" : "Buyer’s")
+    record.errors.add :uprn, I18n.t("validations.property.postcode.must_match_previous", buyer_possessive: record.joint_purchase? ? "Buyers’" : "Buyer’s")
+  end
+end
+
+
+ +
+

+ + #validate_uprn(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+23
+24
+25
+26
+27
+28
+29
+
+
# File 'sales/property_validations.rb', line 23
+
+def validate_uprn(record)
+  return unless record.uprn
+
+  return if record.uprn.match?(/^[0-9]{1,12}$/)
+
+  record.errors.add :uprn, I18n.t("validations.property.uprn.invalid")
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/Sales/SaleInformationValidations.html b/app/models/validations/doc/Validations/Sales/SaleInformationValidations.html new file mode 100644 index 000000000..bef2d1288 --- /dev/null +++ b/app/models/validations/doc/Validations/Sales/SaleInformationValidations.html @@ -0,0 +1,1445 @@ + + + + + + + Module: Validations::Sales::SaleInformationValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::Sales::SaleInformationValidations + + + +

+
+ + + + + + +
+
Includes:
+
CollectionTimeHelper, MoneyFormattingHelper, Validations::SharedValidations
+
+ + + + +
+
Included in:
+
SoftValidations
+
+ + + +
+
Defined in:
+
sales/sale_information_validations.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #check_non_staircasing_non_socialhomebuy_mortgage(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+
+
# File 'sales/sale_information_validations.rb', line 178
+
+def check_non_staircasing_non_socialhomebuy_mortgage(record)
+  if record.mortgage_used?
+    return unless record.mortgage
+
+    if over_tolerance?(record.mortgage_and_deposit_total, record.expected_shared_ownership_deposit_value, 1)
+      %i[mortgage value deposit equity].each do |field|
+        record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
+      end
+      record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
+    end
+  elsif record.mortgage_not_used?
+    if over_tolerance?(record.deposit, record.expected_shared_ownership_deposit_value, 1)
+      %i[mortgageused value deposit equity].each do |field|
+        record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
+      end
+      record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
+    end
+  end
+end
+
+
+ +
+

+ + #check_non_staircasing_socialhomebuy_mortgage(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+
+
# File 'sales/sale_information_validations.rb', line 156
+
+def check_non_staircasing_socialhomebuy_mortgage(record)
+  return unless record.cashdis
+
+  if record.mortgage_used?
+    return unless record.mortgage
+
+    if over_tolerance?(record.mortgage_deposit_and_discount_total, record.expected_shared_ownership_deposit_value, 1)
+      %i[mortgage value deposit cashdis equity].each do |field|
+        record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
+      end
+      record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
+    end
+  elsif record.mortgage_not_used?
+    if over_tolerance?(record.deposit_and_discount_total, record.expected_shared_ownership_deposit_value, 1)
+      %i[mortgageused value deposit cashdis equity].each do |field|
+        record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
+      end
+      record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
+    end
+  end
+end
+
+
+ +
+

+ + #check_staircasing_non_socialhomebuy_mortgage(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+
+
# File 'sales/sale_information_validations.rb', line 218
+
+def check_staircasing_non_socialhomebuy_mortgage(record)
+  if record.mortgage_used?
+    return unless record.mortgage
+
+    if over_tolerance?(record.mortgage_and_deposit_total, record.stairbought_part_of_value, 1)
+      %i[mortgage value deposit stairbought type].each do |field|
+        record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
+      end
+      record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
+    end
+  elsif over_tolerance?(record.deposit, record.stairbought_part_of_value, 1)
+    %i[mortgageused value deposit stairbought type].each do |field|
+      record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
+    end
+    record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
+  end
+end
+
+
+ +
+

+ + #check_staircasing_socialhomebuy_mortgage(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+
+
# File 'sales/sale_information_validations.rb', line 198
+
+def check_staircasing_socialhomebuy_mortgage(record)
+  return unless record.cashdis
+
+  if record.mortgage_used?
+    return unless record.mortgage
+
+    if over_tolerance?(record.mortgage_deposit_and_discount_total, record.stairbought_part_of_value, 1)
+      %i[mortgage value deposit cashdis stairbought].each do |field|
+        record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
+      end
+      record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
+    end
+  elsif over_tolerance?(record.deposit_and_discount_total, record.stairbought_part_of_value, 1)
+    %i[mortgageused value deposit cashdis stairbought].each do |field|
+      record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
+    end
+    record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
+  end
+end
+
+
+ +
+

+ + #over_tolerance?(expected, actual, tolerance) ⇒ Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+250
+251
+252
+
+
# File 'sales/sale_information_validations.rb', line 250
+
+def over_tolerance?(expected, actual, tolerance)
+  (expected - actual).abs >= tolerance
+end
+
+
+ +
+

+ + #validate_basic_monthly_rent(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+71
+72
+73
+74
+75
+76
+77
+78
+
+
# File 'sales/sale_information_validations.rb', line 71
+
+def validate_basic_monthly_rent(record)
+  return unless record.mrent && record.ownershipsch && record.type
+
+  if record.shared_ownership_scheme? && !record.old_persons_shared_ownership? && record.mrent > 9999
+    record.errors.add :mrent, I18n.t("validations.sale_information.monthly_rent.higher_than_expected")
+    record.errors.add :type, I18n.t("validations.sale_information.monthly_rent.higher_than_expected")
+  end
+end
+
+
+ +
+

+ + #validate_discount_and_value(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+
+
# File 'sales/sale_information_validations.rb', line 108
+
+def validate_discount_and_value(record)
+  return unless record.saledate && record.form.start_year_after_2024?
+  return unless record.discount && record.value && record.la
+
+  if record.london_property? && record.discount_value > 136_400
+    %i[discount value la postcode_full uprn].each do |field|
+      record.errors.add field, I18n.t("validations.sale_information.value.over_discounted_london_max", discount_value: record.field_formatted_as_currency("discount_value"))
+    end
+  elsif record.property_not_in_london? && record.discount_value > 102_400
+    %i[discount value la postcode_full uprn].each do |field|
+      record.errors.add field, I18n.t("validations.sale_information.value.over_discounted_max", discount_value: record.field_formatted_as_currency("discount_value"))
+    end
+  end
+end
+
+
+ +
+

+ + #validate_discounted_ownership_value(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+
+
# File 'sales/sale_information_validations.rb', line 44
+
+def validate_discounted_ownership_value(record)
+  return unless record.saledate && record.form.start_year_after_2024?
+  return unless record.value && record.deposit && record.ownershipsch
+  return unless record.mortgage || record.mortgageused == 2 || record.mortgageused == 3
+  return unless record.discount || record.grant || record.type == 29
+
+  if over_tolerance?(record.mortgage_deposit_and_grant_total, record.value_with_discount, 1) && record.discounted_ownership_sale?
+    %i[mortgageused mortgage value deposit ownershipsch discount grant].each do |field|
+      record.errors.add field, I18n.t("validations.sale_information.discounted_ownership_value", mortgage_deposit_and_grant_total: record.field_formatted_as_currency("mortgage_deposit_and_grant_total"), value_with_discount: record.field_formatted_as_currency("value_with_discount"))
+    end
+  end
+end
+
+
+ +
+

+ + #validate_exchange_date(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+
+
# File 'sales/sale_information_validations.rb', line 21
+
+def validate_exchange_date(record)
+  return unless record.exdate && record.saledate
+
+  if record.exdate > record.saledate
+    record.errors.add :exdate, I18n.t("validations.sale_information.exdate.must_be_before_saledate")
+    record.errors.add :saledate, I18n.t("validations.sale_information.saledate.must_be_after_exdate")
+  end
+
+  if record.saledate - record.exdate >= 1.year
+    record.errors.add :exdate, I18n.t("validations.sale_information.exdate.must_be_less_than_1_year_from_saledate")
+    record.errors.add :saledate, I18n.t("validations.sale_information.saledate.must_be_less_than_1_year_from_exdate")
+  end
+end
+
+
+ +
+

+ + #validate_grant_amount(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+80
+81
+82
+83
+84
+85
+86
+87
+
+
# File 'sales/sale_information_validations.rb', line 80
+
+def validate_grant_amount(record)
+  return unless record.saledate && record.form.start_year_after_2024?
+  return unless record.grant && (record.type == 8 || record.type == 21)
+
+  unless record.grant.between?(9_000, 16_000)
+    record.errors.add :grant, I18n.t("validations.sale_information.grant.out_of_range")
+  end
+end
+
+
+ +
+

+ + #validate_mortgage_used_and_stairbought(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+147
+148
+149
+150
+151
+152
+153
+154
+
+
# File 'sales/sale_information_validations.rb', line 147
+
+def validate_mortgage_used_and_stairbought(record)
+  return unless record.stairowned && record.mortgageused
+
+  if !record.stairowned_100? && record.mortgageused == 3
+    record.errors.add :stairowned, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know")
+    record.errors.add :mortgageused, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know")
+  end
+end
+
+
+ +
+

+ + #validate_mortgage_used_dont_know(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+
+
# File 'sales/sale_information_validations.rb', line 236
+
+def validate_mortgage_used_dont_know(record)
+  return unless record.mortgageused == 3
+
+  if record.discounted_ownership_sale?
+    record.errors.add(:mortgageused, I18n.t("validations.invalid_option", question: "Was a mortgage used for the purchase of this property?"))
+  end
+  if record.outright_sale? && record.saledate && !record.form.start_year_after_2024?
+    record.errors.add(:mortgageused, I18n.t("validations.invalid_option", question: "Was a mortgage used for the purchase of this property?"))
+  end
+  if record.shared_ownership_scheme? && record.staircase && record.staircase != 1
+    record.errors.add(:mortgageused, I18n.t("validations.invalid_option", question: "Was a mortgage used for the purchase of this property?"))
+  end
+end
+
+
+ +
+

+ + #validate_non_staircasing_mortgage(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+
+
# File 'sales/sale_information_validations.rb', line 123
+
+def validate_non_staircasing_mortgage(record)
+  return unless record.saledate && record.form.start_year_after_2024?
+  return unless record.value && record.deposit && record.equity
+  return unless record.shared_ownership_scheme? && record.type && record.mortgageused && record.is_not_staircasing?
+
+  if record.social_homebuy?
+    check_non_staircasing_socialhomebuy_mortgage(record)
+  else
+    check_non_staircasing_non_socialhomebuy_mortgage(record)
+  end
+end
+
+
+ +
+

+ + #validate_outright_sale_value_matches_mortgage_plus_deposit(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+
+
# File 'sales/sale_information_validations.rb', line 57
+
+def validate_outright_sale_value_matches_mortgage_plus_deposit(record)
+  return unless record.saledate && record.form.start_year_after_2024?
+  return unless record.outright_sale?
+  return unless record.mortgage_used? && record.mortgage
+  return unless record.deposit && record.value
+
+  if over_tolerance?(record.mortgage_and_deposit_total, record.value, 1)
+    %i[mortgageused mortgage value deposit].each do |field|
+      record.errors.add field, I18n.t("validations.sale_information.outright_sale_value", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), value: record.field_formatted_as_currency("value"))
+    end
+    record.errors.add :ownershipsch, :skip_bu_error, message: I18n.t("validations.sale_information.outright_sale_value", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), value: record.field_formatted_as_currency("value"))
+  end
+end
+
+
+ +
+

+ + #validate_practical_completion_date(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+
+
# File 'sales/sale_information_validations.rb', line 6
+
+def validate_practical_completion_date(record)
+  return unless record.hodate.present? && date_valid?("hodate", record)
+  return if record.saledate.blank?
+
+  if record.hodate > record.saledate
+    record.errors.add :hodate, I18n.t("validations.sale_information.hodate.must_be_before_saledate")
+    record.errors.add :saledate, I18n.t("validations.sale_information.saledate.must_be_after_hodate")
+  end
+
+  if record.saledate - record.hodate >= 3.years && record.form.start_year_after_2024?
+    record.errors.add :hodate, I18n.t("validations.sale_information.hodate.must_be_less_than_3_years_from_saledate")
+    record.errors.add :saledate, I18n.t("validations.sale_information.saledate.must_be_less_than_3_years_from_hodate")
+  end
+end
+
+
+ +
+

+ + #validate_previous_property_unit_type(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+35
+36
+37
+38
+39
+40
+41
+42
+
+
# File 'sales/sale_information_validations.rb', line 35
+
+def validate_previous_property_unit_type(record)
+  return unless record.fromprop && record.frombeds
+
+  if record.frombeds != 1 && record.fromprop == 2
+    record.errors.add :frombeds, I18n.t("validations.sale_information.previous_property_type.property_type_bedsit")
+    record.errors.add :fromprop, I18n.t("validations.sale_information.previous_property_type.property_type_bedsit")
+  end
+end
+
+
+ +
+

+ + #validate_stairbought(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+
+
# File 'sales/sale_information_validations.rb', line 89
+
+def validate_stairbought(record)
+  return unless record.stairbought && record.type
+  return unless record.saledate && record.form.start_year_after_2024?
+
+  max_stairbought = case record.type
+                    when 30, 16, 28, 31, 32
+                      90
+                    when 2, 18
+                      75
+                    when 24
+                      50
+                    end
+
+  if max_stairbought && record.stairbought > max_stairbought
+    record.errors.add :stairbought, I18n.t("validations.sale_information.stairbought.over_max", max_stairbought:, type: record.form.get_question("type", record).answer_label(record))
+    record.errors.add :type, I18n.t("validations.sale_information.stairbought.over_max", max_stairbought:, type: record.form.get_question("type", record).answer_label(record))
+  end
+end
+
+
+ +
+

+ + #validate_staircasing_mortgage(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+
+
# File 'sales/sale_information_validations.rb', line 135
+
+def validate_staircasing_mortgage(record)
+  return unless record.saledate && record.form.start_year_after_2024?
+  return unless record.value && record.deposit && record.stairbought
+  return unless record.shared_ownership_scheme? && record.type && record.mortgageused && record.is_staircase?
+
+  if record.social_homebuy?
+    check_staircasing_socialhomebuy_mortgage(record)
+  else
+    check_staircasing_non_socialhomebuy_mortgage(record)
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/Sales/SetupValidations.html b/app/models/validations/doc/Validations/Sales/SetupValidations.html new file mode 100644 index 000000000..4c5f4b7ba --- /dev/null +++ b/app/models/validations/doc/Validations/Sales/SetupValidations.html @@ -0,0 +1,417 @@ + + + + + + + Module: Validations::Sales::SetupValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::Sales::SetupValidations + + + +

+
+ + + + + + +
+
Includes:
+
CollectionTimeHelper, Validations::SharedValidations
+
+ + + + + + +
+
Defined in:
+
sales/setup_validations.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #validate_merged_organisations_saledate(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+
+
# File 'sales/setup_validations.rb', line 27
+
+def validate_merged_organisations_saledate(record)
+  return unless record.saledate && date_valid?("saledate", record)
+
+  if merged_owning_organisation_inactive?(record)
+    record.errors.add :saledate, I18n.t("validations.setup.saledate.invalid_merged_organisations_saledate",
+                                        owning_organisation: record.owning_organisation.name,
+                                        owning_organisation_merge_date: record.owning_organisation.merge_date.to_formatted_s(:govuk_date),
+                                        owning_absorbing_organisation: record.owning_organisation.absorbing_organisation.name)
+  end
+
+  if absorbing_owning_organisation_inactive?(record)
+    record.errors.add :saledate, I18n.t("validations.setup.saledate.invalid_absorbing_organisations_saledate",
+                                        owning_organisation: record.owning_organisation.name,
+                                        owning_organisation_available_from: record.owning_organisation.available_from.to_formatted_s(:govuk_date))
+  end
+end
+
+
+ +
+

+ + #validate_organisation(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+
+
# File 'sales/setup_validations.rb', line 44
+
+def validate_organisation(record)
+  return unless record.saledate && record.owning_organisation
+
+  if record.owning_organisation.present?
+    if record.owning_organisation&.merge_date.present? && record.owning_organisation.merge_date <= record.saledate
+      record.errors.add :owning_organisation_id, I18n.t("validations.setup.owning_organisation.inactive_merged_organisation_sales",
+                                                        owning_organisation: record.owning_organisation.name,
+                                                        owning_organisation_merge_date: record.owning_organisation.merge_date.to_formatted_s(:govuk_date),
+                                                        owning_absorbing_organisation: record.owning_organisation.absorbing_organisation.name)
+    elsif record.owning_organisation&.absorbed_organisations.present? && record.owning_organisation.available_from.present? && record.owning_organisation.available_from.to_date > record.saledate.to_date
+      record.errors.add :owning_organisation_id, I18n.t("validations.setup.owning_organisation.inactive_absorbing_organisation_sales",
+                                                        owning_organisation: record.owning_organisation.name,
+                                                        owning_organisation_available_from: record.owning_organisation.available_from.to_formatted_s(:govuk_date))
+    end
+  end
+end
+
+
+ +
+

+ + #validate_saledate_collection_year(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+
+
# File 'sales/setup_validations.rb', line 5
+
+def validate_saledate_collection_year(record)
+  return unless record.saledate && date_valid?("saledate", record) && !FeatureToggle.allow_future_form_use?
+
+  first_collection_start_date = if record.saledate_was.present?
+                                  editable_collection_start_date
+                                else
+                                  active_collection_start_date
+                                end
+
+  unless record.saledate.between?(first_collection_start_date, current_collection_end_date)
+    record.errors.add :saledate, saledate_validation_error_message
+  end
+end
+
+
+ +
+

+ + #validate_saledate_two_weeks(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+19
+20
+21
+22
+23
+24
+25
+
+
# File 'sales/setup_validations.rb', line 19
+
+def validate_saledate_two_weeks(record)
+  return unless record.saledate && date_valid?("saledate", record) && !FeatureToggle.allow_future_form_use?
+
+  if record.saledate > Time.zone.today + 14.days
+    record.errors.add :saledate, I18n.t("validations.setup.saledate.later_than_14_days_after")
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/Sales/SoftValidations.html b/app/models/validations/doc/Validations/Sales/SoftValidations.html new file mode 100644 index 000000000..bc76c4854 --- /dev/null +++ b/app/models/validations/doc/Validations/Sales/SoftValidations.html @@ -0,0 +1,1996 @@ + + + + + + + Module: Validations::Sales::SoftValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::Sales::SoftValidations + + + +

+
+ + + + + + +
+
Includes:
+
SaleInformationValidations
+
+ + + + + + +
+
Defined in:
+
sales/soft_validations.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
ALLOWED_INCOME_RANGES_SALES = + +
+
{
+  1 => OpenStruct.new(soft_min: 5000),
+  2 => OpenStruct.new(soft_min: 1500),
+  3 => OpenStruct.new(soft_min: 1000),
+  5 => OpenStruct.new(soft_min: 2000),
+  0 => OpenStruct.new(soft_min: 2000),
+}.freeze
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + #buyer1_livein_wrong_for_ownership_type?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+152
+153
+154
+155
+156
+
+
# File 'sales/soft_validations.rb', line 152
+
+def buyer1_livein_wrong_for_ownership_type?
+  return unless ownershipsch && buy1livein
+
+  (discounted_ownership_sale? || shared_ownership_scheme?) && buy1livein == 2
+end
+
+
+ +
+

+ + #buyer2_livein_wrong_for_ownership_type?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+158
+159
+160
+161
+162
+163
+
+
# File 'sales/soft_validations.rb', line 158
+
+def buyer2_livein_wrong_for_ownership_type?
+  return unless ownershipsch && buy2livein
+  return unless joint_purchase?
+
+  (discounted_ownership_sale? || shared_ownership_scheme?) && buy2livein == 2
+end
+
+
+ +
+

+ + #combined_income_over_soft_max?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+36
+37
+38
+39
+40
+
+
# File 'sales/soft_validations.rb', line 36
+
+def combined_income_over_soft_max?
+  return unless income1 && income2 && la && discounted_ownership_sale?
+
+  income_over_soft_max?(income1 + income2)
+end
+
+
+ +
+

+ + #deposit_over_soft_max?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+64
+65
+66
+67
+68
+
+
# File 'sales/soft_validations.rb', line 64
+
+def deposit_over_soft_max?
+  return unless savings && deposit && mortgage_used?
+
+  deposit > savings * 4 / 3
+end
+
+
+ +
+

+ + #discounted_ownership_value_invalid?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+143
+144
+145
+146
+147
+148
+149
+150
+
+
# File 'sales/soft_validations.rb', line 143
+
+def discounted_ownership_value_invalid?
+  return unless saledate && collection_start_year <= 2023
+  return unless value && deposit && ownershipsch
+  return unless mortgage || mortgageused == 2 || mortgageused == 3
+  return unless discount || grant || type == 29
+
+  mortgage_deposit_and_grant_total != value_with_discount && discounted_ownership_sale?
+end
+
+
+ +
+

+ + #extra_borrowing_expected_but_not_reported?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+70
+71
+72
+73
+74
+
+
# File 'sales/soft_validations.rb', line 70
+
+def extra_borrowing_expected_but_not_reported?
+  return unless extrabor && mortgage && deposit && value && discount
+
+  extrabor != 1 && mortgage + deposit > value - value * discount / 100
+end
+
+
+ +
+

+ + #grant_outside_common_range?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+118
+119
+120
+121
+122
+123
+
+
# File 'sales/soft_validations.rb', line 118
+
+def grant_outside_common_range?
+  return unless grant && type && saledate
+  return if form.start_year_after_2024? && (type == 21 || type == 8)
+
+  !grant.between?(9_000, 16_000)
+end
+
+
+ +
+

+ + #hodate_3_years_or_more_saledate?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+104
+105
+106
+107
+108
+
+
# File 'sales/soft_validations.rb', line 104
+
+def hodate_3_years_or_more_saledate?
+  return unless hodate && saledate
+
+  saledate - hodate >= 3.years
+end
+
+
+ +
+

+ + #income1_over_soft_max?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+24
+25
+26
+27
+28
+
+
# File 'sales/soft_validations.rb', line 24
+
+def income1_over_soft_max?
+  return unless income1 && la && discounted_ownership_sale?
+
+  income_over_soft_max?(income1)
+end
+
+
+ +
+

+ + #income1_under_soft_min?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+12
+13
+14
+15
+16
+
+
# File 'sales/soft_validations.rb', line 12
+
+def income1_under_soft_min?
+  return false unless ecstat1 && income1 && ALLOWED_INCOME_RANGES_SALES[ecstat1]
+
+  income1 < ALLOWED_INCOME_RANGES_SALES[ecstat1][:soft_min]
+end
+
+
+ +
+

+ + #income2_over_soft_max?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+30
+31
+32
+33
+34
+
+
# File 'sales/soft_validations.rb', line 30
+
+def income2_over_soft_max?
+  return unless income2 && la && discounted_ownership_sale?
+
+  income_over_soft_max?(income2)
+end
+
+
+ +
+

+ + #income2_under_soft_min?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+18
+19
+20
+21
+22
+
+
# File 'sales/soft_validations.rb', line 18
+
+def income2_under_soft_min?
+  return false unless ecstat2 && income2 && ALLOWED_INCOME_RANGES_SALES[ecstat2]
+
+  income2 < ALLOWED_INCOME_RANGES_SALES[ecstat2][:soft_min]
+end
+
+
+ +
+

+ + #monthly_charges_over_soft_max?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+125
+126
+127
+128
+129
+130
+
+
# File 'sales/soft_validations.rb', line 125
+
+def monthly_charges_over_soft_max?
+  return unless type && mscharge && proptype
+
+  soft_max = old_persons_shared_ownership? ? 550 : 300
+  mscharge > soft_max
+end
+
+
+ +
+

+ + #mortgage_over_soft_max?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+46
+47
+48
+49
+50
+51
+52
+
+
# File 'sales/soft_validations.rb', line 46
+
+def mortgage_over_soft_max?
+  return false unless mortgage && inc1mort && (inc2mort || not_joint_purchase?)
+  return false if income1_used_for_mortgage? && income1.blank? || income2_used_for_mortgage? && income2.blank?
+
+  income_used_for_mortgage = (income1_used_for_mortgage? ? income1 : 0) + (income2_used_for_mortgage? ? income2 : 0)
+  mortgage > income_used_for_mortgage * 5
+end
+
+
+ +
+

+ + #mortgage_plus_deposit_less_than_discounted_value?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+97
+98
+99
+100
+101
+102
+
+
# File 'sales/soft_validations.rb', line 97
+
+def mortgage_plus_deposit_less_than_discounted_value?
+  return unless mortgage && deposit && value && discount
+
+  discounted_value = value * (100 - discount) / 100
+  mortgage + deposit < discounted_value
+end
+
+
+ +
+

+ + #percentage_discount_invalid?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+
+
# File 'sales/soft_validations.rb', line 165
+
+def percentage_discount_invalid?
+  return unless discount && proptype
+
+  case proptype
+  when 1, 2
+    discount > 50
+  when 3, 4, 9
+    discount > 35
+  end
+end
+
+
+ +
+

+ + #purchase_price_higher_or_lower_textObject + + + + + +

+ + + + +
+
+
+
+110
+111
+112
+
+
# File 'sales/soft_validations.rb', line 110
+
+def purchase_price_higher_or_lower_text
+  value < sale_range.soft_min ? "lower" : "higher"
+end
+
+
+ +
+

+ + #purchase_price_out_of_soft_range?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+76
+77
+78
+79
+80
+
+
# File 'sales/soft_validations.rb', line 76
+
+def purchase_price_out_of_soft_range?
+  return unless value && beds && la && sale_range
+
+  !value.between?(sale_range.soft_min, sale_range.soft_max)
+end
+
+
+ +
+

+ + #purchase_price_soft_min_or_soft_maxObject + + + + + +

+ + + + +
+
+
+
+114
+115
+116
+
+
# File 'sales/soft_validations.rb', line 114
+
+def purchase_price_soft_min_or_soft_max
+  value < sale_range.soft_min ? sale_range.soft_min : sale_range.soft_max
+end
+
+
+ +
+

+ + #savings_over_soft_max?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+60
+61
+62
+
+
# File 'sales/soft_validations.rb', line 60
+
+def savings_over_soft_max?
+  savings && savings > 100_000
+end
+
+
+ +
+

+ + #shared_ownership_deposit_invalid?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+88
+89
+90
+91
+92
+93
+94
+95
+
+
# File 'sales/soft_validations.rb', line 88
+
+def shared_ownership_deposit_invalid?
+  return unless saledate && collection_start_year <= 2023
+  return unless mortgage || mortgageused == 2 || mortgageused == 3
+  return unless cashdis || !social_homebuy?
+  return unless deposit && value && equity
+
+  over_tolerance?(mortgage_deposit_and_discount_total, value * equity / 100, 1)
+end
+
+
+ +
+

+ + #staircase_bought_above_fifty?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+42
+43
+44
+
+
# File 'sales/soft_validations.rb', line 42
+
+def staircase_bought_above_fifty?
+  stairbought && stairbought > 50
+end
+
+
+ +
+

+ + #staircase_owned_out_of_soft_range?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+82
+83
+84
+85
+86
+
+
# File 'sales/soft_validations.rb', line 82
+
+def staircase_owned_out_of_soft_range?
+  return unless type && stairowned
+
+  type == 24 && stairowned.between?(76, 100)
+end
+
+
+ +
+

+ + #wheelchair_when_not_disabled?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+54
+55
+56
+57
+58
+
+
# File 'sales/soft_validations.rb', line 54
+
+def wheelchair_when_not_disabled?
+  return unless disabled && wheel
+
+  wheel == 1 && disabled == 2
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/SetupValidations.html b/app/models/validations/doc/Validations/SetupValidations.html new file mode 100644 index 000000000..60286aa16 --- /dev/null +++ b/app/models/validations/doc/Validations/SetupValidations.html @@ -0,0 +1,679 @@ + + + + + + + Module: Validations::SetupValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::SetupValidations + + + +

+
+ + + + + + +
+
Includes:
+
CollectionTimeHelper, SharedValidations
+
+ + + + + + +
+
Defined in:
+
setup_validations.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + +
+

Instance Method Details

+ + +
+

+ + #validate_irproduct_other(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+69
+70
+71
+72
+73
+
+
# File 'setup_validations.rb', line 69
+
+def validate_irproduct_other(record)
+  if intermediate_product_rent_type?(record) && record.irproduct_other.blank?
+    record.errors.add :irproduct_other, I18n.t("validations.setup.intermediate_rent_product_name.blank")
+  end
+end
+
+
+ +
+

+ + #validate_location(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+75
+76
+77
+78
+79
+80
+81
+82
+
+
# File 'setup_validations.rb', line 75
+
+def validate_location(record)
+  location_during_startdate_validation(record)
+
+  if record.location&.status == :incomplete
+    record.errors.add :location_id, :incomplete, message: I18n.t("validations.setup.location.incomplete")
+    record.errors.add :scheme_id, :incomplete, message: I18n.t("validations.setup.location.incomplete")
+  end
+end
+
+
+ +
+

+ + #validate_managing_organisation_data_sharing_agremeent_signed(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+96
+97
+98
+99
+100
+101
+102
+
+
# File 'setup_validations.rb', line 96
+
+def validate_managing_organisation_data_sharing_agremeent_signed(record)
+  return if record.skip_dpo_validation
+
+  if record.managing_organisation_id_changed? && record.managing_organisation.present? && !record.managing_organisation.data_protection_confirmed?
+    record.errors.add :managing_organisation_id, I18n.t("validations.setup.managing_organisation.data_sharing_agreement_not_signed")
+  end
+end
+
+
+ +
+

+ + #validate_merged_organisations_start_date(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+59
+60
+61
+62
+63
+64
+65
+66
+67
+
+
# File 'setup_validations.rb', line 59
+
+def validate_merged_organisations_start_date(record)
+  return unless record.startdate && date_valid?("startdate", record)
+
+  return add_same_merge_organisation_error(record) if record.owning_organisation == record.managing_organisation
+  return add_same_merge_error(record) if organisations_belong_to_same_merge?(record.owning_organisation, record.managing_organisation)
+
+  add_merged_organisations_errors(record)
+  add_absorbing_organisations_errors(record)
+end
+
+
+ +
+

+ + #validate_organisation(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+
+
# File 'setup_validations.rb', line 23
+
+def validate_organisation(record)
+  created_by, managing_organisation, owning_organisation = record.values_at("created_by", "managing_organisation", "owning_organisation")
+  unless [created_by, managing_organisation, owning_organisation].any?(&:blank?) || ((created_by.organisation.absorbed_organisations + [created_by.organisation]) & [managing_organisation, owning_organisation]).present?
+    record.errors.add :created_by, I18n.t("validations.setup.created_by.invalid")
+    record.errors.add :owning_organisation_id, I18n.t("validations.setup.owning_organisation.invalid")
+    record.errors.add :managing_organisation_id, I18n.t("validations.setup.managing_organisation.invalid")
+  end
+  return unless record.startdate
+
+  if owning_organisation.present?
+    if owning_organisation&.merge_date.present? && owning_organisation.merge_date <= record.startdate
+      record.errors.add :owning_organisation_id, I18n.t("validations.setup.owning_organisation.inactive_merged_organisation",
+                                                        owning_organisation: record.owning_organisation.name,
+                                                        owning_organisation_merge_date: record.owning_organisation.merge_date.to_formatted_s(:govuk_date),
+                                                        owning_absorbing_organisation: record.owning_organisation.absorbing_organisation.name)
+    elsif owning_organisation&.absorbed_organisations.present? && owning_organisation.available_from.present? && owning_organisation.available_from.to_date > record.startdate.to_date
+      record.errors.add :owning_organisation_id, I18n.t("validations.setup.owning_organisation.inactive_absorbing_organisation",
+                                                        owning_organisation: record.owning_organisation.name,
+                                                        owning_organisation_available_from: record.owning_organisation.available_from.to_formatted_s(:govuk_date))
+    end
+  end
+
+  if managing_organisation.present?
+    if managing_organisation&.merge_date.present? && managing_organisation.merge_date <= record.startdate
+      record.errors.add :managing_organisation_id, I18n.t("validations.setup.managing_organisation.inactive_merged_organisation",
+                                                          managing_organisation: record.managing_organisation.name,
+                                                          managing_organisation_merge_date: record.managing_organisation.merge_date.to_formatted_s(:govuk_date),
+                                                          managing_absorbing_organisation: record.managing_organisation.absorbing_organisation.name)
+    elsif managing_organisation&.absorbed_organisations.present? && managing_organisation.available_from.present? && managing_organisation.available_from.to_date > record.startdate.to_date
+      record.errors.add :managing_organisation_id, I18n.t("validations.setup.managing_organisation.inactive_absorbing_organisation",
+                                                          managing_organisation: record.managing_organisation.name,
+                                                          managing_organisation_available_from: record.managing_organisation.available_from.to_formatted_s(:govuk_date))
+    end
+  end
+end
+
+
+ +
+

+ + #validate_scheme(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+92
+93
+94
+
+
# File 'setup_validations.rb', line 92
+
+def validate_scheme(record)
+  scheme_during_startdate_validation(record)
+end
+
+
+ +
+

+ + #validate_scheme_has_confirmed_locations_validation(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+84
+85
+86
+87
+88
+89
+90
+
+
# File 'setup_validations.rb', line 84
+
+def validate_scheme_has_confirmed_locations_validation(record)
+  return unless record.scheme
+
+  unless record.scheme.locations.confirmed.any?
+    record.errors.add :scheme_id, :no_completed_locations, message: I18n.t("validations.scheme.no_completed_locations")
+  end
+end
+
+
+ +
+

+ + #validate_startdate_setup(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+
+
# File 'setup_validations.rb', line 5
+
+def validate_startdate_setup(record)
+  return unless record.startdate && date_valid?("startdate", record) && !FeatureToggle.allow_future_form_use?
+
+  first_collection_start_date = if record.startdate_was.present?
+                                  editable_collection_start_date
+                                else
+                                  active_collection_start_date
+                                end
+
+  unless record.startdate.between?(first_collection_start_date, current_collection_end_date)
+    record.errors.add :startdate, startdate_validation_error_message
+  end
+
+  if record.startdate > Time.zone.today + 14.days
+    record.errors.add :startdate, I18n.t("validations.setup.startdate.later_than_14_days_after")
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/SharedValidations.html b/app/models/validations/doc/Validations/SharedValidations.html new file mode 100644 index 000000000..6c9807b39 --- /dev/null +++ b/app/models/validations/doc/Validations/SharedValidations.html @@ -0,0 +1,853 @@ + + + + + + + Module: Validations::SharedValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::SharedValidations + + + +

+
+ + + + + + +
+
Includes:
+
ActionView::Helpers::NumberHelper
+
+ + + + +
+
Included in:
+
DateValidations, FinancialValidations, HouseholdValidations, Validations::Sales::HouseholdValidations, Validations::Sales::SaleInformationValidations, Validations::Sales::SetupValidations, SetupValidations, TenancyValidations
+
+ + + +
+
Defined in:
+
shared_validations.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + #date_valid?(question, record) ⇒ Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+116
+117
+118
+119
+120
+121
+122
+123
+
+
# File 'shared_validations.rb', line 116
+
+def date_valid?(question, record)
+  if record[question].is_a?(ActiveSupport::TimeWithZone) && record[question].year.zero?
+    record.errors.add question, I18n.t("validations.date.invalid_date")
+    false
+  else
+    true
+  end
+end
+
+
+ +
+

+ + #inactive_status(date, resource) ⇒ Object + + + + + +

+ + + + +
+
+
+
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+
+
# File 'shared_validations.rb', line 87
+
+def inactive_status(date, resource)
+  return if date.blank? || resource.blank?
+
+  status = resource.status_at(date)
+  return unless %i[reactivating_soon activating_soon deactivated].include?(status)
+
+  closest_reactivation = resource.last_deactivation_before(date)
+  open_deactivation = resource.open_deactivation
+
+  date = case status
+         when :reactivating_soon then closest_reactivation.reactivation_date
+         when :activating_soon then resource&.available_from
+         when :deactivated then open_deactivation.deactivation_date
+         end
+
+  { scope: status, date: date&.to_formatted_s(:govuk_date), deactivation_date: closest_reactivation&.deactivation_date&.to_formatted_s(:govuk_date) }
+end
+
+
+ +
+

+ + #location_during_startdate_validation(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+
+
# File 'shared_validations.rb', line 67
+
+def location_during_startdate_validation(record)
+  location_inactive_status = inactive_status(record.startdate, record.location)
+
+  if location_inactive_status.present?
+    date, scope, deactivation_date = location_inactive_status.values_at(:date, :scope, :deactivation_date)
+    record.errors.add :startdate, :not_active, message: I18n.t("validations.setup.startdate.location.#{scope}.startdate", postcode: record.location.postcode, date:, deactivation_date:)
+    record.errors.add :location_id, :not_active, message: I18n.t("validations.setup.startdate.location.#{scope}.location_id", postcode: record.location.postcode, date:, deactivation_date:)
+    record.errors.add :scheme_id, :not_active, message: I18n.t("validations.setup.startdate.location.#{scope}.location_id", postcode: record.location.postcode, date:, deactivation_date:)
+  end
+end
+
+
+ +
+

+ + #scheme_during_startdate_validation(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+78
+79
+80
+81
+82
+83
+84
+85
+
+
# File 'shared_validations.rb', line 78
+
+def scheme_during_startdate_validation(record)
+  scheme_inactive_status = inactive_status(record.startdate, record.scheme)
+  if scheme_inactive_status.present?
+    date, scope, deactivation_date = scheme_inactive_status.values_at(:date, :scope, :deactivation_date)
+    record.errors.add :startdate, I18n.t("validations.setup.startdate.scheme.#{scope}.startdate", name: record.scheme.service_name, date:, deactivation_date:)
+    record.errors.add :scheme_id, I18n.t("validations.setup.startdate.scheme.#{scope}.scheme_id", name: record.scheme.service_name, date:, deactivation_date:)
+  end
+end
+
+
+ +
+

+ + #shared_validate_partner_count(record, max_people) ⇒ Object + + + + + +

+ + + + +
+
+
+
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+
+
# File 'shared_validations.rb', line 105
+
+def shared_validate_partner_count(record, max_people)
+  return if record.form.start_year_after_2024?
+
+  partner_numbers = (2..max_people).select { |n| person_is_partner?(record["relat#{n}"]) }
+  if partner_numbers.count > 1
+    partner_numbers.each do |n|
+      record.errors.add "relat#{n}", I18n.t("validations.household.relat.one_partner")
+    end
+  end
+end
+
+
+ +
+

+ + #validate_numeric_min_max(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+
+
# File 'shared_validations.rb', line 19
+
+def validate_numeric_min_max(record)
+  record.form.numeric_questions.each do |question|
+    next unless question.min || question.max
+    next unless record[question.id] && question.page.routed_to?(record, nil)
+
+    begin
+      answer = Float(record.public_send("#{question.id}_before_type_cast"))
+    rescue ArgumentError
+      add_range_error(record, question)
+    end
+
+    next unless answer
+
+    if (question.min && question.min > answer) || (question.max && question.max < answer)
+      add_range_error(record, question)
+    end
+  end
+end
+
+
+ +
+

+ + #validate_numeric_step(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+
+
# File 'shared_validations.rb', line 38
+
+def validate_numeric_step(record)
+  record.form.numeric_questions.each do |question|
+    next unless question.step
+    next unless record[question.id] && question.page.routed_to?(record, nil)
+
+    value = record.public_send("#{question.id}_before_type_cast")
+    field = question.check_answer_label || question.id
+    incorrect_accuracy = (value.to_d * 100) % (question.step * 100) != 0
+
+    if question.step < 1 && incorrect_accuracy
+      record.errors.add question.id.to_sym, I18n.t("validations.numeric.nearest_hundredth", field:)
+    elsif incorrect_accuracy || value.to_d != value.to_i    # if the user enters a value in exponent notation (eg '4e1') the to_i method does not convert this to the correct value
+      field = question.check_answer_label || question.id
+      case question.step
+      when 1 then record.errors.add question.id.to_sym, :not_integer, message: I18n.t("validations.numeric.whole_number", field:)
+      when 10 then record.errors.add question.id.to_sym, I18n.t("validations.numeric.nearest_ten", field:)
+      end
+    end
+  end
+end
+
+
+ +
+

+ + #validate_other_field(record, value_other = nil, main_field = nil, other_field = nil, main_label = nil, other_label = nil) ⇒ Object + + + + + +

+ + + + +
+
+
+
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+
+
# File 'shared_validations.rb', line 4
+
+def validate_other_field(record, value_other = nil, main_field = nil, other_field = nil, main_label = nil, other_label = nil)
+  return unless main_field || other_field
+
+  main_field_label = main_label || main_field.to_s.humanize(capitalize: false)
+  other_field_label = other_label || other_field.to_s.humanize(capitalize: false)
+  if record[main_field] == value_other && record[other_field].blank?
+    record.errors.add main_field.to_sym, I18n.t("validations.other_field_missing", main_field_label:, other_field_label:)
+    record.errors.add other_field.to_sym, I18n.t("validations.other_field_missing", main_field_label:, other_field_label:)
+  end
+
+  if record[main_field] != value_other && record[other_field].present?
+    record.errors.add other_field.to_sym, I18n.t("validations.other_field_not_required", main_field_label:, other_field_label:)
+  end
+end
+
+
+ +
+

+ + #validate_owning_organisation_data_sharing_agremeent_signed(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+125
+126
+127
+128
+129
+130
+131
+
+
# File 'shared_validations.rb', line 125
+
+def validate_owning_organisation_data_sharing_agremeent_signed(record)
+  return if record.skip_dpo_validation
+
+  if record.owning_organisation_id_changed? && record.owning_organisation.present? && !record.owning_organisation.data_protection_confirmed?
+    record.errors.add :owning_organisation_id, I18n.t("validations.setup.owning_organisation.data_sharing_agreement_not_signed")
+  end
+end
+
+
+ +
+

+ + #validate_property_postcode(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+59
+60
+61
+62
+63
+64
+65
+
+
# File 'shared_validations.rb', line 59
+
+def validate_property_postcode(record)
+  postcode = record.postcode_full
+  if record.postcode_known? && (postcode.blank? || !postcode.match(POSTCODE_REGEXP))
+    error_message = I18n.t("validations.postcode")
+    record.errors.add :postcode_full, :wrong_format, message: error_message
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/SoftValidations.html b/app/models/validations/doc/Validations/SoftValidations.html new file mode 100644 index 000000000..29e6114c2 --- /dev/null +++ b/app/models/validations/doc/Validations/SoftValidations.html @@ -0,0 +1,1516 @@ + + + + + + + Module: Validations::SoftValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::SoftValidations + + + +

+
+ + + + + + +
+
Includes:
+
ChargesHelper
+
+ + + + + + +
+
Defined in:
+
soft_validations.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
ALLOWED_INCOME_RANGES = + +
+
{
+  1 => OpenStruct.new(soft_min: 143, soft_max: 730, hard_min: 90, hard_max: 1230),
+  2 => OpenStruct.new(soft_min: 67, soft_max: 620, hard_min: 50, hard_max: 950),
+  3 => OpenStruct.new(soft_min: 80, soft_max: 480, hard_min: 40, hard_max: 990),
+  4 => OpenStruct.new(soft_min: 50, soft_max: 370, hard_min: 10, hard_max: 450),
+  5 => OpenStruct.new(soft_min: 50, soft_max: 380, hard_min: 10, hard_max: 690),
+  6 => OpenStruct.new(soft_min: 53, soft_max: 540, hard_min: 10, hard_max: 890),
+  7 => OpenStruct.new(soft_min: 47, soft_max: 460, hard_min: 10, hard_max: 1300),
+  8 => OpenStruct.new(soft_min: 54, soft_max: 460, hard_min: 10, hard_max: 2000),
+  9 => OpenStruct.new(soft_min: 50, soft_max: 450, hard_min: 10, hard_max: 750),
+  0 => OpenStruct.new(soft_min: 50, soft_max: 580, hard_min: 10, hard_max: 1040),
+  10 => OpenStruct.new(soft_min: 47, soft_max: 730, hard_min: 10, hard_max: 2000),
+}.freeze
+ +
TWO_YEARS_IN_DAYS = + +
+
730
+ +
TEN_YEARS_IN_DAYS = + +
+
3650
+ +
PHRASES_LIKELY_TO_INDICATE_EXISTING_REASON_CATEGORY = + +
+
[
+  "Decant",
+  "Decanted",
+  "Refugee",
+  "Asylum",
+  "Ukraine",
+  "Ukrainian",
+  "Army",
+  "Military",
+  "Domestic Abuse",
+  "Domestic Violence",
+  "DA",
+  "DV",
+  "Relationship breakdown",
+  "Overcrowding",
+  "Overcrowded",
+  "Too small",
+  "More space",
+  "Bigger property",
+  "Damp",
+  "Mould",
+  "Fire",
+  "Repossession",
+  "Death",
+  "Deceased",
+  "Passed away",
+  "Prison",
+  "Hospital",
+].freeze
+ +
PHRASES_LIKELY_TO_INDICATE_EXISTING_REASON_CATEGORY_REGEX = + +
+
Regexp.union(
+  PHRASES_LIKELY_TO_INDICATE_EXISTING_REASON_CATEGORY.map { |phrase| Regexp.new("\\b[^[:alpha]]*#{phrase}[^[:alpha:]]*\\b", Regexp::IGNORECASE) },
+)
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + #all_tenants_age_and_gender_information_completed?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+78
+79
+80
+81
+82
+83
+84
+
+
# File 'soft_validations.rb', line 78
+
+def all_tenants_age_and_gender_information_completed?
+  person_count = hhmemb || 8
+
+  (1..person_count).all? do |n|
+    public_send("sex#{n}").present? && public_send("age#{n}").present? && details_known_or_lead_tenant?(n) && public_send("age#{n}_known").present? && public_send("age#{n}_known").zero?
+  end
+end
+
+
+ +
+

+ + #all_tenants_gender_information_completed?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+86
+87
+88
+89
+90
+91
+92
+
+
# File 'soft_validations.rb', line 86
+
+def all_tenants_gender_information_completed?
+  person_count = hhmemb || 8
+
+  (1..person_count).all? do |n|
+    public_send("sex#{n}").present? && details_known_or_lead_tenant?(n)
+  end
+end
+
+
+ +
+

+ + #female_in_pregnant_household_in_soft_validation_range?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+74
+75
+76
+
+
# File 'soft_validations.rb', line 74
+
+def female_in_pregnant_household_in_soft_validation_range?
+  all_tenants_age_and_gender_information_completed? && females_in_the_household? && !females_in_age_range(16, 50) && preg_occ == 1
+end
+
+
+ +
+

+ + #major_repairs_date_in_soft_range?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+97
+98
+99
+
+
# File 'soft_validations.rb', line 97
+
+def major_repairs_date_in_soft_range?
+  mrcdate.present? && startdate.present? && mrcdate.between?(startdate.to_date - TEN_YEARS_IN_DAYS, startdate.to_date - TWO_YEARS_IN_DAYS)
+end
+
+
+ +
+

+ + #multiple_partners?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+198
+199
+200
+201
+202
+203
+
+
# File 'soft_validations.rb', line 198
+
+def multiple_partners?
+  return unless hhmemb
+
+  max_person_with_details = sales? ? [hhmemb, 6].min : [hhmemb, 8].min
+  (2..max_person_with_details).many? { |n| public_send("relat#{n}") == "P" }
+end
+
+
+ +
+

+ + #net_income_higher_or_lower_textObject + + + + + +

+ + + + +
+
+
+
+105
+106
+107
+
+
# File 'soft_validations.rb', line 105
+
+def net_income_higher_or_lower_text
+  net_income_in_soft_max_range? ? "higher" : "lower"
+end
+
+
+ +
+

+ + #net_income_in_soft_max_range?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+18
+19
+20
+21
+22
+
+
# File 'soft_validations.rb', line 18
+
+def net_income_in_soft_max_range?
+  return unless weekly_net_income && ecstat1 && hhmemb
+
+  weekly_net_income.between?(applicable_income_range.soft_max, applicable_income_range.hard_max)
+end
+
+
+ +
+

+ + #net_income_in_soft_min_range?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+24
+25
+26
+27
+28
+
+
# File 'soft_validations.rb', line 24
+
+def net_income_in_soft_min_range?
+  return unless weekly_net_income && ecstat1 && hhmemb
+
+  weekly_net_income.between?(applicable_income_range.hard_min, applicable_income_range.soft_min)
+end
+
+
+ +
+

+ + #no_females_in_a_pregnant_household?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+70
+71
+72
+
+
# File 'soft_validations.rb', line 70
+
+def no_females_in_a_pregnant_household?
+  !females_in_the_household? && all_tenants_gender_information_completed? && preg_occ == 1
+end
+
+
+ +
+

+ + #pscharge_in_soft_max_range?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+
+
# File 'soft_validations.rb', line 126
+
+def pscharge_in_soft_max_range?
+  return unless pscharge && period && needstype && owning_organisation
+  return if weekly_value(pscharge).blank?
+
+  soft_max = if needstype == 1
+               owning_organisation.provider_type == "LA" ? 25 : 35
+             else
+               owning_organisation.provider_type == "LA" ? 75 : 100
+             end
+
+  provider_type = owning_organisation.provider_type_before_type_cast
+  hard_max = CHARGE_MAXIMA_PER_WEEK.dig(:pscharge, PROVIDER_TYPE[provider_type], NEEDSTYPE_VALUES[needstype])
+
+  weekly_pscharge = weekly_value(pscharge)
+  weekly_pscharge > soft_max && weekly_pscharge <= hard_max
+end
+
+
+ +
+

+ + #reasonother_might_be_existing_category?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+194
+195
+196
+
+
# File 'soft_validations.rb', line 194
+
+def reasonother_might_be_existing_category?
+  PHRASES_LIKELY_TO_INDICATE_EXISTING_REASON_CATEGORY_REGEX.match?(reasonother)
+end
+
+
+ +
+

+ + #rent_in_soft_max_range?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'soft_validations.rb', line 42
+
+def rent_in_soft_max_range?
+  return unless brent && weekly_value(brent) && startdate
+
+  rent_range = LaRentRange.find_by(
+    start_year: collection_start_year,
+    la:,
+    beds: beds_for_la_rent_range,
+    lettype: get_lettype,
+  )
+  if beds.present? && rent_range.present? && beds > LaRentRange::MAX_BEDS
+    weekly_value(brent) > rent_range.soft_max
+  elsif rent_range.present?
+    weekly_value(brent).between?(rent_range.soft_max, rent_range.hard_max)
+  end
+end
+
+
+ +
+

+ + #rent_in_soft_min_range?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+
+
# File 'soft_validations.rb', line 30
+
+def rent_in_soft_min_range?
+  return unless brent && weekly_value(brent) && startdate
+
+  rent_range = LaRentRange.find_by(
+    start_year: collection_start_year,
+    la:,
+    beds: beds_for_la_rent_range,
+    lettype: get_lettype,
+  )
+  rent_range.present? && weekly_value(brent).between?(rent_range.hard_min, rent_range.soft_min)
+end
+
+
+ +
+

+ + #scharge_in_soft_max_range?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+
+
# File 'soft_validations.rb', line 109
+
+def scharge_in_soft_max_range?
+  return unless scharge && period && needstype && owning_organisation
+  return if weekly_value(scharge).blank?
+
+  soft_max = if needstype == 1
+               owning_organisation.provider_type == "LA" ? 25 : 35
+             else
+               owning_organisation.provider_type == "LA" ? 100 : 200
+             end
+
+  provider_type = owning_organisation.provider_type_before_type_cast
+  hard_max = CHARGE_MAXIMA_PER_WEEK.dig(:scharge, PROVIDER_TYPE[provider_type], NEEDSTYPE_VALUES[needstype])
+
+  weekly_scharge = weekly_value(scharge)
+  weekly_scharge > soft_max && weekly_scharge <= hard_max
+end
+
+
+ +
+

+ + #supcharg_in_soft_max_range?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+
+
# File 'soft_validations.rb', line 143
+
+def supcharg_in_soft_max_range?
+  return unless supcharg && period && needstype && owning_organisation
+  return if weekly_value(supcharg).blank?
+
+  soft_max = if needstype == 1
+               owning_organisation.provider_type == "LA" ? 25 : 35
+             else
+               owning_organisation.provider_type == "LA" ? 75 : 85
+             end
+
+  provider_type = owning_organisation.provider_type_before_type_cast
+  hard_max = CHARGE_MAXIMA_PER_WEEK.dig(:supcharg, PROVIDER_TYPE[provider_type], NEEDSTYPE_VALUES[needstype])
+
+  weekly_supcharg = weekly_value(supcharg)
+  weekly_supcharg > soft_max && weekly_supcharg <= hard_max
+end
+
+
+ +
+

+ + #voiddate_in_soft_range?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+101
+102
+103
+
+
# File 'soft_validations.rb', line 101
+
+def voiddate_in_soft_range?
+  voiddate.present? && startdate.present? && voiddate.between?(startdate.to_date - TEN_YEARS_IN_DAYS, startdate.to_date - TWO_YEARS_IN_DAYS)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/Validations/TenancyValidations.html b/app/models/validations/doc/Validations/TenancyValidations.html new file mode 100644 index 000000000..812d2d626 --- /dev/null +++ b/app/models/validations/doc/Validations/TenancyValidations.html @@ -0,0 +1,584 @@ + + + + + + + Module: Validations::TenancyValidations + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Validations::TenancyValidations + + + +

+
+ + + + + + +
+
Includes:
+
SharedValidations
+
+ + + + + + +
+
Defined in:
+
tenancy_validations.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + #validate_general_needs_fixed_tenancy_length_affordable_social_rent(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+
+
# File 'tenancy_validations.rb', line 19
+
+def validate_general_needs_fixed_tenancy_length_affordable_social_rent(record)
+  return unless record.tenancy_type_fixed_term? && record.affordable_or_social_rent? && record.is_general_needs?
+  return if record.tenancylength.blank?
+
+  min_tenancy_length = 2
+  return if record.tenancylength.to_i.between?(min_tenancy_length, 99)
+
+  message = I18n.t("validations.tenancy.length.invalid_fixed", min_tenancy_length:)
+  record.errors.add :needstype, message
+  record.errors.add :rent_type, message
+  record.errors.add :tenancylength, :tenancylength_invalid, message: message
+  record.errors.add :tenancy, message
+end
+
+
+ +
+

+ + #validate_general_needs_fixed_tenancy_length_intermediate_rent(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+
+
# File 'tenancy_validations.rb', line 33
+
+def validate_general_needs_fixed_tenancy_length_intermediate_rent(record)
+  return unless record.tenancy_type_fixed_term? && !record.affordable_or_social_rent? && record.is_general_needs?
+  return if record.tenancylength.blank?
+
+  min_tenancy_length = 1
+  return if record.tenancylength.to_i.between?(min_tenancy_length, 99)
+
+  message = I18n.t("validations.tenancy.length.invalid_fixed", min_tenancy_length:)
+  record.errors.add :needstype, message
+  record.errors.add :rent_type, message
+  record.errors.add :tenancylength, :tenancylength_invalid, message: message
+  record.errors.add :tenancy, message
+end
+
+
+ +
+

+ + #validate_joint_tenancy(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+71
+72
+73
+74
+75
+76
+77
+78
+
+
# File 'tenancy_validations.rb', line 71
+
+def validate_joint_tenancy(record)
+  return unless record.collection_start_year && record.joint
+
+  if record.hhmemb == 1 && record.joint == 1 && record.collection_start_year >= 2022
+    record.errors.add :joint, :not_joint_tenancy, message: I18n.t("validations.tenancy.not_joint")
+    record.errors.add :hhmemb, I18n.t("validations.tenancy.joint_more_than_one_member")
+  end
+end
+
+
+ +
+

+ + #validate_other_tenancy_type(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+67
+68
+69
+
+
# File 'tenancy_validations.rb', line 67
+
+def validate_other_tenancy_type(record)
+  validate_other_field(record, 3, :tenancy, :tenancyother, "tenancy type", "other tenancy type")
+end
+
+
+ +
+

+ + #validate_periodic_tenancy_length(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'tenancy_validations.rb', line 47
+
+def validate_periodic_tenancy_length(record)
+  return unless record.is_periodic_tenancy? && record.tenancylength.present?
+
+  min_tenancy_length = 1
+  return if record.tenancylength.to_i.between?(min_tenancy_length, 99)
+
+  message = I18n.t("validations.tenancy.length.invalid_periodic", min_tenancy_length:)
+  record.errors.add :tenancylength, :tenancylength_invalid, message: message
+  record.errors.add :tenancy, message
+end
+
+
+ +
+

+ + #validate_supported_housing_fixed_tenancy_length(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+
+
# File 'tenancy_validations.rb', line 6
+
+def validate_supported_housing_fixed_tenancy_length(record)
+  return unless record.tenancy_type_fixed_term? && record.is_supported_housing?
+  return if record.tenancylength.blank?
+
+  min_tenancy_length = 1
+  return if record.tenancylength.to_i.between?(min_tenancy_length, 99)
+
+  message = I18n.t("validations.tenancy.length.invalid_fixed", min_tenancy_length:)
+  record.errors.add :needstype, message
+  record.errors.add :tenancylength, :tenancylength_invalid, message: message
+  record.errors.add :tenancy, message
+end
+
+
+ +
+

+ + #validate_tenancy_length_blank_when_not_required(record) ⇒ Object + + + + + +

+ + + + +
+
+
+
+58
+59
+60
+61
+62
+63
+64
+65
+
+
# File 'tenancy_validations.rb', line 58
+
+def validate_tenancy_length_blank_when_not_required(record)
+  return if record.tenancylength.blank?
+  return if record.tenancy_type_fixed_term? || record.is_periodic_tenancy?
+
+  message = I18n.t("validations.tenancy.length.fixed_term_not_required")
+  record.errors.add :tenancylength, :tenancylength_invalid, message: message
+  record.errors.add :tenancy, message
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/_index.html b/app/models/validations/doc/_index.html new file mode 100644 index 000000000..6c5778ed4 --- /dev/null +++ b/app/models/validations/doc/_index.html @@ -0,0 +1,246 @@ + + + + + + + Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
+ + +

Documentation by YARD 0.9.36

+
+

Alphabetic Index

+ +
+

Namespace Listing A-Z

+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/app/models/validations/doc/class_list.html b/app/models/validations/doc/class_list.html new file mode 100644 index 000000000..5f36869e7 --- /dev/null +++ b/app/models/validations/doc/class_list.html @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + Class List + + + + + + diff --git a/app/models/validations/doc/css/common.css b/app/models/validations/doc/css/common.css new file mode 100644 index 000000000..cf25c4523 --- /dev/null +++ b/app/models/validations/doc/css/common.css @@ -0,0 +1 @@ +/* Override this file with custom rules */ \ No newline at end of file diff --git a/app/models/validations/doc/css/full_list.css b/app/models/validations/doc/css/full_list.css new file mode 100644 index 000000000..fa3598242 --- /dev/null +++ b/app/models/validations/doc/css/full_list.css @@ -0,0 +1,58 @@ +body { + margin: 0; + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-size: 13px; + height: 101%; + overflow-x: hidden; + background: #fafafa; +} + +h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; } +.clear { clear: both; } +.fixed_header { position: fixed; background: #fff; width: 100%; padding-bottom: 10px; margin-top: 0; top: 0; z-index: 9999; height: 70px; } +#search { position: absolute; right: 5px; top: 9px; padding-left: 24px; } +#content.insearch #search, #content.insearch #noresults { background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat center left; } +#full_list { padding: 0; list-style: none; margin-left: 0; margin-top: 80px; font-size: 1.1em; } +#full_list ul { padding: 0; } +#full_list li { padding: 0; margin: 0; list-style: none; } +#full_list li .item { padding: 5px 5px 5px 12px; } +#noresults { padding: 7px 12px; background: #fff; } +#content.insearch #noresults { margin-left: 7px; } +li.collapsed ul { display: none; } +li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; } +li.collapsed a.toggle { opacity: 0.5; cursor: default; background-position: top left; } +li { color: #888; cursor: pointer; } +li.deprecated { text-decoration: line-through; font-style: italic; } +li.odd { background: #f0f0f0; } +li.even { background: #fafafa; } +.item:hover { background: #ddd; } +li small:before { content: "("; } +li small:after { content: ")"; } +li small.search_info { display: none; } +a, a:visited { text-decoration: none; color: #05a; } +li.clicked > .item { background: #05a; color: #ccc; } +li.clicked > .item a, li.clicked > .item a:visited { color: #eee; } +li.clicked > .item a.toggle { opacity: 0.5; background-position: bottom right; } +li.collapsed.clicked a.toggle { background-position: top right; } +#search input { border: 1px solid #bbb; border-radius: 3px; } +#full_list_nav { margin-left: 10px; font-size: 0.9em; display: block; color: #aaa; } +#full_list_nav a, #nav a:visited { color: #358; } +#full_list_nav a:hover { background: transparent; color: #5af; } +#full_list_nav span:after { content: ' | '; } +#full_list_nav span:last-child:after { content: ''; } + +#content h1 { margin-top: 0; } +li { white-space: nowrap; cursor: normal; } +li small { display: block; font-size: 0.8em; } +li small:before { content: ""; } +li small:after { content: ""; } +li small.search_info { display: none; } +#search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #888; padding-left: 0; padding-right: 24px; } +#content.insearch #search { background-position: center right; } +#search input { width: 110px; } + +#full_list.insearch ul { display: block; } +#full_list.insearch .item { display: none; } +#full_list.insearch .found { display: block; padding-left: 11px !important; } +#full_list.insearch li a.toggle { display: none; } +#full_list.insearch li small.search_info { display: block; } diff --git a/app/models/validations/doc/css/style.css b/app/models/validations/doc/css/style.css new file mode 100644 index 000000000..eb0dbc86f --- /dev/null +++ b/app/models/validations/doc/css/style.css @@ -0,0 +1,497 @@ +html { + width: 100%; + height: 100%; +} +body { + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-size: 13px; + width: 100%; + margin: 0; + padding: 0; + display: flex; + display: -webkit-flex; + display: -ms-flexbox; +} + +#nav { + position: relative; + width: 100%; + height: 100%; + border: 0; + border-right: 1px dotted #eee; + overflow: auto; +} +.nav_wrap { + margin: 0; + padding: 0; + width: 20%; + height: 100%; + position: relative; + display: flex; + display: -webkit-flex; + display: -ms-flexbox; + flex-shrink: 0; + -webkit-flex-shrink: 0; + -ms-flex: 1 0; +} +#resizer { + position: absolute; + right: -5px; + top: 0; + width: 10px; + height: 100%; + cursor: col-resize; + z-index: 9999; +} +#main { + flex: 5 1; + -webkit-flex: 5 1; + -ms-flex: 5 1; + outline: none; + position: relative; + background: #fff; + padding: 1.2em; + padding-top: 0.2em; + box-sizing: border-box; +} + +@media (max-width: 920px) { + .nav_wrap { width: 100%; top: 0; right: 0; overflow: visible; position: absolute; } + #resizer { display: none; } + #nav { + z-index: 9999; + background: #fff; + display: none; + position: absolute; + top: 40px; + right: 12px; + width: 500px; + max-width: 80%; + height: 80%; + overflow-y: scroll; + border: 1px solid #999; + border-collapse: collapse; + box-shadow: -7px 5px 25px #aaa; + border-radius: 2px; + } +} + +@media (min-width: 920px) { + body { height: 100%; overflow: hidden; } + #main { height: 100%; overflow: auto; } + #search { display: none; } +} + +#main img { max-width: 100%; } +h1 { font-size: 25px; margin: 1em 0 0.5em; padding-top: 4px; border-top: 1px dotted #d5d5d5; } +h1.noborder { border-top: 0px; margin-top: 0; padding-top: 4px; } +h1.title { margin-bottom: 10px; } +h1.alphaindex { margin-top: 0; font-size: 22px; } +h2 { + padding: 0; + padding-bottom: 3px; + border-bottom: 1px #aaa solid; + font-size: 1.4em; + margin: 1.8em 0 0.5em; + position: relative; +} +h2 small { font-weight: normal; font-size: 0.7em; display: inline; position: absolute; right: 0; } +h2 small a { + display: block; + height: 20px; + border: 1px solid #aaa; + border-bottom: 0; + border-top-left-radius: 5px; + background: #f8f8f8; + position: relative; + padding: 2px 7px; +} +.clear { clear: both; } +.inline { display: inline; } +.inline p:first-child { display: inline; } +.docstring, .tags, #filecontents { font-size: 15px; line-height: 1.5145em; } +.docstring p > code, .docstring p > tt, .tags p > code, .tags p > tt { + color: #c7254e; background: #f9f2f4; padding: 2px 4px; font-size: 1em; + border-radius: 4px; +} +.docstring h1, .docstring h2, .docstring h3, .docstring h4 { padding: 0; border: 0; border-bottom: 1px dotted #bbb; } +.docstring h1 { font-size: 1.2em; } +.docstring h2 { font-size: 1.1em; } +.docstring h3, .docstring h4 { font-size: 1em; border-bottom: 0; padding-top: 10px; } +.summary_desc .object_link a, .docstring .object_link a { + font-family: monospace; font-size: 1.05em; + color: #05a; background: #EDF4FA; padding: 2px 4px; font-size: 1em; + border-radius: 4px; +} +.rdoc-term { padding-right: 25px; font-weight: bold; } +.rdoc-list p { margin: 0; padding: 0; margin-bottom: 4px; } +.summary_desc pre.code .object_link a, .docstring pre.code .object_link a { + padding: 0px; background: inherit; color: inherit; border-radius: inherit; +} + +/* style for */ +#filecontents table, .docstring table { border-collapse: collapse; } +#filecontents table th, #filecontents table td, +.docstring table th, .docstring table td { border: 1px solid #ccc; padding: 8px; padding-right: 17px; } +#filecontents table tr:nth-child(odd), +.docstring table tr:nth-child(odd) { background: #eee; } +#filecontents table tr:nth-child(even), +.docstring table tr:nth-child(even) { background: #fff; } +#filecontents table th, .docstring table th { background: #fff; } + +/* style for
    */ +#filecontents li > p, .docstring li > p { margin: 0px; } +#filecontents ul, .docstring ul { padding-left: 20px; } +/* style for
    */ +#filecontents dl, .docstring dl { border: 1px solid #ccc; } +#filecontents dt, .docstring dt { background: #ddd; font-weight: bold; padding: 3px 5px; } +#filecontents dd, .docstring dd { padding: 5px 0px; margin-left: 18px; } +#filecontents dd > p, .docstring dd > p { margin: 0px; } + +.note { + color: #222; + margin: 20px 0; + padding: 10px; + border: 1px solid #eee; + border-radius: 3px; + display: block; +} +.docstring .note { + border-left-color: #ccc; + border-left-width: 5px; +} +.note.todo { background: #ffffc5; border-color: #ececaa; } +.note.returns_void { background: #efefef; } +.note.deprecated { background: #ffe5e5; border-color: #e9dada; } +.note.title.deprecated { background: #ffe5e5; border-color: #e9dada; } +.note.private { background: #ffffc5; border-color: #ececaa; } +.note.title { padding: 3px 6px; font-size: 0.9em; font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; display: inline; } +.summary_signature + .note.title { margin-left: 7px; } +h1 .note.title { font-size: 0.5em; font-weight: normal; padding: 3px 5px; position: relative; top: -3px; text-transform: capitalize; } +.note.title { background: #efefef; } +.note.title.constructor { color: #fff; background: #6a98d6; border-color: #6689d6; } +.note.title.writeonly { color: #fff; background: #45a638; border-color: #2da31d; } +.note.title.readonly { color: #fff; background: #6a98d6; border-color: #6689d6; } +.note.title.private { background: #d5d5d5; border-color: #c5c5c5; } +.note.title.not_defined_here { background: transparent; border: none; font-style: italic; } +.discussion .note { margin-top: 6px; } +.discussion .note:first-child { margin-top: 0; } + +h3.inherited { + font-style: italic; + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-weight: normal; + padding: 0; + margin: 0; + margin-top: 12px; + margin-bottom: 3px; + font-size: 13px; +} +p.inherited { + padding: 0; + margin: 0; + margin-left: 25px; +} + +.box_info dl { + margin: 0; + border: 0; + width: 100%; + font-size: 1em; + display: flex; + display: -webkit-flex; + display: -ms-flexbox; +} +.box_info dl dt { + flex-shrink: 0; + -webkit-flex-shrink: 1; + -ms-flex-shrink: 1; + width: 100px; + text-align: right; + font-weight: bold; + border: 1px solid #aaa; + border-width: 1px 0px 0px 1px; + padding: 6px 0; + padding-right: 10px; +} +.box_info dl dd { + flex-grow: 1; + -webkit-flex-grow: 1; + -ms-flex: 1; + max-width: 420px; + padding: 6px 0; + padding-right: 20px; + border: 1px solid #aaa; + border-width: 1px 1px 0 0; + overflow: hidden; + position: relative; +} +.box_info dl:last-child > * { + border-bottom: 1px solid #aaa; +} +.box_info dl:nth-child(odd) > * { background: #eee; } +.box_info dl:nth-child(even) > * { background: #fff; } +.box_info dl > * { margin: 0; } + +ul.toplevel { list-style: none; padding-left: 0; font-size: 1.1em; } +.index_inline_list { padding-left: 0; font-size: 1.1em; } + +.index_inline_list li { + list-style: none; + display: inline-block; + padding: 0 12px; + line-height: 30px; + margin-bottom: 5px; +} + +dl.constants { margin-left: 10px; } +dl.constants dt { font-weight: bold; font-size: 1.1em; margin-bottom: 5px; } +dl.constants.compact dt { display: inline-block; font-weight: normal } +dl.constants dd { width: 75%; white-space: pre; font-family: monospace; margin-bottom: 18px; } +dl.constants .docstring .note:first-child { margin-top: 5px; } + +.summary_desc { + margin-left: 32px; + display: block; + font-family: sans-serif; + font-size: 1.1em; + margin-top: 8px; + line-height: 1.5145em; + margin-bottom: 0.8em; +} +.summary_desc tt { font-size: 0.9em; } +dl.constants .note { padding: 2px 6px; padding-right: 12px; margin-top: 6px; } +dl.constants .docstring { margin-left: 32px; font-size: 0.9em; font-weight: normal; } +dl.constants .tags { padding-left: 32px; font-size: 0.9em; line-height: 0.8em; } +dl.constants .discussion *:first-child { margin-top: 0; } +dl.constants .discussion *:last-child { margin-bottom: 0; } + +.method_details { border-top: 1px dotted #ccc; margin-top: 25px; padding-top: 0; } +.method_details.first { border: 0; margin-top: 5px; } +.method_details.first h3.signature { margin-top: 1em; } +p.signature, h3.signature { + font-size: 1.1em; font-weight: normal; font-family: Monaco, Consolas, Courier, monospace; + padding: 6px 10px; margin-top: 1em; + background: #E8F4FF; border: 1px solid #d8d8e5; border-radius: 5px; +} +p.signature tt, +h3.signature tt { font-family: Monaco, Consolas, Courier, monospace; } +p.signature .overload, +h3.signature .overload { display: block; } +p.signature .extras, +h3.signature .extras { font-weight: normal; font-family: sans-serif; color: #444; font-size: 1em; } +p.signature .not_defined_here, +h3.signature .not_defined_here, +p.signature .aliases, +h3.signature .aliases { display: block; font-weight: normal; font-size: 0.9em; font-family: sans-serif; margin-top: 0px; color: #555; } +p.signature .aliases .names, +h3.signature .aliases .names { font-family: Monaco, Consolas, Courier, monospace; font-weight: bold; color: #000; font-size: 1.2em; } + +.tags .tag_title { font-size: 1.05em; margin-bottom: 0; font-weight: bold; } +.tags .tag_title tt { color: initial; padding: initial; background: initial; } +.tags ul { margin-top: 5px; padding-left: 30px; list-style: square; } +.tags ul li { margin-bottom: 3px; } +.tags ul .name { font-family: monospace; font-weight: bold; } +.tags ul .note { padding: 3px 6px; } +.tags { margin-bottom: 12px; } + +.tags .examples .tag_title { margin-bottom: 10px; font-weight: bold; } +.tags .examples .inline p { padding: 0; margin: 0; font-weight: bold; font-size: 1em; } +.tags .examples .inline p:before { content: "â–¸"; font-size: 1em; margin-right: 5px; } + +.tags .overload .overload_item { list-style: none; margin-bottom: 25px; } +.tags .overload .overload_item .signature { + padding: 2px 8px; + background: #F1F8FF; border: 1px solid #d8d8e5; border-radius: 3px; +} +.tags .overload .signature { margin-left: -15px; font-family: monospace; display: block; font-size: 1.1em; } +.tags .overload .docstring { margin-top: 15px; } + +.defines { display: none; } + +#method_missing_details .notice.this { position: relative; top: -8px; color: #888; padding: 0; margin: 0; } + +.showSource { font-size: 0.9em; } +.showSource a, .showSource a:visited { text-decoration: none; color: #666; } + +#content a, #content a:visited { text-decoration: none; color: #05a; } +#content a:hover { background: #ffffa5; } + +ul.summary { + list-style: none; + font-family: monospace; + font-size: 1em; + line-height: 1.5em; + padding-left: 0px; +} +ul.summary a, ul.summary a:visited { + text-decoration: none; font-size: 1.1em; +} +ul.summary li { margin-bottom: 5px; } +.summary_signature { padding: 4px 8px; background: #f8f8f8; border: 1px solid #f0f0f0; border-radius: 5px; } +.summary_signature:hover { background: #CFEBFF; border-color: #A4CCDA; cursor: pointer; } +.summary_signature.deprecated { background: #ffe5e5; border-color: #e9dada; } +ul.summary.compact li { display: inline-block; margin: 0px 5px 0px 0px; line-height: 2.6em;} +ul.summary.compact .summary_signature { padding: 5px 7px; padding-right: 4px; } +#content .summary_signature:hover a, +#content .summary_signature:hover a:visited { + background: transparent; + color: #049; +} + +p.inherited a { font-family: monospace; font-size: 0.9em; } +p.inherited { word-spacing: 5px; font-size: 1.2em; } + +p.children { font-size: 1.2em; } +p.children a { font-size: 0.9em; } +p.children strong { font-size: 0.8em; } +p.children strong.modules { padding-left: 5px; } + +ul.fullTree { display: none; padding-left: 0; list-style: none; margin-left: 0; margin-bottom: 10px; } +ul.fullTree ul { margin-left: 0; padding-left: 0; list-style: none; } +ul.fullTree li { text-align: center; padding-top: 18px; padding-bottom: 12px; background: url(data:image/gif;base64,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) no-repeat top center; } +ul.fullTree li:first-child { padding-top: 0; background: transparent; } +ul.fullTree li:last-child { padding-bottom: 0; } +.showAll ul.fullTree { display: block; } +.showAll .inheritName { display: none; } + +#search { position: absolute; right: 12px; top: 0px; z-index: 9000; } +#search a { + display: block; float: left; + padding: 4px 8px; text-decoration: none; color: #05a; fill: #05a; + border: 1px solid #d8d8e5; + border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; + background: #F1F8FF; + box-shadow: -1px 1px 3px #ddd; +} +#search a:hover { background: #f5faff; color: #06b; fill: #06b; } +#search a.active { + background: #568; padding-bottom: 20px; color: #fff; fill: #fff; + border: 1px solid #457; + border-top-left-radius: 5px; border-top-right-radius: 5px; +} +#search a.inactive { color: #999; fill: #999; } +.inheritanceTree, .toggleDefines { + float: right; + border-left: 1px solid #aaa; + position: absolute; top: 0; right: 0; + height: 100%; + background: #f6f6f6; + padding: 5px; + min-width: 55px; + text-align: center; +} + +#menu { font-size: 1.3em; color: #bbb; } +#menu .title, #menu a { font-size: 0.7em; } +#menu .title a { font-size: 1em; } +#menu .title { color: #555; } +#menu a, #menu a:visited { color: #333; text-decoration: none; border-bottom: 1px dotted #bbd; } +#menu a:hover { color: #05a; } + +#footer { margin-top: 15px; border-top: 1px solid #ccc; text-align: center; padding: 7px 0; color: #999; } +#footer a, #footer a:visited { color: #444; text-decoration: none; border-bottom: 1px dotted #bbd; } +#footer a:hover { color: #05a; } + +#listing ul.alpha { font-size: 1.1em; } +#listing ul.alpha { margin: 0; padding: 0; padding-bottom: 10px; list-style: none; } +#listing ul.alpha li.letter { font-size: 1.4em; padding-bottom: 10px; } +#listing ul.alpha ul { margin: 0; padding-left: 15px; } +#listing ul small { color: #666; font-size: 0.7em; } + +li.r1 { background: #f0f0f0; } +li.r2 { background: #fafafa; } + +#content ul.summary li.deprecated .summary_signature a, +#content ul.summary li.deprecated .summary_signature a:visited { text-decoration: line-through; font-style: italic; } + +#toc { + position: relative; + float: right; + overflow-x: auto; + right: -3px; + margin-left: 20px; + margin-bottom: 20px; + padding: 20px; padding-right: 30px; + max-width: 300px; + z-index: 5000; + background: #fefefe; + border: 1px solid #ddd; + box-shadow: -2px 2px 6px #bbb; +} +#toc .title { margin: 0; } +#toc ol { padding-left: 1.8em; } +#toc li { font-size: 1.1em; line-height: 1.7em; } +#toc > ol > li { font-size: 1.1em; font-weight: bold; } +#toc ol > li > ol { font-size: 0.9em; } +#toc ol ol > li > ol { padding-left: 2.3em; } +#toc ol + li { margin-top: 0.3em; } +#toc.hidden { padding: 10px; background: #fefefe; box-shadow: none; } +#toc.hidden:hover { background: #fafafa; } +#filecontents h1 + #toc.nofloat { margin-top: 0; } +@media (max-width: 560px) { + #toc { + margin-left: 0; + margin-top: 16px; + float: none; + max-width: none; + } +} + +/* syntax highlighting */ +.source_code { display: none; padding: 3px 8px; border-left: 8px solid #ddd; margin-top: 5px; } +#filecontents pre.code, .docstring pre.code, .source_code pre { font-family: monospace; } +#filecontents pre.code, .docstring pre.code { display: block; } +.source_code .lines { padding-right: 12px; color: #555; text-align: right; } +#filecontents pre.code, .docstring pre.code, +.tags pre.example { + padding: 9px 14px; + margin-top: 4px; + border: 1px solid #e1e1e8; + background: #f7f7f9; + border-radius: 4px; + font-size: 1em; + overflow-x: auto; + line-height: 1.2em; +} +pre.code { color: #000; tab-size: 2; } +pre.code .info.file { color: #555; } +pre.code .val { color: #036A07; } +pre.code .tstring_content, +pre.code .heredoc_beg, pre.code .heredoc_end, +pre.code .qwords_beg, pre.code .qwords_end, pre.code .qwords_sep, +pre.code .words_beg, pre.code .words_end, pre.code .words_sep, +pre.code .qsymbols_beg, pre.code .qsymbols_end, pre.code .qsymbols_sep, +pre.code .symbols_beg, pre.code .symbols_end, pre.code .symbols_sep, +pre.code .tstring, pre.code .dstring { color: #036A07; } +pre.code .fid, pre.code .rubyid_new, pre.code .rubyid_to_s, +pre.code .rubyid_to_sym, pre.code .rubyid_to_f, +pre.code .dot + pre.code .id, +pre.code .rubyid_to_i pre.code .rubyid_each { color: #0085FF; } +pre.code .comment { color: #0066FF; } +pre.code .const, pre.code .constant { color: #585CF6; } +pre.code .label, +pre.code .symbol { color: #C5060B; } +pre.code .kw, +pre.code .rubyid_require, +pre.code .rubyid_extend, +pre.code .rubyid_include { color: #0000FF; } +pre.code .ivar { color: #318495; } +pre.code .gvar, +pre.code .rubyid_backref, +pre.code .rubyid_nth_ref { color: #6D79DE; } +pre.code .regexp, .dregexp { color: #036A07; } +pre.code a { border-bottom: 1px dotted #bbf; } +/* inline code */ +*:not(pre) > code { + padding: 1px 3px 1px 3px; + border: 1px solid #E1E1E8; + background: #F7F7F9; + border-radius: 4px; +} + +/* Color fix for links */ +#content .summary_desc pre.code .id > .object_link a, /* identifier */ +#content .docstring pre.code .id > .object_link a { color: #0085FF; } +#content .summary_desc pre.code .const > .object_link a, /* constant */ +#content .docstring pre.code .const > .object_link a { color: #585CF6; } diff --git a/app/models/validations/doc/file_list.html b/app/models/validations/doc/file_list.html new file mode 100644 index 000000000..1e32eeb50 --- /dev/null +++ b/app/models/validations/doc/file_list.html @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + File List + + + +
    +
    +

    File List

    + + + +
    + +
      + + + +
    +
    + + diff --git a/app/models/validations/doc/frames.html b/app/models/validations/doc/frames.html new file mode 100644 index 000000000..53734c221 --- /dev/null +++ b/app/models/validations/doc/frames.html @@ -0,0 +1,22 @@ + + + + + Documentation by YARD 0.9.36 + + + + diff --git a/app/models/validations/doc/index.html b/app/models/validations/doc/index.html new file mode 100644 index 000000000..6c5778ed4 --- /dev/null +++ b/app/models/validations/doc/index.html @@ -0,0 +1,246 @@ + + + + + + + Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
    + + +

    Documentation by YARD 0.9.36

    +
    +

    Alphabetic Index

    + +
    +

    Namespace Listing A-Z

    + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/app/models/validations/doc/js/app.js b/app/models/validations/doc/js/app.js new file mode 100644 index 000000000..8d067fe30 --- /dev/null +++ b/app/models/validations/doc/js/app.js @@ -0,0 +1,314 @@ +(function() { + +var localStorage = {}, sessionStorage = {}; +try { localStorage = window.localStorage; } catch (e) { } +try { sessionStorage = window.sessionStorage; } catch (e) { } + +function createSourceLinks() { + $('.method_details_list .source_code'). + before("[View source]"); + $('.toggleSource').toggle(function() { + $(this).parent().nextAll('.source_code').slideDown(100); + $(this).text("Hide source"); + }, + function() { + $(this).parent().nextAll('.source_code').slideUp(100); + $(this).text("View source"); + }); +} + +function createDefineLinks() { + var tHeight = 0; + $('.defines').after(" more..."); + $('.toggleDefines').toggle(function() { + tHeight = $(this).parent().prev().height(); + $(this).prev().css('display', 'inline'); + $(this).parent().prev().height($(this).parent().height()); + $(this).text("(less)"); + }, + function() { + $(this).prev().hide(); + $(this).parent().prev().height(tHeight); + $(this).text("more..."); + }); +} + +function createFullTreeLinks() { + var tHeight = 0; + $('.inheritanceTree').toggle(function() { + tHeight = $(this).parent().prev().height(); + $(this).parent().toggleClass('showAll'); + $(this).text("(hide)"); + $(this).parent().prev().height($(this).parent().height()); + }, + function() { + $(this).parent().toggleClass('showAll'); + $(this).parent().prev().height(tHeight); + $(this).text("show all"); + }); +} + +function searchFrameButtons() { + $('.full_list_link').click(function() { + toggleSearchFrame(this, $(this).attr('href')); + return false; + }); + window.addEventListener('message', function(e) { + if (e.data === 'navEscape') { + $('#nav').slideUp(100); + $('#search a').removeClass('active inactive'); + $(window).focus(); + } + }); + + $(window).resize(function() { + if ($('#search:visible').length === 0) { + $('#nav').removeAttr('style'); + $('#search a').removeClass('active inactive'); + $(window).focus(); + } + }); +} + +function toggleSearchFrame(id, link) { + var frame = $('#nav'); + $('#search a').removeClass('active').addClass('inactive'); + if (frame.attr('src') === link && frame.css('display') !== "none") { + frame.slideUp(100); + $('#search a').removeClass('active inactive'); + } + else { + $(id).addClass('active').removeClass('inactive'); + if (frame.attr('src') !== link) frame.attr('src', link); + frame.slideDown(100); + } +} + +function linkSummaries() { + $('.summary_signature').click(function() { + document.location = $(this).find('a').attr('href'); + }); +} + +function summaryToggle() { + $('.summary_toggle').click(function(e) { + e.preventDefault(); + localStorage.summaryCollapsed = $(this).text(); + $('.summary_toggle').each(function() { + $(this).text($(this).text() == "collapse" ? "expand" : "collapse"); + var next = $(this).parent().parent().nextAll('ul.summary').first(); + if (next.hasClass('compact')) { + next.toggle(); + next.nextAll('ul.summary').first().toggle(); + } + else if (next.hasClass('summary')) { + var list = $('
    '); + list.html(next.html()); + list.find('.summary_desc, .note').remove(); + list.find('a').each(function() { + $(this).html($(this).find('strong').html()); + $(this).parent().html($(this)[0].outerHTML); + }); + next.before(list); + next.toggle(); + } + }); + return false; + }); + if (localStorage.summaryCollapsed == "collapse") { + $('.summary_toggle').first().click(); + } else { localStorage.summaryCollapsed = "expand"; } +} + +function constantSummaryToggle() { + $('.constants_summary_toggle').click(function(e) { + e.preventDefault(); + localStorage.summaryCollapsed = $(this).text(); + $('.constants_summary_toggle').each(function() { + $(this).text($(this).text() == "collapse" ? "expand" : "collapse"); + var next = $(this).parent().parent().nextAll('dl.constants').first(); + if (next.hasClass('compact')) { + next.toggle(); + next.nextAll('dl.constants').first().toggle(); + } + else if (next.hasClass('constants')) { + var list = $('
    '); + list.html(next.html()); + list.find('dt').each(function() { + $(this).addClass('summary_signature'); + $(this).text( $(this).text().split('=')[0]); + if ($(this).has(".deprecated").length) { + $(this).addClass('deprecated'); + }; + }); + // Add the value of the constant as "Tooltip" to the summary object + list.find('pre.code').each(function() { + console.log($(this).parent()); + var dt_element = $(this).parent().prev(); + var tooltip = $(this).text(); + if (dt_element.hasClass("deprecated")) { + tooltip = 'Deprecated. ' + tooltip; + }; + dt_element.attr('title', tooltip); + }); + list.find('.docstring, .tags, dd').remove(); + next.before(list); + next.toggle(); + } + }); + return false; + }); + if (localStorage.summaryCollapsed == "collapse") { + $('.constants_summary_toggle').first().click(); + } else { localStorage.summaryCollapsed = "expand"; } +} + +function generateTOC() { + if ($('#filecontents').length === 0) return; + var _toc = $('
      '); + var show = false; + var toc = _toc; + var counter = 0; + var tags = ['h2', 'h3', 'h4', 'h5', 'h6']; + var i; + var curli; + if ($('#filecontents h1').length > 1) tags.unshift('h1'); + for (i = 0; i < tags.length; i++) { tags[i] = '#filecontents ' + tags[i]; } + var lastTag = parseInt(tags[0][1], 10); + $(tags.join(', ')).each(function() { + if ($(this).parents('.method_details .docstring').length != 0) return; + if (this.id == "filecontents") return; + show = true; + var thisTag = parseInt(this.tagName[1], 10); + if (this.id.length === 0) { + var proposedId = $(this).attr('toc-id'); + if (typeof(proposedId) != "undefined") this.id = proposedId; + else { + var proposedId = $(this).text().replace(/[^a-z0-9-]/ig, '_'); + if ($('#' + proposedId).length > 0) { proposedId += counter; counter++; } + this.id = proposedId; + } + } + if (thisTag > lastTag) { + for (i = 0; i < thisTag - lastTag; i++) { + if ( typeof(curli) == "undefined" ) { + curli = $('
    1. '); + toc.append(curli); + } + toc = $('
        '); + curli.append(toc); + curli = undefined; + } + } + if (thisTag < lastTag) { + for (i = 0; i < lastTag - thisTag; i++) { + toc = toc.parent(); + toc = toc.parent(); + } + } + var title = $(this).attr('toc-title'); + if (typeof(title) == "undefined") title = $(this).text(); + curli =$('
      1. ' + title + '
      2. '); + toc.append(curli); + lastTag = thisTag; + }); + if (!show) return; + html = ''; + $('#content').prepend(html); + $('#toc').append(_toc); + $('#toc .hide_toc').toggle(function() { + $('#toc .top').slideUp('fast'); + $('#toc').toggleClass('hidden'); + $('#toc .title small').toggle(); + }, function() { + $('#toc .top').slideDown('fast'); + $('#toc').toggleClass('hidden'); + $('#toc .title small').toggle(); + }); +} + +function navResizeFn(e) { + if (e.which !== 1) { + navResizeFnStop(); + return; + } + + sessionStorage.navWidth = e.pageX.toString(); + $('.nav_wrap').css('width', e.pageX); + $('.nav_wrap').css('-ms-flex', 'inherit'); +} + +function navResizeFnStop() { + $(window).unbind('mousemove', navResizeFn); + window.removeEventListener('message', navMessageFn, false); +} + +function navMessageFn(e) { + if (e.data.action === 'mousemove') navResizeFn(e.data.event); + if (e.data.action === 'mouseup') navResizeFnStop(); +} + +function navResizer() { + $('#resizer').mousedown(function(e) { + e.preventDefault(); + $(window).mousemove(navResizeFn); + window.addEventListener('message', navMessageFn, false); + }); + $(window).mouseup(navResizeFnStop); + + if (sessionStorage.navWidth) { + navResizeFn({which: 1, pageX: parseInt(sessionStorage.navWidth, 10)}); + } +} + +function navExpander() { + var done = false, timer = setTimeout(postMessage, 500); + function postMessage() { + if (done) return; + clearTimeout(timer); + var opts = { action: 'expand', path: pathId }; + document.getElementById('nav').contentWindow.postMessage(opts, '*'); + done = true; + } + + window.addEventListener('message', function(event) { + if (event.data === 'navReady') postMessage(); + return false; + }, false); +} + +function mainFocus() { + var hash = window.location.hash; + if (hash !== '' && $(hash)[0]) { + $(hash)[0].scrollIntoView(); + } + + setTimeout(function() { $('#main').focus(); }, 10); +} + +function navigationChange() { + // This works around the broken anchor navigation with the YARD template. + window.onpopstate = function() { + var hash = window.location.hash; + if (hash !== '' && $(hash)[0]) { + $(hash)[0].scrollIntoView(); + } + }; +} + +$(document).ready(function() { + navResizer(); + navExpander(); + createSourceLinks(); + createDefineLinks(); + createFullTreeLinks(); + searchFrameButtons(); + linkSummaries(); + summaryToggle(); + constantSummaryToggle(); + generateTOC(); + mainFocus(); + navigationChange(); +}); + +})(); diff --git a/app/models/validations/doc/js/full_list.js b/app/models/validations/doc/js/full_list.js new file mode 100644 index 000000000..59069c5e2 --- /dev/null +++ b/app/models/validations/doc/js/full_list.js @@ -0,0 +1,216 @@ +(function() { + +var $clicked = $(null); +var searchTimeout = null; +var searchCache = []; +var caseSensitiveMatch = false; +var ignoreKeyCodeMin = 8; +var ignoreKeyCodeMax = 46; +var commandKey = 91; + +RegExp.escape = function(text) { + return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); +} + +function escapeShortcut() { + $(document).keydown(function(evt) { + if (evt.which == 27) { + window.parent.postMessage('navEscape', '*'); + } + }); +} + +function navResizer() { + $(window).mousemove(function(e) { + window.parent.postMessage({ + action: 'mousemove', event: {pageX: e.pageX, which: e.which} + }, '*'); + }).mouseup(function(e) { + window.parent.postMessage({action: 'mouseup'}, '*'); + }); + window.parent.postMessage("navReady", "*"); +} + +function clearSearchTimeout() { + clearTimeout(searchTimeout); + searchTimeout = null; +} + +function enableLinks() { + // load the target page in the parent window + $('#full_list li').on('click', function(evt) { + $('#full_list li').removeClass('clicked'); + $clicked = $(this); + $clicked.addClass('clicked'); + evt.stopPropagation(); + + if (evt.target.tagName === 'A') return true; + + var elem = $clicked.find('> .item .object_link a')[0]; + var e = evt.originalEvent; + var newEvent = new MouseEvent(evt.originalEvent.type); + newEvent.initMouseEvent(e.type, e.canBubble, e.cancelable, e.view, e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget); + elem.dispatchEvent(newEvent); + evt.preventDefault(); + return false; + }); +} + +function enableToggles() { + // show/hide nested classes on toggle click + $('#full_list a.toggle').on('click', function(evt) { + evt.stopPropagation(); + evt.preventDefault(); + $(this).parent().parent().toggleClass('collapsed'); + highlight(); + }); +} + +function populateSearchCache() { + $('#full_list li .item').each(function() { + var $node = $(this); + var $link = $node.find('.object_link a'); + if ($link.length > 0) { + searchCache.push({ + node: $node, + link: $link, + name: $link.text(), + fullName: $link.attr('title').split(' ')[0] + }); + } + }); +} + +function enableSearch() { + $('#search input').keyup(function(event) { + if (ignoredKeyPress(event)) return; + if (this.value === "") { + clearSearch(); + } else { + performSearch(this.value); + } + }); + + $('#full_list').after(""); +} + +function ignoredKeyPress(event) { + if ( + (event.keyCode > ignoreKeyCodeMin && event.keyCode < ignoreKeyCodeMax) || + (event.keyCode == commandKey) + ) { + return true; + } else { + return false; + } +} + +function clearSearch() { + clearSearchTimeout(); + $('#full_list .found').removeClass('found').each(function() { + var $link = $(this).find('.object_link a'); + $link.text($link.text()); + }); + $('#full_list, #content').removeClass('insearch'); + $clicked.parents().removeClass('collapsed'); + highlight(); +} + +function performSearch(searchString) { + clearSearchTimeout(); + $('#full_list, #content').addClass('insearch'); + $('#noresults').text('').hide(); + partialSearch(searchString, 0); +} + +function partialSearch(searchString, offset) { + var lastRowClass = ''; + var i = null; + for (i = offset; i < Math.min(offset + 50, searchCache.length); i++) { + var item = searchCache[i]; + var searchName = (searchString.indexOf('::') != -1 ? item.fullName : item.name); + var matchString = buildMatchString(searchString); + var matchRegexp = new RegExp(matchString, caseSensitiveMatch ? "" : "i"); + if (searchName.match(matchRegexp) == null) { + item.node.removeClass('found'); + item.link.text(item.link.text()); + } + else { + item.node.addClass('found'); + item.node.removeClass(lastRowClass).addClass(lastRowClass == 'r1' ? 'r2' : 'r1'); + lastRowClass = item.node.hasClass('r1') ? 'r1' : 'r2'; + item.link.html(item.name.replace(matchRegexp, "$&")); + } + } + if(i == searchCache.length) { + searchDone(); + } else { + searchTimeout = setTimeout(function() { + partialSearch(searchString, i); + }, 0); + } +} + +function searchDone() { + searchTimeout = null; + highlight(); + if ($('#full_list li:visible').size() === 0) { + $('#noresults').text('No results were found.').hide().fadeIn(); + } else { + $('#noresults').text('').hide(); + } + $('#content').removeClass('insearch'); +} + +function buildMatchString(searchString, event) { + caseSensitiveMatch = searchString.match(/[A-Z]/) != null; + var regexSearchString = RegExp.escape(searchString); + if (caseSensitiveMatch) { + regexSearchString += "|" + + $.map(searchString.split(''), function(e) { return RegExp.escape(e); }). + join('.+?'); + } + return regexSearchString; +} + +function highlight() { + $('#full_list li:visible').each(function(n) { + $(this).removeClass('even odd').addClass(n % 2 == 0 ? 'odd' : 'even'); + }); +} + +/** + * Expands the tree to the target element and its immediate + * children. + */ +function expandTo(path) { + var $target = $(document.getElementById('object_' + path)); + $target.addClass('clicked'); + $target.removeClass('collapsed'); + $target.parentsUntil('#full_list', 'li').removeClass('collapsed'); + if($target[0]) { + window.scrollTo(window.scrollX, $target.offset().top - 250); + highlight(); + } +} + +function windowEvents(event) { + var msg = event.data; + if (msg.action === "expand") { + expandTo(msg.path); + } + return false; +} + +window.addEventListener("message", windowEvents, false); + +$(document).ready(function() { + escapeShortcut(); + navResizer(); + enableLinks(); + enableToggles(); + populateSearchCache(); + enableSearch(); +}); + +})(); diff --git a/app/models/validations/doc/js/jquery.js b/app/models/validations/doc/js/jquery.js new file mode 100644 index 000000000..198b3ff07 --- /dev/null +++ b/app/models/validations/doc/js/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7.1 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
        a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
        "+""+"
        ",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
        t
        ",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
        ",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

        ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
        ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
        ","
        "],thead:[1,"","
        "],tr:[2,"","
        "],td:[3,"","
        "],col:[2,"","
        "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
        ","
        "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
        ").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/app/models/validations/doc/method_list.html b/app/models/validations/doc/method_list.html new file mode 100644 index 000000000..bc0fb538f --- /dev/null +++ b/app/models/validations/doc/method_list.html @@ -0,0 +1,1179 @@ + + + + + + + + + + + + + + + + + + Method List + + + +
        +
        +

        Method List

        + + + +
        + + +
        + + diff --git a/app/models/validations/doc/top-level-namespace.html b/app/models/validations/doc/top-level-namespace.html new file mode 100644 index 000000000..22e249e03 --- /dev/null +++ b/app/models/validations/doc/top-level-namespace.html @@ -0,0 +1,100 @@ + + + + + + + Top Level Namespace + + — Documentation by YARD 0.9.36 + + + + + + + + + + + + + + + + + + + +
        + + +

        Top Level Namespace + + + +

        +
        + + + + + + + + + + + +
        + + + + + + + + + + +
        + + + +
        + + \ No newline at end of file