From 60f570c947303258e71adb1137ffe2d1861bd50e Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 5 Jan 2025 18:33:39 +0000 Subject: [PATCH] 2024-02-24 --- Websites/SharePrices/.vs/SharePrices/v16/.suo | Bin 0 -> 59904 bytes Websites/SharePrices/.vs/SharePrices/v17/.suo | Bin 58368 -> 108032 bytes Websites/SharePrices/SharePrices.v12.suo | Bin 69120 -> 70656 bytes .../SharePrices/App_Code/DataAccessLayer.vb | 26 +- .../SharePrices/CreateDBSchema.sql | 278 +- .../SharePrices/SharePrices/SharePrices.aspx | 21 +- .../SharePrices/SharePrices.aspx.vb | 28 +- .../SharePrices/SharePricesStyles.css | 28 +- .../SharePrices/bin/SharePrices.dll | Bin 44032 -> 45056 bytes .../SharePrices/bin/SharePrices.pdb | Bin 73216 -> 75264 bytes .../SharePrices/obj/Debug/SharePrices.dll | Bin 44032 -> 45056 bytes .../SharePrices/obj/Debug/SharePrices.pdb | Bin 73216 -> 75264 bytes .../SharePrices/scripts/SharePrices.js | 2957 +++++++++-------- 13 files changed, 2004 insertions(+), 1334 deletions(-) create mode 100644 Websites/SharePrices/.vs/SharePrices/v16/.suo diff --git a/Websites/SharePrices/.vs/SharePrices/v16/.suo b/Websites/SharePrices/.vs/SharePrices/v16/.suo new file mode 100644 index 0000000000000000000000000000000000000000..df1a7c163f86d7a7afd616a071e9b935ce348211 GIT binary patch literal 59904 zcmeHQ34Bz={hxiP^%m4B^}vXLc73$T?dSI

}Xa0md8TU?IR zz;w}xzaEh%Dn$qUZqdi4^z8N!TlcrOKgCzUMNb_+ZS`xuafr9-NELY+Fm{SoF&WsK z@vBlSNRdkX>pjo|tyLZW*7@lR1f%;(7ZT${fhZFp5ybxz;m7|leh2X@gue>>nk95D zYfwXVfF|>6A;xEbpJQrAGX-z>XNW2>MU(?~mx%V`=8tj0@TFV+t?}JfW-9x_|I(5G z$1>f{2&cate1`2|K5uLKW8kwKe77t74l|tJ(2d43aqMk|4~Jg}*bA^dU@AbxO#HtO z-m!k{Z>;&Wzq3B?f^Un>?@Qp12TTAQ4mbk9u6Gom6u|GwO@ET<>$HxwJy+v-3g9@v z2*5NzEnp@o)#LXPn0W{s`yzCkcl0Y5OGe+2(rz>m%6^Wk3rxX^sQ$n-CU|5Lyv z<}=gMa5ciN0Q?egrTPA5_`d*L1GpA&AK+HNO@QkGHvnz~FpXcC{xbNtn7?m>e>-3~ z;MagV0CxiJ0^AMw4dAzcdjR(W9tPYGSOHiGcmVJqU=`pYz+-?%0FMHQ^Ktl30GgfCSJ5-@6+Q{60h<4e*MeV?tv{UH)-8s-w^HABs0YfLHvdBQ9wZU26PA zDx%AOUH`;Q=MpV0_`7)0^`9F5miCXUJljLAxBm%p)Hh<>&4+AL2P#k}W@AitV=SH^ z=HOQc`e>K*n=nf4E}VhP1ii?~amZo2q#8`(NZ_X^ zF#+JU|C3(q2%z(de+F{V2|C$>`m)O4kpHFpeH7C2il2Bj{uX5n)?1QabqSWNVb6CD>0I&^v^fm;rt( z{hfjtV5Z2!ti#%kl{XI>j~0Y*c1Y$h{?aZ#B}yb~?JewM5S#%56eRVe(~W(C;sljmqa4#)+lo}UamWk|y}9BJ(U z@LKYs<9a>%86?SB=B>o)$>e5_`D zQle5&f-Z0-oC7H#bYe_e9q^}3|EXiz%1opNIO^m$pChplGi4Hvd(yt+K?TSSwcvjg zb8w5C17kTTHs^oxG+xVZ9e>IAk6MYjN6bJD>-%x@i$>&Zj-<<&e|-~8++OhyLHykT zbmWET-aD}U)w@?L{@pxanp9Rjd4GgWfh{Pn-}b>e=@AiAV$;-dYQwGvE`0sN%k=jh zGS2~_)5&v9hc(}WKhoRTC`$mg7S?eKp6sa{;F^l+ACzAkP)mBwNR}3JbhN}W2j9$* zt*3;;%_kdzOQB5JBCuM6``X0nM`JtIYJ9z^ii{%tgEa_~Avn{k0KZw7 zb}#tZv)vure+i{&VJaqVWTz|7up}j8kLIg-voc|e?AIy8#rXOa_{-qm+Xe1+8(5=G6Jjyg%s5@ZGZS!BV!h5c!y%%0Zr6V0L>0!?WvrWr54P04paDK6Npy zZ3y4)CqgWN|16MShVV5Y>)T+m*!5B&nt}h$D-j>*{qK5(V51m5BkKSOyZ-0nj!5n}G0K5;+l<(RvD;+ZL^Blu4r zD8za2$0NP(J_@{uH|H^*_yYb@PpIcRpH$D|-|>l|sFzFM^@;0{&XMbVf)Ai+{9`Q#!UTjpHMYoejP1 zO&vYa$h?+lZ(Unnw5PYRr8BRqyR)^a0m0EZb=^%}-7O7GuD_!_eQizAKtnV^TQppt z9pW7FB=!STtnyWi5906i(z1fWl8S<`KO8O?=PxL#Ebtdsh06R@#rfgF%Hp!3;$Z2b zg*D8^G?fj@@4&oz=5*mkDoLO&+O=Te!qW?j@Re5I+4y<$wN?Aux2s>uU|jR#@HjvhuGq z{SBu7>??){qo39O-Vo=&pZy0z{0HCdgiiYio|n9>(*NRJL;MZ&c*J{#xCHN4exSn7 z{m>BmqTh;-3`uA8-1YcMmCup~RX!~>qN+mv@2{l{!qRDfojg1BnSk`<(J5kGIfg#m z;=TVJKJ~l>m|&C)8Yidv)+MHu-U+9`VQo7U=1JWcDbKXM1jxG05z^z$n8ANJ>o=s#_~ja7f3^B5;g z{{xH<_U9efsQ$bRLV9>8n)t@=m)P6c2hhBFkfOA0K{AD2G||&O~4+2Jpo|)#J2!!AJT|@0AMKP+F4G(d4T-^BLN2h zMgc|x#sI*8N$P$O{DT3901gHC0RcchAP5Kn!T^?ml5!ycOt92PvtFpZ8V{HNI2^!w zqP_Siz(hbPpbStBu-3yQJRfZdI~KpI0bmg0;_;j52&)0GPxHAJ{s{mueQ|Lkcs>Pi zDqxoRuFmvl!*2vM0h-OQIq+KmFe-hKDlwu+;r4!M}b#s z)+ue0`t(RToZR-v?=k*-?2nkxJ@@}h5tlT8E|va?{VbUye)etlW3S~u3~}E#6OA9` zb`7{0DT$W{{2W)?0KDRV6LC3i>Fo7C6Rkn|r^BNvn(O~e=-*pNP1nDbvfJ06OhfPQ zz#r{UG2KUejxyQ*@JHY$Eu*VNdG*>3T3Z)j1hD*Ei;>Fq%kM{`{&#~9LDqBq{{eB? zU+L`g-wAT`(Jn#lOKPXvpKVW<`U|!8i?o`q4EU%aq3xm*)Pr_Ez0#yY=7ki>-BJIk zFsuLWF=KB|!cWc%JT2O0_CZi^}AE{eX zMy>ggS&sV`H1Tt8VLswsx;z|*aE(71{i#47>~={*2b2CVtvrBN{7Vq`J0zNL$?%gm z;oO?cWitL-k>I0dqN(t6K2PRYewKR_B6%%;1LCeV6Fm{_+Xg;fjRLjyEp@Mp<%szA z#UpuIulRq5xIZwHn1MF#0)8!FDJz|_4U#s@1BVlo+>iNz%{v(Q$q$j9dBsouK_^p= z(sKrmN;!v8pB{mBPE&so?`P8fR{S$D&M1*_WgF>y{CG@F0ZD&ZZtdc8=lqloevW}; zPTOBNpD_=~;_7!+{Io&-0r9%E9@+zwBP? zpL6eKH2do6o_{X(Rmc?#>1#eXL$^xmjc0$FgVN0g-)3D?G7Iu&0J3TTR6K(6 zcVeXXqGpt3tsWzsvKJ|>9~5u_Qs6om+NTcqc6ibD#V1bOt6|MgGzN z%b#lgI&q_vf2m8Nj@K*xX^1;GeGN}1b42m43b@<$btfze*NsaP%33av8rFLueR zR_y`eK_R=oswfsLp+-E%C_e%eFMOw5)dc|)Y{~Lq; z9{}8JC9nAF5f_WZq}vGeU)oyJq5t0oW=;Q7(Lb$&bnAtg%zxJUx9j_~?ScAtd)w%J z$g1Ylf7*X2p>q9;*ZL>_K^+iX1@=!=L+eOgJMHhCn29wWr~S_AtJr_czY;HT)5YGn z|C)+dG5lO{lAP<}ekAG+dXU3#eWRqt}~O!hW)1$xHVO`x3T7d z(y;%eUH=n-U(0{-{VyZ?Pulpc{Xg0Kv#IPqWIeV0$1eZr^(b5R|0(-N4($I+yZ;SA z`|l2*v$uZ+^1p8nq$7!+NBZ|F;*$rWv*Ty~quo7~-B*1b+y9-8{_7QdtjE6{f2RAt zDbstUzfU0UrECN^cl_S>f9tyUir*{!VOwm`|LU1awU_-r`G3Y>fAU)Y=OONTdqM+v zPPhH7sI1>^`Tg~)0W0TeUw@S&=l}SQM2F`3PPU%4Z@c}b=%wwy$;xj%e@L$pqb}5T z{!jnh=M_KmrSZGvF`aO0uTAGW#y#-`X?jifv;O#_5>}8#MINL}o}e6pEtCI~Ir0vd zU>4*qdb=(n_3C?NgU;NBYuz*Ghh??}Ic|W?o0@KF6t2ly&b*yapw?dBleJt9Y!9Z= z8m%2PxliAMug+m;M4zGNfcrv}^8?rY# z?ES7v)_)I9iBl(}>sBCFenr+=!FlI&?0gZm^XQ_i<kyfz>0Lv zGh9`tdOwZm*`vbFBXg!)FVH4u3!Vj`blutOXLBOc&Ykn0d-LZvaPdOF1XTdhj4R_GhEEHbRkCrGt~du!_i}00TIy)DiQYrNlXFQg z=a^wa?m5n0-kfK6-NU&BBzv-#=GkKBuElDNGU;HWYcak}*B|XDcVw;KWjg-UUTN-> zEkWLs*`KKY9fvX|bD8Y_p!{$L4YqKp@E56QuK&6IazDI15a3K95)2^HP469bDhtuC?qW|I96;9_uc-2gWYip(ve`R^i zG;5B%>VMd91Cf7p`-QQBWgK=P6kz9kCI0)d_OJ?bSs8v+;dee(_!r_$F+z&)pC=S9 z!b}GmxVs>lW6_( z_dg~7W&MV~>8v#z#VlQiH728W__Fkn3m!W9*RS9F!fw}}uuHY*e(IRggO;=&d(*4e zoHc#@JvYlw5wo~?_lMU%JfeE(RgJe@HsX^Kx0u|;ug?QfSlA=G9I$uGeb`gvo)Bu5 z)$V)le&uQWq5XEW-X|jD*5Rp&YWEY{3jjfLAx7B znBIAq>g*McG3`i49tNa){tama(}@Cj$|`l&Zs)y3P{-6~mq3Q#I+b?(amTbeWrn#e z#~W=ap!RwST2zIG&|U$2ul55mm3;g~@GbXx^5lCZn<&bh>!oPGzEz%BsP0P2_0qJX zcd(7RWr;X*=6Z>ukRsVXb92ma#Ikoq;Wy-Lo7hW1Ub|qkDGhnSc3GO$IXGVIZPNg1 zPdcsoow^Aw*Jyywy&g3!n16UKIjO+f&7h5Vc6tYP({_S$Qrt{#&ZYKt;)xJ#uC4TS z*Z(CyZ+{B<1nV<<{GGiu=OI6&Cf#V$7HG#g`nVo3*Qp81#j|tNsf*n2&ywXL?Wb*^ z4RcpBN)+QU^z-IaCRNhSqn#4vD0DyRv>t#DiSobC)Es3h|Lc7mR!u=V@;~M8d4LH1 zI&o4TProC@=Xnv0INfeju8Lxf@NCriHob#7|H!I!;O;hO-GtI~Fz&YU+{TTmo0tGS z$Hvum1mx{CJb!~{9yN)Dz|a9%C=c{^8dOfSuyRKXPam9vUu~!zYdsvb(eo2q|DA4L zwntuQ!KB`39?DXVyz>-Ewgh+Mxu-nAqAlX7lLKjg_Fub8M>n+&AO9E1tx+ZQP0b~t zh5~=%xKIJkyDkX%>k5NGe`8Z&QK%?f+#ITJmKs5yA&&Xsk$rvFc20!msmxz9LmlFs zU(i%EuBkZWZ)z&2^M^u>L4RFSxXB+3)&(0%g3Zm%4f%^=(L=#-Lvdq4iNCm@qzk0(zA!H}thcyf3s)HE)?DO~I? z%r7bN7ZirW{<{27vp*avF3t}Y*A;|A@u}GLr%tL;<_L_Uqw9SC2I6&hV_&Qws zI8Z+2+3vs0TKS!IvZT`SD+HqAlr_r(Tiy7Lj_50wmt6O|DQ8&g;H{50Y}nHNU*GoE zeVu(mIdx&eGEMfxp{rKnH}&}yk0g=^c`1YS7J`%`#>2f14c+oMc+2@;IQSiRA{3Y9 z7l-ku?nDTMDnkC^;-Vl(d@xv5TvS+8QW0L{kjX)Es{^PB3K1?3h6>A(>++&-Ip(Q~ zAPP~Qk3y6N%S%F`V6dQMQSM(&@mOMC*%ZxiTh{1r;`$3O>&n89*3MheI;?ck13UiX zzdyZ#rq6_V=XwYgxa>w82>a=LjJ+E$M_-NsI0@_sE};>-W8u!_2)}!n5Sd<+f{s{P z2(BlDTTiMAN-F#X`4wgUl3-cLUsYICR+^6+M+yte7Xcma|52`GVrD!-G8&OR{=s?v zw6F5nZrg3|EgxO+r%&DtulsC5yEHgznyLL?pn_Ha8qg-!z+Z}X8;`KP3C$J=L9y%atK_ql-V4+m8dXDL2RXi zbH3dQ9>MJj?&~Jk?zt>@Vr`){ZumkUb=yvUz&OTtt+$R_l|YG ze8UId>MFf#U*m=P)t$%6t@e7HX zR+o4q9O*7qJx&77reIprW7_16aB0X6yIG6ROX2YCRJUr~H0$4RHJwNPA1o|ZN%2hN z%+|kUkAE5*{C@@3j0|M`pEvz~DOzb`YW8D#_$~Z@cJ-%A2hIHH%s;A~Zfj2Z@xi;@ z-?8E1vCn;W^{4McXo&HH2BhVEK*1}pqX1XZitj=Cx&wYSq~;*}n;~DkiTFhj6Ba}I z`UKKf9#RzO*mrqSe70ny%w&96f-vf=D}3EsTdyDFuGz5|n_Q895Jt4umCLN5 zdcdZxA)tUuTuV*-gf_Pc1~vxIdbio>ckA3}@0gCK)+q_ebsJ7H)ufPpQb=^B)9Oi?+$T+6Pj*LL841T&{#ZWp7*oG!*3Q#1Xi8935}J zJRyD$KW`*%b;tYdM+@;9`r__mg!nVU4;YKKg+KWqp7nvVuwdmIgXj7~kPhOX?-$}Z zghvBHya4~C!_cA7Fw7L9` z$Nl2k{a<<2H)D|JGXVRBx>fy{RoBWKqt?rJmbvC^)r*m6U;WKB6>b!=5#zQE*3ay< z4rPi~xi>-Q-%SPyfT!WNar@kON>NHR#S0bNtKw4`aA;n4#l)S zBgLV3s>Gg!nev?p{PXm#Y?-hh1WL{2Bh%7$5pjvBJOrShlP z#q{?#{gI}BfawQKzrgfInf_?gA7lDV&0c4d%Bm;tg79QgJLB-kG;im_C`q5+@QzBh zyq$An&GY;_a?iY5rVo9q13O7NQ6r?a{1y|l%ePE1c4G+d3S?cfb@@i|;)(BLDer@n zGn28HFW$TEJYK9^WFyMPoXtkgV(0tud(Io__RDINko|@{KRJhX^x6pO>NwN`#|&=_ z*fg5Do+C8$(r_>FGX+cK?>X#+KXSzcdV|sj3{+!b(^tn5^L7^ zd;1A}tegGuy>oxzZA3gRg|{Or?O{ODA?G^Ib4{lP>9D+%`)A9NlA1ZEa)4_pZll>f zE#}DU=yC2l6_wSKSx5CqDLq{m>#iBV^MEL=HDNr)_ktFLsqtgi%tah}SF)ZL>F;Tr zn|a;`dz4j1R(u3Dzeq_y>j^bgVhP)Fw1hmJhg6KCKK>R@u6H2!l&sVZIa+ExdwMBj zbIz8L6n4HzHN2FxJx5C#(_}4>BbW24o?pF`J6EaGiJ(!mR-_)Mr{-wOrY_ms94(pd zvz*(zG5=_7iI>(qEl10&G|en8^%B(HHetR^zx<1GwEUcF$pv%9RVVjN!EbU-9L0K0 zq6FE2aGtxZWiE2JsmDTZj@FAVd8`f;$D1e*d8>z9#B8WL9(W+`%3_Nbyx@-%NXD9^crk? z&*QhMrg=s-akC{@dgg*}m3_)u19p1A@jj)zyc(I5UwobUTbR6UEyWtolxx-+I@T;5 z+oKJBE^njBQWF-O*hZJ0d%ehBPPLb-eI{0J z#b+n>86Cr^)VZ%uv(AQ2CEUEU-n124OU&MG)s8#WfL+Vhi}`&Z_m?Z7*}c zF(?j#+$%X8TA^arSrkBAi7S4F4#Ao(T($EUp4Z^YoBQCuKOQ%G!2-X-5kee>y?iHE zVZ9jk_?>$!o*@*xk3qV}4g=l)HhA_wTGw)M&yMw`zjIey_^Z=CytL-DGj6yd`sxmM zvEKAHo+N1b6N7t0I#?PsSHb)H~HkG^7 zi&Y=!R2!SKeVY0w=icIE1#zmK&D9c`T!Un_ojTRZ#-pl29Dcna=7PUE1^$8Hx7IH+ zaPBzxty`3TpXr}+t08`d@aJzcLv-@h6_97sz5j1u>*qJ!8CKZm zfRYX5X1YJr^LhfJx3fcuX_daTfVdw@Q!k>Zu z5qaE@`$gV+UiG8fUob=)!l&aXMf#t=WQg10zrNPMjyas;@v`!-H2n>x|LiM<2&13X z{@xJhz@PmGL;MHd?SxMI2%eX`tJDX>dJv&_5Tc*A-GwNINlb-rr-pIYJ6h*qNh zl{?ya<2PHW4%%QLs1?iJ-Yt9i^j@0yv$r9;A(vNt1-;0*6`W;LtMrLx6&GbKf6nW? z)p?eK=LUMWT2wdCZ-W{ftW+*0LzB{RRkoeV@$|9m-Ar#EMOGT^$L(Bdl{oJckEhMl z>b;h=UK^iljvzv=?*ENQD{gwUxgHd`Q_h=|^|HJF*N^#N0eUy*1~npSP4!Ma)|G?x zgVR^{8Yr9B9Sm%D>%JTN-jZY|Q#ezV#F^7NChS@$d U3)VrkDvx|N*WlG*=Rt$`e_7{PcmMzZ literal 0 HcmV?d00001 diff --git a/Websites/SharePrices/.vs/SharePrices/v17/.suo b/Websites/SharePrices/.vs/SharePrices/v17/.suo index 029dbbf7d6c7dd928e412c418181fefe22677c86..a35604e32bb9512d1d9096c9a33a64e44a5d5784 100644 GIT binary patch delta 2095 zcmeIy$4^v29Ki8?!xI*KR#rf4i()TX6;Y8y4EAW;H5|}jOuR~rWo?Ko_J-*0*t^f( z#ZfG%SWvOA<)#Nu{snvBV)>3?%^FLL@un~NWPb1WCX=1t%x}x<^MlZIGMeGdAk z%T{eNr9UNXH6zg{CaL_X6~bsvDf~&ZO8eGQ>+(a#IImS2~w+ZgxF6wX(_wfMrcnEz}A2U9|Q#`|Sgz*B& zLEl~F?AMU+zn*`kp3Q^48arFqIq`Nc@zZ|#rY9mJ3Vx?w^TR*tx=|JOSTi&_q9WtN z;=4AIk%{HX@2xbH@P0Jx0%1=!Ln&_Mp877)E^^v)g}p$?w}Et(Uh>}1ucc&W*=6o8 z*Fpaw{-fF>1HOIqv|Qi48Z?{mq*svMP5eZPr1e>TfdS+&J3W}c klI}L{ue`54@>W-u%6o0LkSphu%G}{;vaDOY967V|XUFX^1ONa4 delta 1367 zcmdUvO-vI(6vsQ;ZCUDqAQcMMQlvs96&n#jP$&X{2tq3#%9kMGH)0RPgCSv~#uFjZ zr*bqdnwWUfJ?KSKl>-M8h(RD)@an~bNe^-m{0}M87!O?C6&?uW*(9NUnkba1Hpu_Ay_1Q0U*R&vB#hIbO=m;{I}Z{E0`t z?yniS6Qq()Ol#W`U9}VO6tG0c>!-wb|I1;1YOxO6G5%j2-Uf$BG+8OhBx-h(Qi*3S@i5Vw7lf$)!cIWr0FV zedBMQFuQi!=@DcX=Js#&a%hn}nW^sBWws%v=1Xd^5UjG3J<%bu^?rfG5vGwuBf!O;u zLv-^#dMvrvQF=Q!%yd*SUrwI+2b8*yr!EK+p3ed+q>6C4p0~OcK0->^N#DX23WY-x op+!c@qKA6E_KmxXn1%c{>1EX;HYBS3IGW5dt<3$7sn-X7119sTW&i*H diff --git a/Websites/SharePrices/SharePrices.v12.suo b/Websites/SharePrices/SharePrices.v12.suo index 6d2302ef1b4df577729325f45c2a38bc770c3bff..01a015430b0484672b48f6d964e30b220f1ad449 100644 GIT binary patch delta 7783 zcmd^E3s{v^y8hO`H;8f(5FrHx6mKZFK@>2Nt(&VN!bmommk`jlA`tBDs976tjf#`H zm-kbqWL|18PrK4imV1_i{$g`~7QM9LHv=bIvnop0oDz@~!*& z*Y~aOT^DMfGS+T3E-^)GzWz}u7NJPw_Z4hN!vY#^|B1_EYJfyE=aMF!%TKo-yu;7R5JLx7>cFo5d~_sIK~ z7DoC%;7N>vY%8r^$sMeSO#&tZ<-io60;mLLEiJS-wLF+0T8j)YjoR|lY~W~a1O6lq z!RVhYz~QzX}VVlbY^kHBVua zf3pq(JnU2ec+D(ckm(Pao{81W8egE68Ho-1$+ve2L1$m2Alyt2hIXt0Ox?) zAA;^=cto!A|LMHD6jBkKwh~TULj_b!C2;9tnn-1o0cit>;n=NC$v5Gd~sFd=&lLc|9}z2(W|2-%oC;9vL4y|Ct*<}WP_7q?tN z5hsMRQ-)7pOpm!u-;Z9A_D&A*vb@>}I~8vg%w&2=hO~FimwWCTBcpx%_DC7kHo{oIEzE6Wj9elgZd)pTFAubx+EOq> zGQaRx(iVEy$A|<|r9Sv!X%DOWJ0CmT=WgGckmelRC>vXwq)9W%8-w$Fc>2-bj$*0x z+K)t#{5q^*)c*d_DTP~C*+21lqGa{c4Sz+!w=^ArkBPvV7z=)ngk0-Q^b+I*Y@jB{ zMsPl}!S8$#$3ega#{3HM0QQ7h&DpM2K2q0JMm^bHER*7%bZLJ638_tvmD{!j`k*;w z4$CT%QDagZMANXJe~i4vnEO*2(F54S12Oyx?Dx}=KPH;!L&&k6iMpV?05&in)jA0bF-PnayUcm{`Ll z11FCgHy9s^be6TOyj1W!9j#zM+Lj8H!Ft-gYU4Nq$(zkL1Hc2Q7MYII5iDPsgE~;% ztumreG)#Vk$ccJiLcRcbq#E_HQr@Y7Ibp)4X=+ahm_c+Noy~L`NZumtmuUd}JljO2}zzuohs)G4-g2 zepYNE+7EfejiriyCcj0r3KP3{1V_Do*xazIalOD3s$P-2^WOVbIgB3Hk-nA#VzL9eTaIOOSs)QIcCwfArVw zkf6ON4>~O98_4Q+ReJPMq%l5SJ|n0BdiwOd(48~=&w`#sM?G3<^fbz+!0ULx;sA{{ z;E4BTM@{c=bEHPOsQ2?uDm}QfrVp?nU84|u*o6#@V0&`ISf9W?U*)Lu>0C`8$DF5; zg9kF?Yx-e+o=u}wXeef?f#*5Yz^St|%I->ZALOYPQ0;6@Un!FoYV;@uShq=|%FbXS zNGO3m+@jF|$P+JUG!hGC_*RYDgA^T*8<0O|helno()PWfIS8wgb|2En3mKpPUZWkT zaP*i)lVQ6nkloP1@{ctAznyVKzDHiHBU$M}bI>kbzzfvp|0ybh6vMf<7lqMAm z4O^jDD0RJJmFkU(RT_3F_Q}R9!9EUhy{{^q|43Cx3{vd!a&IMX3{Why#-dnbXtrXF z?nR1CUYw$&_LwSn)vEI7*@{(;LNcrTdah!X&Wo8;z|TwB?Vvet!;fUpJT&Jiz{MIH>&n0wnu? z{t=Z<0T1Z@f9Nyi|GUm9{}2CC`M(zo&;Fn5tK9G};DKYX-I5cz_Q9-wg5i{~I8JKB$;pqx}E%8EWA4$JM}> z;U(<GdFB5t8as@D@lkQtGztpFkq{DVnJ!<~^fTN{>{vXhEMcH>*QdBfmR{^y^aRji-rDbq=BZw+qXw*GwfYf#vK)#(H9e8IQ z+_PeYe%$}|uHp)bI4R(^Z$X``#xqxx8v9>WYHWZyyCA<`ld?G<09cLBdeoU?P-^Vy zrPNmEkrzC&z@ydI3{hbvD;#^nX{K⪙fDzx(tyJ-#H!$+>~y*Byn=UD?BoLM%n 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 DhH7rF diff --git a/Websites/SharePrices/SharePrices/App_Code/DataAccessLayer.vb b/Websites/SharePrices/SharePrices/App_Code/DataAccessLayer.vb index fb2a1d7..6394bb4 100644 --- a/Websites/SharePrices/SharePrices/App_Code/DataAccessLayer.vb +++ b/Websites/SharePrices/SharePrices/App_Code/DataAccessLayer.vb @@ -180,14 +180,25 @@ Public Class DataAccessLayer ' DeleteHolding = DataReaderToJSONString(c.ExecuteReader()) ' DisposeSQLCommand(c) 'End Function - Public Shared Function SoldHolding(HoldingID As Integer, SoldDate As DateTime) As String + Public Shared Function SoldHolding(HoldingID As Integer, SoldDate As DateTime, SoldCurrency As String, SoldProceeds As Double) As String Dim c As SqlCommand = GetSQLCommand("usp_SoldHolding") c.Parameters.AddWithValue("HoldingID", HoldingID) c.Parameters.AddWithValue("SoldDate", SoldDate) + c.Parameters.AddWithValue("SoldCurrency", SoldCurrency) + c.Parameters.AddWithValue("SoldProceeds", SoldProceeds) SoldHolding = DataReaderToJSONString(c.ExecuteReader()) DisposeSQLCommand(c) End Function + Public Shared Function SetAccountCashValue(AccountName As String, Currency As String, Value As Double) As String + Dim c As SqlCommand = GetSQLCommand("usp_SetAccountCashValue") + c.Parameters.AddWithValue("AccountName", AccountName) + c.Parameters.AddWithValue("Currency", Currency) + c.Parameters.AddWithValue("Value", Value) + SetAccountCashValue = DataReaderToJSONString(c.ExecuteReader()) + DisposeSQLCommand(c) + End Function + Public Shared Function SwapInstrumentDisplayOrders(Symbol1 As String, Symbol2 As String) As String Dim c As SqlCommand = GetSQLCommand("usp_SwapDisplayOrder") c.Parameters.AddWithValue("Symbol1", Symbol1) @@ -196,6 +207,19 @@ Public Class DataAccessLayer DisposeSQLCommand(c) End Function + Public Shared Function SetTotalHoldingsValues(TotalValue As Double) As String + Dim c As SqlCommand = GetSQLCommand("usp_SetTotalHoldingsValue") + c.Parameters.AddWithValue("TotalValueGBP", TotalValue) + SetTotalHoldingsValues = DataReaderToJSONString(c.ExecuteReader()) + DisposeSQLCommand(c) + End Function + + Public Shared Function GetTotalHoldingsHistory() As String + Dim c As SqlCommand = GetSQLCommand("usp_GetTotalHoldingsHistory") + GetTotalHoldingsHistory = DataReaderToJSONString(c.ExecuteReader()) + DisposeSQLCommand(c) + End Function + Private Shared Function GetSQLConnection() As SqlConnection Dim c As New SqlConnection("Server=OZHOST1\SQL2008;Database=SharePrices;Trusted_Connection=True;Application Name=Share Prices Web;") c.Open() diff --git a/Websites/SharePrices/SharePrices/CreateDBSchema.sql b/Websites/SharePrices/SharePrices/CreateDBSchema.sql index 7ebfc46..bb0e965 100644 --- a/Websites/SharePrices/SharePrices/CreateDBSchema.sql +++ b/Websites/SharePrices/SharePrices/CreateDBSchema.sql @@ -5,6 +5,8 @@ GO DROP VIEW vErroneousPrices_Intraday DROP VIEW vErroneousPrices_Daily DROP VIEW vHolding +DROP FUNCTION dbo.fn_GetExchangeRate +DROP FUNCTION dbo.fn_GetPriceAtDate DROP PROCEDURE usp_SwapDisplayOrder DROP PROCEDURE usp_GetHoldingsHistory --DROP PROCEDURE usp_DeleteHolding @@ -25,6 +27,7 @@ DROP TABLE Account DROP TABLE InstrumentHistory_Daily DROP TABLE InstrumentHistory_Intraday DROP TABLE Instrument +DROP TABLE TotalHoldingsHistory_Daily --DROP TABLE Exchange */ GO @@ -67,6 +70,7 @@ CREATE TABLE Instrument ( CurrentPrice real NULL, InstrumentType VARCHAR(15) NULL, ShowInMarquee CHAR(1) NULL, -- A = Always, O = Only when open, NULL = Never + WatchlistID tinyint NULL, --Not a real ID yet TradeDayStart datetime NULL, TradeDayEnd datetime NULL, LastUpdated datetime NULL, @@ -139,15 +143,31 @@ CREATE TABLE Holding ( AccountID tinyint NOT NULL, InstrumentID smallint NOT NULL, --NoUnits int NOT NULL, - NoUnits real NOT NULL, + --NoUnits real NOT NULL, + NoUnits numeric(36, 12) NOT NULL, --PurchasePricePerUnit money NOT NULL, - PurchasePricePerUnit real NOT NULL, - ActualExchangeRate real NULL, + --PurchasePricePerUnit real NOT NULL, + PurchasePricePerUnit numeric(36, 12) NOT NULL, + --ActualExchangeRate real NULL, + ActualExchangeRate numeric(36, 12) NULL, PurchaseDate datetime NOT NULL, SoldDate datetime NULL, + SoldCurrencyID smallint NULL, + SoldProceeds numeric(36, 12) NULL, CONSTRAINT PK_Holding PRIMARY KEY CLUSTERED (HoldingID), CONSTRAINT FK_Holding_Account FOREIGN KEY (AccountID) REFERENCES Account (AccountID), - CONSTRAINT FK_Holding_Instrument FOREIGN KEY (InstrumentID) REFERENCES Instrument (InstrumentID) + CONSTRAINT FK_Holding_Instrument FOREIGN KEY (InstrumentID) REFERENCES Instrument (InstrumentID), + CONSTRAINT FK_Holding_SoldCurrencyInstrument FOREIGN KEY (SoldCurrencyID) REFERENCES Instrument (InstrumentID) +) +GO + +CREATE TABLE TotalHoldingsHistory_Daily ( + HistoryDate date NOT NULL, + [Open] int NOT NULL, + Low int NOT NULL, + High int NOT NULL, + [Close] int NOT NULL, + CONSTRAINT PK_TotalHoldingsHistory_Daily PRIMARY KEY CLUSTERED (HistoryDate) ) GO @@ -227,6 +247,47 @@ BEGIN END GO +CREATE FUNCTION dbo.fn_GetPriceAtDate(@InstrumentID INT, @DT DATETIME) +RETURNS REAL +AS +BEGIN + DECLARE @Rate REAL + + IF @InstrumentID IS NULL OR @DT IS NULL + BEGIN + RETURN 0.0 + END + + --Is there a rate for this exact datetime? + SELECT @Rate = ClosePrice FROM InstrumentHistory_Intraday WHERE InstrumentID = @InstrumentID AND HistoryDT = @DT + IF @Rate IS NULL + BEGIN + --No exect match + DECLARE @StartDT DATETIME, @EndDT DATETIME, @StartRate REAL, @EndRate REAL + --@StartID INT, @EndID INT, + SELECT TOP 1 @StartDT = HistoryDT, @StartRate = ClosePrice FROM InstrumentHistory_Intraday WHERE InstrumentID = @InstrumentID AND HistoryDT < @DT ORDER BY HistoryDT DESC + SELECT TOP 1 @EndDT = HistoryDT, @EndRate = OpenPrice FROM InstrumentHistory_Intraday WHERE InstrumentID = @InstrumentID AND HistoryDT > @DT ORDER BY HistoryDT + IF @StartDT IS NOT NULL AND @EndDT IS NOT NULL + BEGIN + --Work out how far between the 2 dates our DT is, and calculate rate accordingly + DECLARE @TotalSeconds BIGINT + DECLARE @Percent REAL + SELECT @TotalSeconds = DATEDIFF(second, @StartDT, @EndDT) + SET @Percent = CONVERT(REAL, DATEDIFF(second, @StartDT, @DT)) / @TotalSeconds * 100 + SET @Rate = @StartRate + ((@EndRate - @StartRate) / 100 * @Percent) + END + ELSE + BEGIN + --We don't have BOTH a start AND end price + --Return the non-NULL rate if we have one, zero otherwise + SET @Rate = COALESCE(@StartRate, @EndRate, 0) + END + END + + RETURN @Rate +END +GO + --CREATE PROCEDURE usp_InsertInstrument (@ExchangeShortName varchar(10), @Symbol varchar(7), @FullName varchar(100)) CREATE PROCEDURE usp_InsertInstrument (@Symbol varchar(8), @FullName varchar(100)) AS @@ -350,29 +411,50 @@ BEGIN SET NOCOUNT ON SELECT - i.DisplayOrder, - --e.ShortName as [Exchange], - i.FullName as [InstrumentName], - ISNULL(i.DisplayName, LEFT(i.FullName, 30)) as [DisplayName], - i.Symbol as [Symbol], - i.PostPandemicDilution as [PostPandemicDilution], - i.GMTOffset as [GMTOffset], - i.Currency as [Currency], - i.CurrentPrice as [CurrentPrice], - i.InstrumentType as [InstrumentType], - i.ShowInMarquee as [ShowInMarquee], - i.TradeDayStart as [SingleDayStartDate], - i.TradeDayEnd as [SingleDayEndDate], - ISNULL((SELECT MIN(dd.HistoryDT) FROM InstrumentHistory_Daily dd WHERE dd.InstrumentID = i.InstrumentID), CONVERT(DATETIME, '2030-12-31')) as [MinDailyDate], - ISNULL((SELECT MAX(dd.HistoryDT) FROM InstrumentHistory_Daily dd WHERE dd.InstrumentID = i.InstrumentID), CONVERT(DATETIME, '1970-01-01')) as [MaxDailyDate], - ISNULL((SELECT MIN(id.HistoryDT) FROM InstrumentHistory_Intraday id WHERE id.InstrumentID = i.InstrumentID), CONVERT(DATETIME, '2030-12-31')) as [MinIntradayDate], - ISNULL((SELECT MAX(id.HistoryDT) FROM InstrumentHistory_Intraday id WHERE id.InstrumentID = i.InstrumentID), CONVERT(DATETIME, '1970-01-01')) as [MaxIntradayDate] + DisplayOrder, + [InstrumentName], + [DisplayName], + [Symbol], + [PostPandemicDilution], + [GMTOffset], + [Currency], + [CurrentPrice], + [InstrumentType], + [ShowInMarquee], + [WatchlistID], + [SingleDayStartDate], + [SingleDayEndDate], + [MinDailyDate], + [MaxDailyDate], + [MinIntradayDate], + [MaxIntradayDate], + [LastSoldDate], + dbo.fn_GetPriceAtDate(dt.InstrumentID, LastSoldDate) as [LastSoldPrice] FROM - Instrument i - /*INNER JOIN Exchange e - ON e.ExchangeID = i.ExchangeID*/ + (SELECT + i.InstrumentID, + i.DisplayOrder, + i.FullName as [InstrumentName], + ISNULL(i.DisplayName, LEFT(i.FullName, 30)) as [DisplayName], + i.Symbol as [Symbol], + i.PostPandemicDilution as [PostPandemicDilution], + i.GMTOffset as [GMTOffset], + i.Currency as [Currency], + i.CurrentPrice as [CurrentPrice], + i.InstrumentType as [InstrumentType], + i.ShowInMarquee as [ShowInMarquee], + i.WatchlistID as [WatchlistID], + i.TradeDayStart as [SingleDayStartDate], + i.TradeDayEnd as [SingleDayEndDate], + ISNULL((SELECT MIN(dd.HistoryDT) FROM InstrumentHistory_Daily dd WHERE dd.InstrumentID = i.InstrumentID), CONVERT(DATETIME, '2030-12-31')) as [MinDailyDate], + ISNULL((SELECT MAX(dd.HistoryDT) FROM InstrumentHistory_Daily dd WHERE dd.InstrumentID = i.InstrumentID), CONVERT(DATETIME, '1970-01-01')) as [MaxDailyDate], + ISNULL((SELECT MIN(id.HistoryDT) FROM InstrumentHistory_Intraday id WHERE id.InstrumentID = i.InstrumentID), CONVERT(DATETIME, '2030-12-31')) as [MinIntradayDate], + ISNULL((SELECT MAX(id.HistoryDT) FROM InstrumentHistory_Intraday id WHERE id.InstrumentID = i.InstrumentID), CONVERT(DATETIME, '1970-01-01')) as [MaxIntradayDate], + (SELECT MAX(h.SoldDate) FROM Holding h WHERE h.InstrumentID = i.InstrumentID AND h.SoldDate IS NOT NULL) as [LastSoldDate] + FROM + Instrument i) as dt ORDER BY - i.DisplayOrder + DisplayOrder END GO GRANT EXECUTE ON usp_GetInstruments TO WebApp_Role @@ -406,7 +488,7 @@ GO CREATE PROCEDURE usp_GetIntradayData (@Symbol varchar(8), @StartDate datetime, @EndDate datetime) AS BEGIN - DECLARE @MAX_DAYS INT = 90 + DECLARE @MAX_DAYS INT = 30 IF DATEDIFF(dd, @StartDate, @EndDate) > @MAX_DAYS BEGIN @@ -761,16 +843,84 @@ GO GRANT EXECUTE ON usp_DeleteHolding TO WebApp_Role GO */ -CREATE PROCEDURE usp_SoldHolding (@HoldingID int, @SoldDate datetime) +CREATE PROCEDURE usp_SoldHolding (@HoldingID int, @SoldDate datetime, @SoldCurrency varchar(8), @SoldProceeds numeric(36, 12)) AS BEGIN - UPDATE Holding SET SoldDate = @SoldDate WHERE HoldingID = @HoldingID + UPDATE + Holding + SET + SoldDate = @SoldDate, + SoldCurrencyID = (SELECT InstrumentID FROM Instrument WHERE Symbol = @SoldCurrency), + SoldProceeds = @SoldProceeds + WHERE + HoldingID = @HoldingID + SELECT @@ROWCOUNT AS [RecordsUpdated] END GO GRANT EXECUTE ON usp_SoldHolding TO WebApp_Role GO +CREATE PROCEDURE usp_SetAccountCashValue (@AccountName varchar(20), @Currency varchar(8), @Value numeric(36, 12)) +AS +BEGIN + DECLARE @AccountID int + DECLARE @CurrencyID int + + SELECT @AccountID = AccountID FROM Account WHERE ShortName = @AccountName + SELECT @CurrencyID = InstrumentID FROM Instrument WHERE Symbol = @Currency + + + IF EXISTS (SELECT NULL FROM Holding WHERE AccountID = @AccountID AND InstrumentID = @CurrencyID) + BEGIN + UPDATE + Holding + SET + NoUnits = @Value + WHERE + AccountID = @AccountID + AND InstrumentID = @CurrencyID + END + ELSE + BEGIN + INSERT Holding ( + AccountID, + InstrumentID, + NoUnits, + PurchasePricePerUnit, + PurchaseDate) + VALUES ( + @AccountID, + @CurrencyID, + @Value, + 1.0, + '2020-01-01') + END + + SELECT + h.HoldingID, + a.ShortName as [AccountName], + i.Symbol as [Symbol], + h.PurchaseDate, + h.NoUnits, + h.PurchasePricePerUnit, + ISNULL(h.ActualExchangeRate, dbo.fn_GetExchangeRate(i.Currency, h.PurchaseDate)) as [PurchaseExchangeRate], + h.NoUnits * h.PurchasePricePerUnit / ISNULL(h.ActualExchangeRate, dbo.fn_GetExchangeRate(i.Currency, h.PurchaseDate)) as [BookCostGBP], + h.SoldDate + FROM + Holding h + INNER JOIN Instrument i + ON h.InstrumentID = i.InstrumentID + INNER JOIN Account a + ON a.AccountID = h.AccountID + WHERE + a.AccountID = @AccountID + AND h.InstrumentID = @CurrencyID +END +GO +GRANT EXECUTE ON usp_SetAccountCashValue TO WebApp_Role +GO + CREATE PROCEDURE usp_SwapDisplayOrder (@Symbol1 varchar(8), @Symbol2 varchar(8)) AS BEGIN @@ -800,10 +950,82 @@ GO GRANT EXECUTE ON usp_SwapDisplayOrder TO WebApp_Role GO +CREATE PROCEDURE usp_SetTotalHoldingsValue (@TotalValueGBP money) +AS +BEGIN + DECLARE @Rounded INT = CONVERT(int, FLOOR(@TotalValueGBP)) + DECLARE @EndOfPreviousWeek DATE = DATEADD(day, 1 - DATEPART(weekday, CURRENT_TIMESTAMP), convert(date, CURRENT_TIMESTAMP)) + DECLARE @PreviousDay DATE = DATEADD(day, -1, CONVERT(DATE, CURRENT_TIMESTAMP)) + + IF DATENAME(WEEKDAY, CURRENT_TIMESTAMP) NOT IN ('Saturday', 'Sunday') + BEGIN + IF EXISTS (SELECT NULL FROM TotalHoldingsHistory_Daily WHERE HistoryDate = CONVERT(date, CURRENT_TIMESTAMP)) + BEGIN + UPDATE + TotalHoldingsHistory_Daily + SET + Low = CASE WHEN @Rounded < Low THEN @Rounded ELSE Low END, + High = CASE WHEN @Rounded > High THEN @Rounded ELSE High END, + [Close] = @Rounded + WHERE + HistoryDate = CONVERT(date, CURRENT_TIMESTAMP) + END + ELSE + BEGIN + INSERT TotalHoldingsHistory_Daily (HistoryDate, [Open], Low, High, [Close]) VALUES (CONVERT(date, CURRENT_TIMESTAMP), @Rounded, @Rounded, @Rounded, @Rounded) + END + END + + SELECT + pw.HistoryDate as [PreviousWeekDate], + pw.[Close] as [PreviousWeekClose], + pd.HistoryDate as [PreviousDay], + pd.[Close] as [PreviousClose] + FROM + (SELECT TOP 1 + * + FROM + TotalHoldingsHistory_Daily + WHERE + HistoryDate <= @EndOfPreviousWeek + ORDER BY + HistoryDate DESC) as [pw], + (SELECT TOP 1 + * + FROM + TotalHoldingsHistory_Daily + WHERE + HistoryDate <= @PreviousDay + ORDER BY + HistoryDate DESC) as [pd] +END +GO +GRANT EXECUTE ON usp_SetTotalHoldingsValue TO WebApp_Role +GO + +CREATE PROCEDURE usp_GetTotalHoldingsHistory +AS +BEGIN + SELECT + h.HistoryDate, + h.[Open], + h.[High], + h.[Low], + h.[Close] + FROM + TotalHoldingsHistory_Daily h + ORDER BY + HistoryDate +END +GO +GRANT EXECUTE ON usp_GetTotalHoldingsHistory TO WebApp_Role +GO + CREATE VIEW vHolding AS SELECT h.HoldingID, + i.InstrumentID, a.ShortName as [AccountName], i.Symbol, i.FullName as [InstrumentName], diff --git a/Websites/SharePrices/SharePrices/SharePrices.aspx b/Websites/SharePrices/SharePrices/SharePrices.aspx index 03bf482..5639bd9 100644 --- a/Websites/SharePrices/SharePrices/SharePrices.aspx +++ b/Websites/SharePrices/SharePrices/SharePrices.aspx @@ -26,24 +26,28 @@ - - + + + +