From 7bb9f8b7a2d56620e5747308dee3bf81b1655cde Mon Sep 17 00:00:00 2001 From: ryaningham2001 <ryaningham2001@gmail.com> Date: Wed, 26 Apr 2023 13:50:59 +0100 Subject: [PATCH 1/2] clubs testing --- .../__pycache__/views.cpython-310.pyc | Bin 5739 -> 5739 bytes ...reservation_reservee_email.cpython-310.pyc | Bin 702 -> 702 bytes cinema/__pycache__/forms.cpython-310.pyc | Bin 2017 -> 2036 bytes cinema/__pycache__/models.cpython-310.pyc | Bin 2482 -> 2537 bytes cinema/__pycache__/urls.cpython-310.pyc | Bin 1544 -> 1292 bytes cinema/__pycache__/views.cpython-310.pyc | Bin 8077 -> 6881 bytes cinema/forms.py | 2 +- .../0014_showing_social_distancing_seat.py | 42 ++++++++++++++ ...015_remove_showing_adult_price_and_more.py | 24 ++++++++ cinema/migrations/0016_delete_seat.py | 15 +++++ .../0017_showing_covid_capacity_and_more.py | 22 ++++++++ ...ing_social_distancing_seat.cpython-310.pyc | Bin 0 -> 1122 bytes ...owing_adult_price_and_more.cpython-310.pyc | Bin 0 -> 665 bytes .../0016_delete_seat.cpython-310.pyc | Bin 0 -> 546 bytes ...ng_covid_capacity_and_more.cpython-310.pyc | Bin 0 -> 704 bytes cinema/models.py | 29 ++++++---- cinema/templates/cinema/create_showing.html | 36 +++++++++--- cinema/urls.py | 6 +- cinema/views.py | 26 ++++----- clubs/__pycache__/forms.cpython-310.pyc | Bin 1024 -> 1366 bytes clubs/__pycache__/models.cpython-310.pyc | Bin 1493 -> 1878 bytes clubs/__pycache__/urls.cpython-310.pyc | Bin 892 -> 1070 bytes clubs/__pycache__/views.cpython-310.pyc | Bin 4300 -> 5346 bytes clubs/forms.py | 8 ++- clubs/migrations/0005_clubdiscountrequest.py | 39 +++++++++++++ .../0004_club_active.cpython-310.pyc | Bin 624 -> 624 bytes .../0005_clubdiscountrequest.cpython-310.pyc | Bin 0 -> 1076 bytes clubs/models.py | 9 ++- .../clubs/create_club_discount_request.html | 32 +++++++++++ clubs/templates/clubs/manage_clubs.html | 52 ++++++++++++++++++ clubs/templates/clubs/view_club.html | 4 +- clubs/urls.py | 2 + clubs/views.py | 40 +++++++++++++- db.sqlite3 | Bin 294912 -> 307200 bytes 34 files changed, 342 insertions(+), 46 deletions(-) create mode 100644 cinema/migrations/0014_showing_social_distancing_seat.py create mode 100644 cinema/migrations/0015_remove_showing_adult_price_and_more.py create mode 100644 cinema/migrations/0016_delete_seat.py create mode 100644 cinema/migrations/0017_showing_covid_capacity_and_more.py create mode 100644 cinema/migrations/__pycache__/0014_showing_social_distancing_seat.cpython-310.pyc create mode 100644 cinema/migrations/__pycache__/0015_remove_showing_adult_price_and_more.cpython-310.pyc create mode 100644 cinema/migrations/__pycache__/0016_delete_seat.cpython-310.pyc create mode 100644 cinema/migrations/__pycache__/0017_showing_covid_capacity_and_more.cpython-310.pyc create mode 100644 clubs/migrations/0005_clubdiscountrequest.py create mode 100644 clubs/migrations/__pycache__/0005_clubdiscountrequest.cpython-310.pyc create mode 100644 clubs/templates/clubs/create_club_discount_request.html diff --git a/authentication/__pycache__/views.cpython-310.pyc b/authentication/__pycache__/views.cpython-310.pyc index f236c9cbf1ab05725680fa05a6f8ac6a38ca06b8..34318c765611a97a08acacfa4586f8779c429f59 100644 GIT binary patch delta 20 acmaE@^IC^HpO=@50SI=xx^Co75CZ@`{RKn- delta 20 acmaE@^IC^HpO=@50SLYybK1zAAO-+Jm<9d- diff --git a/booking/migrations/__pycache__/0009_reservation_reservee_email.cpython-310.pyc b/booking/migrations/__pycache__/0009_reservation_reservee_email.cpython-310.pyc index 646f501bd36c7652d36c2db022d3b27f6b8ab137..fc411cedeb1b3753c123dd2205bd2a53c1a77a1e 100644 GIT binary patch delta 77 zcmdnTx{sABpO=@50SI=xPUJev7&Y<6XEre)w@7UAMaIKg5GI%pBE*5jEe@O9{FKt1 RR69l>ub2f$2r!8;0|4An5N!Ye delta 77 zcmdnTx{sABpO=@50SF>pCUTu+yfyL0XEt#lw@7^QMaIKg5GI%pA|!ysEe@O9{FKt1 RR69l>ub2f$2r!8;0|4QH5Rd=> diff --git a/cinema/__pycache__/forms.cpython-310.pyc b/cinema/__pycache__/forms.cpython-310.pyc index 9f056839d5f98345deb6d4731bd4b99fa217262c..a07ccac6397582074123b52976121a5fefa43541 100644 GIT binary patch delta 134 zcmaFJ|An77pO=@50SF9ZT~pR><lVxe&2o#aIJqb_HSZQnT4qk}Ew18{#G;b;lFZ!H zTY|;;$(e~c@hO==!Mx<jjBH|?-?LOO@@oK%kO1N$B@m%8xt~>K@+`L1{5n9cEL>b? WatOOW8%S-D&g2iw;*$@sD*^!YrX}tG delta 118 zcmeyu|B#<IpO=@50SKgzI;G6m$h(C_n)w!6adJ^=YThlDw9K5`TU^B@iA5#xC7HRY zo8Pl^GxDngl}i9|krIedpDfKHGkG5?$K<tatNFEoLb7l<?aArv{%j!iMcR`;FpE#V H%&rIk1+*XI diff --git a/cinema/__pycache__/models.cpython-310.pyc b/cinema/__pycache__/models.cpython-310.pyc index 07d3d3f592af395575eaa9b001770f710307303a..45f294de5d601ee73a6ed7e5f0304cc5651e83ef 100644 GIT binary patch delta 448 zcmYk0%}T>S5XZA^J~lO}AFb6MR1_-4Y7srC1wjM_FJ5{wmu1avbtO%7H!6DZBJ|{G zd;nj-gPz3)3BG{%5^j2OVSfBzX8$uEwVzrw_5F&W-!4C7J@>u(YoZtUDz~9!b@neO zna!MM6i)H-<v7D5ul@5nb6Mrd2&aceAF(m!J>jr1G)yC$=^23!Lu=VT3Xq)D8zj<z zYdZ|`ipr?WNG1k6$10Qkk(qrF4`fqM1*P0nJnqA<J%`r8br#^wI<Cl-B4)LS!S=i* z+l8&!%ZnRYHgzdeV*)kMgV(!A??iImQS_Dvv+#+VFj2PQ*cnHwaO$*B2OgcJ$J{$e z)0orbNbs12lPZk_jR_O_!X(lGVKb&GBZ||EBsYUIE(ujioF|-x)hN9cj70Q`Mk2eH z>w3E^ZpnQ@BK=QAJdO#GwW2Y?R$=u5EsX^z;fCj#9`X<_)h*eA*K!?p@b^qtxA$}@ WtbvVUVhYJFwA~Zbg$H*V&Hn-XXmB<F delta 344 zcmXv|Jx>Bb5Z!^}Zh<?(mk?tRV}y91ghY&?)Q-l6ZX1H^9b9sN**!F|CSpI0CH@5L zwbTFL#Xn&D3l=VZ%;de7mp7T2kKAJ}HMOh+QML7Q#-EH;>QjR|e2&(!5^J=UnFqqM zPV`4}f0|zq7r4%iIb|E1^7x#v!h&do6}!YvAjYbAt9P<tLI!;i^a5|}gqrL5V|>%M z^-z<J@8XwUEgz`6H3g|DN<#r|%<gD<?M;Ra*}rn|HO6+tzRE%>1L3Y030qmQsmP9q zLnYYJOVGffUdB_S2{sC&0yVrhc8^6y<t*9fGe78E3UA;rO9nIUO#W?hF!Fr<n~C)| zqJ<VMK@;nA&!n(!Gm_Rs1((r0PU(BGt)`9?BvnL-2_|GgwDBT-4sBe;PayvdmFZWt diff --git a/cinema/__pycache__/urls.cpython-310.pyc b/cinema/__pycache__/urls.cpython-310.pyc index a0e6f8884d8395daf01e5e80264dcbe5083522ff..cb1bb59c035a7d8df631f3a819d26c83585ed705 100644 GIT binary patch delta 89 zcmeC+>EY7J=jG*M0D?*Jt||Xm85kaeILJT{$Z-JT;ztY<b?$Jb^F|4!C<HTTDsHx6 cY+z#c(-fW@&2o8i9BUn;(&W3W%1j)e0nm36qyPW_ delta 343 zcmeC->fq7I=jG*M00QZwPAR`x85kaeILJT*$Z-JTVjjkcI(JM`8B-KenX`ma6jRuH znSnedAWt|&8Ol=u@<dWpLA-Q<DA5$PU<OU~%|eU~O!ZZ=xrup+>8bH0naSCyCB^#5 zMX8A;Fs^<SFABd(4NY}QYECLbwM}MTiB&<i9Z(yJ1ctWKf)t1)3Ls1Mk@Uf3KoWkM rVw0ybUp9#1gSsvr;u-`WVhw^1(LOnYrH)Z!@^cnt4n9T@<oEypFhgrq diff --git a/cinema/__pycache__/views.cpython-310.pyc b/cinema/__pycache__/views.cpython-310.pyc index 706454da84acfeb084dee88010649f1ae6117cf4..b7860e030af1e2ec29a61efd031accdfc58ccb5a 100644 GIT binary patch delta 2081 zcma)7O>7%Q6yEXAdSb7C8Ygb-_-E}Vq1&`cfx48R7AgpYv^9dD9(pmZchhe0Png{l zs5bZziCYQLAaMbyNK}vmCm*;%&m53I0`|rQDMI4Jg#(E9W>edBjD)TI{5<pK{mu8@ z-g)-da;zPVh9&rXZY=44sk^Z(xxYJqmlSrtD+W`mlBRaUWZzFT{%2sBO!4!<#gZ0q zL(F(<)39uohNJ8#fE%i}Tek6zy(cl1e-PXurEXs4q%<WqtvWM|mgQ3GX8Uckb;AOE zvt=}E7EALVLf6Wu#(V&p%<?D;%a5RR96>`UAgDbk^6T^@S?KQ2l7H?PF3%uj5Rw2| zK!nDGZDAnIe~Qd?(2S<A1nT(_6oh$%lL*rYG6Gs*S%e(I=pcn<Q3Kga^H7{{){T05 z)jH#ja)O-hexc|jG7vRS#pV-e#&ffXQkuUSD_8!1JdcS(2;#V~cBp7S#?Fv3e=e2f zv+<?Legw04?oosV-igl?#5D|ARB>BCk>8IWC+GO@@f`Vse??F6vxy`z_)4POsX2l5 zxE|8!9kL}m@_NF0#R;w-apdZ_Bj1gGCK1UddU%_xO1Q3%O-rzs1WkAj>)47O*(Pu% zv@LA~oPZ;(PdGlu?+{)2B)Ao_Cml(TI-zYp5H?m}SBG*Ew}=JVBd*WXUt|*??<3h* z3gEV4wr<rLrmn8FS#vMgCyg6iGaF5d2^yyPm*Z+NH9(svTIkazf`6y^{&-$H0ir7# zjJ287=Z|~DYS+zLqpF*hU28!D+~B$7v5Fh3w{MwxwO-q()lK`|0iMx;X1IX%MJVE4 zF(H?%9U>clFFAE)0X8W~5K6+nFh0HvASDWsVGX`P<!|vzs81&2u+Emd-y|I}GgLdl z2T{Ps(LL6So#$^%KHV8k9CtzpLVHxx93<1Dlp8vj25cy`VakG4H+G;~-Q3V?w(%*? zq-Mzq&^VVn3;UW}VWUD%0hK5DPAd4q6Q~vN>e&l{y^Im7Jt%_IccmK*!#2Lg-6s() z@t;#4%@4T|>0(_T8aJK?{_#=mnrL5&=l`=Z!Qrq*b}pE3BgjY?A_mmpTmDZrBPa0k zE{lG?I`vYgADx(k;{HT*vd3I8!~7Uc06}ngWNF+0x*D#H=ie*L_h7)n*%=m0Q-EL8 zPgsQ)()T(~!MaA+6?8I(vfq=%G{@n7JMFyz7DYx6-U|yi?Pf#s^>wxIK%g<ShQxDa zIAueFox&9{$$P`uja{_uE6lvUX&Xz}f?8;xydt1p5TbirVhpDleJH43_=lN-`5L&Y z6MzRFl<|2U9t*3fORF$rD#94#E(WLy>z;MNEyXtLZyL5$ZNLop4G-cR3J~@>>a7B3 z1-_Agzf;2h*v9NMLK)#4!ZN}N!X<>u2o(g3&oiT<)Cb|1KGSULn+@XvMr`5cgp?&& Zyg5HD(Fv;3G##UPnhA$#ochO<=)XNWgD?O9 delta 2699 zcma)8OKcle6rJZ8&rIy`CyA5P#;rebLZ%5xXd6mt)$l8A(~l^j1w}%U@k~+&f6AK) zg=)eGg>6+uuNzPottu8_frPSzicJM9kl3-9A^~EBSd|3}7KnS_IJV<B61IHi&imZo zJNG{SHgj_}T8~6R0(}1Y_C@2t=teY6yp8d@WMt!q-2RM_{a9GY7&#*k&#W<Q6yTXN z2ImER^vl2g5XmO{Svo_KY$Q09-;_Lsn(wZfmQ7Qjk?sTVlv2HBoA2A30?o7cg11Ov zOO_ddJ)bIBl44&e3o}Vv9RSc}nnjs!*HJo%FpiKz$Twk_&8ZV)dh5EH7e_~Mcog9Y zgnj^B;`S-m%@w5BH{nqi)#w_H<2n&RLwE{d5+RKsBcK+#AK?H(cPF`K9;j@UsA<-A z`3ZZyh(EVjqRh|^l0#d!G=qfOyk`GK#^b2QH}f<~DRwM6bMgQCbA)d~;M=*jT}k^o zdW0NhkE6wbmh~rb&tZgVwj3*DvM6?FYft>=v9Zi^u%<)+wm&Ken6{VTXFX((W6zUU z*`fH%mGh3Y5;GJ-y-C(&C%6)K<i%b`z8kwI5Wyx!&pMeGY|RL*6L?qFg*C~M9ATx; z2{@udjPRY{nqv1mf}uIex(L*Z6kWpJ3S`sP)%x{vZ8^I{>(y+rmMxY__3E`^?E@HO zixHiD7&;~UYuNW8x-HIz7jhlZ^RvdZZ4xg~HeR6#ru8O=nkV7~m&%o@ML8!^>_l%i zmuTZq1a`J@D2%UZw$^)KZ~{b6HYu%Bt3@XEuy@#PW0Xp>xP{Yx7A0<nTSuonvecDU z(MAG*S7y;RU07-r08}kbR1yk=@E1q{sziek{td{a58fy_z4cL_Lkb<4;5^{zm_bJd z5l*sP;<($Y5kEehQ4sj*ZiUhat4SqKX*f(fg6yOzX!V-GtzI)Axclr;VuYM!WMKck zXJKBKFVare*)s!~myhA3<R`RgnVvyM+eo~_f?-xn+kAjajw8&mPX=y}cWCEPVmfwo z7T*GUb5LL4m5ODscS3@lZgnkEP~nA<Z;f;Pjy)R8kaJMAX*M);+HE<;yWL?l$sLn@ zO7c#{dz*w)oSa>=;z?+wGcCSpKPNwd0t-82h#;jjAd)H)dV&2q^x1(EFs>7N9*vBl zEc!C<*(r8^U(V%o_^yX&%b6(dKstFcIAB9{OyLOc$;~$FMPIOOT7G-gHcw&s=t^7i zntJ`3LH>Be?2IH5<ymZy&iaL2N@k=>u$Fy6Qsg`<$TKc<8rdOEz>w~UYoe_{p9wl5 z?=!m?1_5&SuueV2E|=ahZR<v=RIZuT;#9R*D=wRhjp50wcD16beozw_9zT&7O07yt zzJc%j>T6Jz_kh=Mv|CYV4eg7SvSt4Xt1QeV*0o>p(EwETJPh#&E6|3A*`tAeH{b;B z2JgWg2~WAvc!Rw0iqLRj7Sf<Vvz2)gR7ir-NP@bn%=$sS7u^{x9fH9d$wnspcGSoO zCgO5M?`dn7yi)LA$DWl!GdSB>uiL@<`u~QqNXb#`WtXunxVzgzt3F-_eR{CX2hK)* z8eL0cLH3R9>4RS%GF*Xv&$uE$2Q1-9Zh!E+@txm@V=NXcxWte!>3Xm|soY8KU!dh5 zP%R64+pgiglHs?<7&u~K^YNLWiWHfplZ$%ZiyJG&+H!r;V!tOH7cU4pjc^FzC<5N* z^fba*ggJzB2p15rVmPVjWt6TUaNf3D;?gioc<PC2-B_)dC&3}X!vACmAx+ZAPf^XQ Y3HD=3=`E<KP)LobJ*uXL)wtI4A2y@<x&QzG diff --git a/cinema/forms.py b/cinema/forms.py index 2a8a7440..9dc071c0 100644 --- a/cinema/forms.py +++ b/cinema/forms.py @@ -19,7 +19,7 @@ class ShowingForm(forms.ModelForm): film = forms.ModelChoiceField(queryset=Film.objects.all()) class Meta: model = Showing - fields = ['screen', 'film', 'start_time'] + fields = ['screen', 'film', 'start_time', 'social_distancing'] class FilmForm(forms.ModelForm): class Meta: diff --git a/cinema/migrations/0014_showing_social_distancing_seat.py b/cinema/migrations/0014_showing_social_distancing_seat.py new file mode 100644 index 00000000..68f7250c --- /dev/null +++ b/cinema/migrations/0014_showing_social_distancing_seat.py @@ -0,0 +1,42 @@ +# Generated by Django 4.1.5 on 2023-04-23 16:33 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("cinema", "0013_remove_cinema_ticket_price_showing_adult_price_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="showing", + name="social_distancing", + field=models.BooleanField(default=False), + ), + migrations.CreateModel( + name="Seat", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("seat_number", models.CharField(max_length=10)), + ("is_available", models.BooleanField(default=True)), + ( + "showing", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="seats", + to="cinema.showing", + ), + ), + ], + ), + ] diff --git a/cinema/migrations/0015_remove_showing_adult_price_and_more.py b/cinema/migrations/0015_remove_showing_adult_price_and_more.py new file mode 100644 index 00000000..aa130764 --- /dev/null +++ b/cinema/migrations/0015_remove_showing_adult_price_and_more.py @@ -0,0 +1,24 @@ +# Generated by Django 4.1.5 on 2023-04-23 16:42 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("cinema", "0014_showing_social_distancing_seat"), + ] + + operations = [ + migrations.RemoveField( + model_name="showing", + name="adult_price", + ), + migrations.RemoveField( + model_name="showing", + name="child_price", + ), + migrations.RemoveField( + model_name="showing", + name="student_price", + ), + ] diff --git a/cinema/migrations/0016_delete_seat.py b/cinema/migrations/0016_delete_seat.py new file mode 100644 index 00000000..ca98efba --- /dev/null +++ b/cinema/migrations/0016_delete_seat.py @@ -0,0 +1,15 @@ +# Generated by Django 4.1.5 on 2023-04-23 17:02 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("cinema", "0015_remove_showing_adult_price_and_more"), + ] + + operations = [ + migrations.DeleteModel( + name="Seat", + ), + ] diff --git a/cinema/migrations/0017_showing_covid_capacity_and_more.py b/cinema/migrations/0017_showing_covid_capacity_and_more.py new file mode 100644 index 00000000..319043ba --- /dev/null +++ b/cinema/migrations/0017_showing_covid_capacity_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 4.1.5 on 2023-04-23 17:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("cinema", "0016_delete_seat"), + ] + + operations = [ + migrations.AddField( + model_name="showing", + name="covid_capacity", + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name="showing", + name="last_seat_number_assigned", + field=models.IntegerField(default=0), + ), + ] diff --git a/cinema/migrations/__pycache__/0014_showing_social_distancing_seat.cpython-310.pyc b/cinema/migrations/__pycache__/0014_showing_social_distancing_seat.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8cd47da895070d2a80be8d41683ea9041654c3e9 GIT binary patch literal 1122 zcmZWo!H(ND5S1uemSwNA+ol0}%dIfbH4>!gAy^dI+Pg(iB!_N;poR*9_KdZ3Bx*y- zn>dFYl3x8G`I7ttuRZ0SQ_yTXly;K<rN9B-8*(`FG^}=Z(tyU>Kab$YP7wU<!Iy&* zxJT2D$v^;M5tQL9EZK~O9<w5v@m~Unfd3T$$8gno9nCtxPJ&VA9i0hA%%!EujjUCr zt&7VFu&@so-uLAg5V%Lvz9NIcEQDajAk4#AgnUI2A;Ngo1rD8U2=Ugl33MSLwg>*> zkV1dUmkb8PrLY6TZAj=^bFSyl5n_b;I9Tnh;?;0<4R&D<zS>4hmUH-e%W^i`h3l04 zH?H^KDs8GEUMP*FbO*O?-M%9Xmeo0mmJ_vFJi%I=8MQ!RPpfB2=R(4|xZ<P+QC0?B z_tNY3Y_(9b5TI-=HO0w~N1^KiE+risMWmV6NoZN3<Bjbs6&B$53Ch|r1;0CXe>&oB zAlG#z7KUg9*QYE>X*S{sZd}izp<C1obc1s=^U7iyv2SU&(Cc!J=AG{Vx;!oAb5Wqq z>r*#SR>*Uy3OO&(b^LDoV%U~DzN~?g>{VJ&mRM7KgN09^jnC?8#7v(8ySPc)J{;}2 zL^NI@Tq;Np5(sHM5aQ`t7QRN00MAeZk|t;k^AVCmfMZ{~i98(qTvY{1-B7MSX$pVf z)gqV54@r&I)tj73(=O9vQeWlzR}v+LmDG9V7|dPLWKWIhx|73`$>H?KrPUc;HtU<f zd`~wv=EKYB-R!rG)Hm<z{8X0Nv|6l7)V0kXX+`2%Rd2FCP@0=}vgy&uG@CrWovokY z{<2Wd_ZL+;rv`$o)iC?~A~I^IA3k->|Jp)$?Z;;u<6mNzrad5&1dQ>2d5488Ohf*$ zSw);s`|*F+#jrOFX&3oD$3L<Q_MTrPADT#`*!5Z+#xQSWZpHof6FF`l>i9|_^PQK% cXYpB-cC}BOOAgu}`cp{A#$<L`65fdZ1IAub8UO$Q literal 0 HcmV?d00001 diff --git a/cinema/migrations/__pycache__/0015_remove_showing_adult_price_and_more.cpython-310.pyc b/cinema/migrations/__pycache__/0015_remove_showing_adult_price_and_more.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b4ef3948a3b3ff94aeb00b7670e792056921fe81 GIT binary patch literal 665 zcmY*X!EV$r5Vf7`Zkp{L;J|qWryN?f0xlIomDm;`K@Y7EBC=$;nIY>{;w*8}cF*O? zhww|ja^eR-;s8vt3tdL?cxL=&#`ElIGKm?<cXa}<1!G@3XInyYj%m4vq<{f0Sjkh) z*-Hijf=>(r<O^{dqyoYVmJGfTjwRg3rO9jEn991W3vJ7goMT$<h!nDv1EX}F^EAM4 zG3W|I_*rc1!InMj>^w+^FrsFW-+A-5OCtO*GZssoJ~}u!e4^aEx;8dfuF8xq6d2cN zO9+afZv1F-?#CM1qEXA*WJpEgvH~oW)g}6{*W+w%3RnaD#5FCT-QdrXk&jdlR?5dp zQF2=#*}F=8Y<1BU=sdtBTFT1|x|(=qeteE)b%mz}3-EEZ#0^<rSbdMqd-d~nb|lYN z+D>2De6CA5tFpGF?oPh7<_c?Pnw5Nyx}H9kvy+RNeDUs3w%54#p)falSyf&VBOuqj z$h#Mj#L!b!_c!=Q)D{m)TcBBL++VKhfUeWMn46M{m=NLba3Hwg;jb|Ke~*6j=(8m7 lJFw6;ulC`xpSO?SO}4h~Q$Zg+Ta)&jcRjlQwksY4e*p32xqkov literal 0 HcmV?d00001 diff --git a/cinema/migrations/__pycache__/0016_delete_seat.cpython-310.pyc b/cinema/migrations/__pycache__/0016_delete_seat.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d59927f4e06ccd415e07d4d32ab49f863cd49a4d GIT binary patch literal 546 zcmYjP%}yIJ5VpOWG^C;2dX6};2N0+#hpMWOScEvhp;1*evSgX{ba7bQ!QKEl!<7f& z+_&+yCtjhKFixmoq#4cs%r~}MU+)v7Kk7&wQbPVF<1OWA93Y2H6pAR?5JSh5l4GKn z%I=BEfKJ$5HfAaxk)rd2d8DARZ*=WttDOy1a=oPtjRWK`L;++>6~S^^({Tp*q>~yy zB&)k>8P`t#_bOQIR@#D*acg&X@3Zh=+%<@B;cm38g;cYq6;rP(5Yj4PoQIf?K(@G2 zZl!^<;$7?skyIgKUtkK>Bz+*n)l4=ok%59KSOvDy5In<0<NFdCXyMc;Xky<@;RW9# z@gFe06#p*EFZ}yl+Tn?<FQnn6t7Zml8~6{aufYf1&iOBpe)x%(N28J-{@mlU8`%Ec z=-chenRA4v_zEO{Jt9ZA`vNE91|lG!o$1`CLw1ovn%^Ug<%_(-Xujwzma(%Ui)(5k iZS8i{`4Yv_|GMu=+raYJ`?@;CH~a@Aq=z4{kJ&TeACeCM literal 0 HcmV?d00001 diff --git a/cinema/migrations/__pycache__/0017_showing_covid_capacity_and_more.cpython-310.pyc b/cinema/migrations/__pycache__/0017_showing_covid_capacity_and_more.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ea8161304b0dbed77ae287b11e365b816599ad1 GIT binary patch literal 704 zcmY*X!D<vi5bf@n-JM+$$;E)+AtzxE2?>INh(_HgIhcb%#9^T6ovNMmGSjnm&m`{2 zgI@C?euBT!S5N*zK(u-`VUvO?s;X<M>b;tJb92N<e&G?k6pZ~2!EK2tI3#tC$N&Rg zvWlm?5~<+q9RmT;4+atPdGtL>BZyDgxc7%@*;x2dr3<SXT^r~7RSj6WJUrc&0R@Mo z?ll=?DF>Dc-~~@3jOV>D0Q>U+#L&Cs(7(LN4(?_PktUGP@Sz{RznMxa^mA>nQhsZH z|KN$F4X{D!P&Izw&gu(o3V$!J&o#(gEmW?XrRB89nEL_XOtob*jtEECT^d!Pk2~9& zX)M7%D3xovcG9%f6s=Uw>B1nK&?1TKK9SOoq@)&YiR5oc`K485XcHp91sXt;Yjl<_ zz<lxw;B9DcqY!Q!n+6NCUCNK@1zuD7liB-J(3z`mlV{n7r7}CmrZ`hoHmUQrLeseH zqtWMR9U;p;qp~}Xv&qrvBzyDeAZsshcUJ1JyLnwri6_WbY-Q`aWyIT4c}<nP%al|G z2$#jZ#nOf!rBCV}l1Z2l@xQnyxZoom|6O~@Rabd3j{Okk$`th;Ogr2i+U{`;YvpZI TN1r@jG58{!$AxKIVmtZ|@K?fi literal 0 HcmV?d00001 diff --git a/cinema/models.py b/cinema/models.py index 1a24cdfa..0afa544e 100644 --- a/cinema/models.py +++ b/cinema/models.py @@ -1,7 +1,4 @@ from django.db import models - -from authentication.models import User - # Create your models here. class Cinema(models.Model): @@ -26,7 +23,7 @@ class Screen(models.Model): cinema = models.ForeignKey(Cinema, on_delete=models.CASCADE, related_name='screens') screen_number = models.PositiveSmallIntegerField() seating_capacity = models.PositiveIntegerField() - + class Showing(models.Model): id = models.AutoField(primary_key=True) @@ -35,19 +32,29 @@ class Showing(models.Model): start_time = models.DateTimeField() end_time = models.DateTimeField(null=True) available_seats = models.IntegerField() - adult_price = models.FloatField() - student_price = models.FloatField() - child_price = models.FloatField() + # adult_price = models.FloatField() + # student_price = models.FloatField() + # child_price = models.FloatField() + social_distancing = models.BooleanField(default=False) + last_seat_number_assigned = models.IntegerField(default=0) + covid_capacity = models.IntegerField(default=0) - def save(self, *args, **kwargs): - self.end_time = self.start_time + self.film.length - super().save(*args, **kwargs) - def __str__(self): out = self.start_time.strftime("%d %B %Y %I:%M%p") out = out + " - " + self.film.title return out + def save(self, *args, **kwargs): + self.end_time = self.start_time + self.film.length + super().save(*args, **kwargs) + + +# class Seat(models.Model): +# row = models.CharField(max_length=1) +# number = models.IntegerField() +# screen = models.ForeignKey(Screen, on_delete=models.CASCADE, related_name='seats') + + class Ticket(models.Model): productID = models.AutoField(primary_key=True) name = models.CharField(max_length=255) diff --git a/cinema/templates/cinema/create_showing.html b/cinema/templates/cinema/create_showing.html index 5100af40..f5fa82da 100644 --- a/cinema/templates/cinema/create_showing.html +++ b/cinema/templates/cinema/create_showing.html @@ -1,6 +1,4 @@ -{% extends 'base.html' %} - -{% block content %} +{% extends 'base.html' %} {% block content %} <div class="container mt-4"> <h1>Create Showing</h1> @@ -10,7 +8,7 @@ <label for="film">Film</label> <select class="form-control" id="film" name="film"> {% for film in films %} - <option value="{{ film.id }}">{{ film.title }}</option> + <option value="{{ film.id }}">{{ film.title }}</option> {% endfor %} </select> </div> @@ -18,19 +16,39 @@ <label for="screen">Screen</label> <select class="form-control" id="screen" name="screen" required> {% for screen in screens %} - <option value="{{ screen.id }}">{{ screen.cinema.name }} - Screen {{ screen.screen_number }}</option> + <option value="{{ screen.id }}"> + {{ screen.cinema.name }} - Screen {{ screen.screen_number }} + </option> {% endfor %} </select> </div> <div class="form-group"> <label for="start_time">Start Time</label> - <input type="datetime-local" class="form-control" id="start_time" name="start_time" required> + <input + type="datetime-local" + class="form-control" + id="start_time" + name="start_time" + required + /> + </div> + <div class="form-group form-check"> + <input + type="checkbox" + class="form-check-input" + id="social_distancing" + name="social_distancing" + /> + <label class="form-check-label" for="social_distancing" + >Social Distancing</label + > </div> <div class="form-group"> <button type="submit" class="btn btn-primary mr-2">Create Showing</button> - <a href="{% url 'create_film' %}" class="btn btn-secondary">Create Film</a> + <a href="{% url 'create_film' %}" class="btn btn-secondary" + >Create Film</a + > </div> - </form> </div> -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/cinema/urls.py b/cinema/urls.py index df0ccf74..24a557f4 100644 --- a/cinema/urls.py +++ b/cinema/urls.py @@ -17,7 +17,7 @@ urlpatterns = [ path('delete_film/<int:pk>', views.film_delete, name='delete_film'), path('showings/<int:pk>', views.film_showings, name='film_showings'), path('manage_tickets/', views.tickets_list, name='manage_tickets'), - path('manage_tickets/create_ticket/', views.tickets_create, name='create_ticket'), - path('manage_tickets/delete_ticket/<int:pk>/', views.tickets_delete, name='delete_ticket'), - path('manage_tickets/update_ticket/<int:pk>/', views.tickets_update, name='update_ticket'), + #path('manage_tickets/create_ticket/', views.tickets_create, name='create_ticket'), + #path('manage_tickets/delete_ticket/<int:pk>/', views.tickets_delete, name='delete_ticket'), + #path('manage_tickets/update_ticket/<int:pk>/', views.tickets_update, name='update_ticket'), ] diff --git a/cinema/views.py b/cinema/views.py index 6226adb7..dd5a08e6 100644 --- a/cinema/views.py +++ b/cinema/views.py @@ -125,17 +125,6 @@ def screen_delete(request, pk): return redirect('screen_list') def showing_create(request): - """ - Handle a user creating a showing from an accompanying screen - - Returns: - If the request method is "POST" and the form is not valid: - The showing form, with the error message passed in as context. - If the request method is not "POST": - The showing form form. - Otherwise: - A redirect to the screen management page. - """ perms = get_user_permissions(request) if perms == '0' or perms == '1': return redirect('no_access') @@ -151,8 +140,13 @@ def showing_create(request): print(form.errors) if form.is_valid(): f = form.save(commit=False) - f.available_seats = screen.seating_capacity - f.save() + if not f.social_distancing: + f.available_seats = screen.seating_capacity + f.save() + else: + f.covid_capacity = screen.seating_capacity / 2 + f.available_seats = f.covid_capacity + f.save() return redirect('manage_screens') else: print('invalid form') @@ -230,4 +224,8 @@ def film_showings(request, pk): return render(request, 'cinema/film_showings.html', context) except AttributeError as e: context = {'film': film, 'showings': showings} - return render(request, 'cinema/film_showings.html', context) \ No newline at end of file + return render(request, 'cinema/film_showings.html', context) + + +def tickets_list(request): + pass \ No newline at end of file diff --git a/clubs/__pycache__/forms.cpython-310.pyc b/clubs/__pycache__/forms.cpython-310.pyc index b207d66296a9ad351af0494115d457dfd1c8f660..b7295f18adbaf3e04a175cef0ee13642ffcc1ccd 100644 GIT binary patch literal 1366 zcma)6OHbQC5Z?7GP9Q1`6xu>1)LRZ9RlQYJg+yr8100}LRm+mK$xeciA7R&S8m{!0 z^u}M>YfqfH_0$=Ml$2Ll$)9#+$Ft+_n{nQ3HW;p@;f@?zjQt{Gb~$Kl;iCft$s|u$ z$^*`sw4|L_sU6s<6F8|GxSV}p(vj{DCSBl1-l-kb(BsJ(dTN&*A3eUTqo;o9smsOz zYtNlye%9v3?dK}h=bS9tINM3tH7&w@7%I?^6{3j0fmtM9C)T~Z%!++DE<qPP$}zia zG`8@$c#Z%p;F1LvR=}l&6<DWMU`rcscZ^Tz-s9Cbav&>{98YI*fE_pk%=426uCy?N zebSs}*xZFew0+}bA_ddbg#sv|tW3M0j5jfj(~FC-@rOB9ol7ta1tc&$%rlrqHq*Qt zCs!t<B2FS9C9<IR+Me;Fh;E1?(}<!pmn8;AW<H9JOOZ@Y6v<~?JcPt}{TLFd&zM?4 zZw0?Ub>4*gW09?Y%m#-d4Lf<SOp#+9e$J3(rLoHJD+smzI_&Hmbi(Z~uflQ!8~r5y zzR}CmZk&M(dq|!RE9EwaW8)A5E?#osA^6PU^ISc{?cSNAT6Fm$!4d(vuL_#%h-u{` zQ27@GK5OyHb3>k~#Hxm2DC9E9@Nci&E32y0d-lod?e9&*bc|ckZyNnrX%v%`ttVo- z^@l?1QLZHFa{U8|2la$tncy$?GoMNv%+VpW>4Ye?dROoZJfN9XYXoHdmy;FxwrjI; zFDd$ZuhYZ~EbR4aT29vPNLaCD9%nF$<mG5aN)%u`1w!Z9E%Z=_Jb<1B3VR4WFEQ{D z1y}TtwbyPKPacVEkSiKy<5lyZtKm?UJXD0K@6wnMFIA^i)GA7Fn`Xv;I~lom^rzA! O$UIx(Evw}%yMF+%t1w6a delta 400 zcmcb{)xg1*&&$ij00cUL(kZ7IC-TWKx=hrTb!234XGmd5VQpbZVNGSsVr^!QVgrh> zrLY4<*r6iqDICEJnw&2|`ZXDEv8Lr0<rcqW1o4<A&X=0Jkx6pnbACoPF`!71*yKNq z`OXqRrr%1IB0-Rl5Qq>45g_3rh%z`!9K>P=5-dRc8ANa}2r(A1PhQ6)%g8qQ43jw{ z$7B}ffO<5uSV8(kK!hlWz-B7QI&P4pB!~dJsYnW!Vi}+WD2R%rK?I2Br^#`PEhQ^4 zFFn7AiDB|577>?QoWA)fsX1=I5CFRwtPY#qw>WHa^HWN5Qtd$DRLlV+co+m2g_y+H E0A|EQ1^@s6 diff --git a/clubs/__pycache__/models.cpython-310.pyc b/clubs/__pycache__/models.cpython-310.pyc index b7971be96c1398ec2541aa42dcdbe280a018e2f5..bf979b55c25984da3a67eb2eee01cc21a8c57d28 100644 GIT binary patch delta 448 zcmYk1yGjE=6oz;9lD%flZoDCa1R=15)K-EL6S0XB1Hv?6%^4xfl1*keTBgv#CPml> zuudtyiJ(O~AH&WwiGnlC$AA7gGylwo{pq?%v1my+M!X4;K6m#?G_T$4o=aeY^(2AC zNMt-J)CT)n3Y^#H3xzE5ccn@eZ{Nx(nfAr$|3ky#1XtQdFo_b7sLYf|Wg4;o1mu}Q zb<_qZpw0+2|7i=g4H^{CcTg8WU-h_PV7|F5H{!|d*&yvFlVR3j<LQK@8TH`T>2Wp| zP8!JE#C$G3$BDq9KuMs2Xtje4?up75C=18}n*s-jrGC}9>^2)+s`fE+X|>`c%vu8$ z1ND*^daKMMd`6Fl8Kd5iJ*>Syi|>eQ3Y>*$GUPQ;7~yEdlY0jFm%3G{qb2OrK^T%x goYgE5E_T|1lOJn$q@KTMRo_L&k=6~q>YLkpKew@E!2kdN delta 80 zcmcb{ca@tjpO=@50SHW7TvK@1Ci2NJMoiQWXG`G>X3*r?ILninQFHPWW;I65&D<=G fjLd$T+>^JnrA=01R}$a>YU5$xVFW=T7BNl$xA6|; diff --git a/clubs/__pycache__/urls.cpython-310.pyc b/clubs/__pycache__/urls.cpython-310.pyc index 15705d14ef32476705636715dfb5d569e8df041d..d43dadb87610beefc1456d98d8b824f130268854 100644 GIT binary patch delta 289 zcmeyvwvIzPpO=@50SJ2XT~h>E7#JRdILLqx$Z-JT;vEyUr>mthrii67XYr+or?B@j z19=ia9)F4?h?mY4C6FQ&%%CZ~@k}#geU(~bK|xV|S!#T8PH9qnN@j6#eraAwd{Js) zX=-tazD;IciB&<i-7Q(X>Z+7eQu8VanIVOthzD+ypQhmCAf|~5MchDd6!8FwTim5Z mIR%L&C8<Su#VZ+#1VIvllYcU$Gs;X(WR_&(W8`Dx_yz!OD_Ic$ delta 110 zcmZ3-@rO-2pO=@50SGu<TvMc&85kaeILLqp$Z-JT;yDwwr*oxqMDeAF1v6-hZ+y|r x$n2-dKlvNeM6p}krA0Xfi6teeMR~<58H)IU8jAQQFK13?l$gxVBFV(@0|0$$7_$HX diff --git a/clubs/__pycache__/views.cpython-310.pyc b/clubs/__pycache__/views.cpython-310.pyc index 24c660515263ca7c1ce68dc054876e9fdf6e3a9f..bda26fe5d5d0aaef32874010a0c7408ee35a5b8f 100644 GIT binary patch delta 2625 zcmaJ@OK%%h6rMY8+hfN~oWybBB+jGlG_-1=4_f-7NlQ^tB-*G#BdBG3r>)J{PVY?I zv~pyjbW5e`N`NSfWC2o^RTnI};18e*7HnpN#1CN8Eg;Uh<HjK|%*fw;%-lKWeCOq# z3cuT_Mlu<f;M%-*nP&4(Qe))LCv$GQ*6;Kai5fKK4b(DDrZ(sd)`pxR*pq178?I%Y zY;D9D5$lAPb8@hs@J5|cYSH8)$r*FwG)4O!N$bSP(=^=&d*ig94!}4;GjtHfNjgM_ zVJy%r9f5I*=IAJl(=<Ou^DvpA<8%VXSvpAzFz%;`8<IW6E%KNs{3*!|hXeE8%BKqz zzuZ`<2iM(uE3O~d3jcvj4Ti%#p7CGFp_Bmz<8K~*e!!FR{K=|Hb!vP;*3>|+DjUY8 zw5GMBs@alTN=s|0Ekez2^))?+wImvA>FWw;66Z~MB1uBCw7kq3O_$m_|584f-bXtM z6`9b8zmTU%oc|^lK1zW|HUJPRCC_6cxRe2GBQ&Cy1D40l9Dvhb2J8Id?FK7GB1#?` z!>6MFp;2zs19vsplGrp~RI1s2*fmL-m?R~qNQ%TsMz#o>eg0CB2|2`nQTMmU@uYIc z4I<eVF0F-z>n}Ef%c~VXU<zz872yzq&`xIsoWFq})Dw>m<8lgNdK+e77RH(t_kIzT zM{WH{08`F_UNUcLIdYUg(LQX?!R`{91>7>24g*7F7%Iq)APfV9s$XilLZ>Ztw-Q4B zF44(SIjA&Cfh)uxg-^V~00&Bl4hooroq%OomiSlNkj;+4!d4d<Dsx3B!`_4`JC3m9 z(|kkEBu?SxNrY4UM|~@u!Ra8v5W*Z^H40fY$W}uYoK|B(!-zHh%sAup;d^fbgl5Gr zHcMWGvbS)rH_PJqIegxW<pdI3Tv?`I?FD|>ERc)*j`^Uyr7yDGs^K?;W*w@#P8Ou2 zJ42&X7HJgf)b-rJwfA^k=p$Tz2|u`lA3PuFLubU{o3P`f7EwT2M3;eo8E*8!!t?dm zC^3+UCH4;gE`FTYJd8h12xCQ7<hh@io;?q5ux-}Z1zaLwVGQ^au6Efq{vt7PKm@j4 zW-hS7V)$MX;XMRQxG0)0abk@Zx@i}WVoJockS$ES$}d`{3;)e|B;_{$#yUZk_|Mj> zyS?~E>mFL2te#wMKyIBzMXmsV)i_0$u&V&J%+A0N8kKq_sFXZgV_hn`wCDL;>TFwh z0GSE3Wmc&NERCN*ae|=GDtm6J?$RPeMv2+@qUF0mak=FC_Zy5x^avVtm$3%(g$_Ha zk=ZlVgxqsd7UZA}dxDbxoyw8V`AFa4wgb=01mN|B1qG9Q9)5lmAdp(n9M%X_R`Qw5 ztbkB?o!o%ks!SEwu>%F>D!e1N<PB|8Vh3AtRi`S|piV0-WkcVThy>?!JXco&WnEg6 z0|P2_+h~!N3?*9@g*w(r2$819(-lE~s8#CJU42-H{3$9%aaZjQj@%7u9=K;aL~Jvv zRw9K&eC~rUcIn6XY<DucQ?j<tI)fr-cgxtFNn`(~(AUTy_y95s?>O8hvBX^dOV|1d z`&a^jP~y6m22=EaVE-on!#deks?gS|dQl)YJR$+5W`|M@DP`}%5j(cST+tRp4-+x@ zK0Ifl6ksqh{5k~gzgtC^-eWDEy|&xte5Z-__QLmY#P9YuC?_4mp_tr)c9My2n|Bt> zJJ#M%_gbR$v_xpVr?-5922F3n49vnDb?Xm$>-P-x!&2HQcUDyAim+oJ;2-q8Y%`=S z)UYl1QAHD3i?QSMbt<oaq}G7i>oc@8s#=S9%ES^MRBCQiFtDqMHpWCpx`@jKge3$_ zJqQ7STL`EE7;;_UYY^s`XF=ME=bpzr^|9q<Bn$pNSmMr*jQA@7F{a8%h_M0FFimsV LOq-*CDJ$_0HhCH$ delta 1740 zcmZ`(&2Jk;6yI5UKWwi*YCCr9B#qsYqzff!NeXHjT0v+8msE)Kz*5OtJX7Sd{^0F8 zK;_Cv?X4108F2#y$D9$T{sjos8<!O)Zb+!A)GG(x8%IsCQm_1*_hxqIz4v<`f4RRm zbNy^Kt>LeD^(wzveUO`He?E9cjG4wQo(hWHl2_`My)x<=PX{yIidX4Yy{ghP!K^on z`<bBT)wsj6_cX6A(mcoW_q4mro8tw30{7;5k(Y2?;AK98>q%bWRa_VOEU)3(;B`KS zYm;X_(A@dIHBGLu`%IS)SzUK^`42lKSM=qaiGI?58~-7fAL-jWKbk*jcakIRmNn8x ziBWRIxb>ZJ$B68a#_f@DH-R^%c4KxfX6NHnuix_9Z4rihE{jdS9d-7_j%$3AI3q75 z8Z0GmB$~S?@cKC62LV)20v*9MV++J*LlH($qs=OUS8NBvkHgl@KD7M70Q&oW0JC@y zTkU=?5?@3I8Z62`61OS^+_hPO*(|5$Seg}ehe1<5vCHz)<YTrhJ!3gjr%w}~hzKh3 zzR`SV8TCW!ut4$|0%cwuxul*XSbPQzl;YHWM||EQ=jP-S!)0e>-F$z%f=7GML_Dy7 zXat9VtisC#GYD}q^!EiMP&`OZTU7?9Y-JURek7E=HT>==)e{EFObpj%a30mRuE~a3 zc^6(q#ZB%4IkTgjfmIaY9KqDpc`p8U`Rnw~YXs|xxf|BEg(9gXf-=F1WOj3wVsw*n z5);z}<@AI(xoK~DIeKpcA+|eV3sctNKyJT)Y4!O<IzNu-43XR#4mc8USw6CxYztlc za>F%uVcIpiLwR<{K5-050+okl`F*OoIhAK+T_yWXdU1-NiFGal5sB;aacY5G`PoU& zF^j_6gE!=AW`ixscINAhia?cfP5zrXJ>I12o>2jpNF^5H6p}LO3)mq&ffXN{;P-gH zi#>pArxyXGSXEAJwn1R<kfNO|!P^AXLvZA{fog1pL)Cj&UGfJf-8|~9^rX^MX)8}v z+}rY3=VJ54v`;Jxc{+Q6U6UVXpN@~CoVd8{95!!b(8qW#kaKS#AV(xpR)B_zs{<8T zY;}5_sN)B&0Y}6g<%0aY-B8WHHpzVp!~lf+Ew{9$f+l)nV*tce9%WT<isjg82g2_O z-ol#kVM#9Lt7FByDFFHqDo381Jod3&sH`a8D2`)mb4K|TieBW?m^-Y}ukiKoC4|X1 za&(iW<uCcVc^&uMQ*yiXXdD~VIpL%}$bB!5Q?ozpMd50<kM$M;4YWy;-$N<3sR5!+ zS4_A(OQ+QLuuiZ=aE0I+0a<#klvPnTa4)vE@b+P_E-o`vLu%Tx=HS?L)Kfr-Mkqc> R-AOaMWLvgvSM7o`_aE`6Xh#45 diff --git a/clubs/forms.py b/clubs/forms.py index ff9fe52c..c5854f73 100644 --- a/clubs/forms.py +++ b/clubs/forms.py @@ -1,5 +1,5 @@ from django import forms -from .models import Club, ClubRepresentative +from .models import Club, ClubRepresentative, ClubDiscountRequest class ClubForm(forms.ModelForm): class Meta: @@ -11,4 +11,8 @@ class ClubRepresentativeForm(forms.ModelForm): class Meta: model = ClubRepresentative fields = ['email', 'first_name', 'last_name', 'password'] - \ No newline at end of file + +class ClubDiscountRequestForm(forms.ModelForm): + class Meta: + model = ClubDiscountRequest + fields = ['new_discount_rate', 'reason'] \ No newline at end of file diff --git a/clubs/migrations/0005_clubdiscountrequest.py b/clubs/migrations/0005_clubdiscountrequest.py new file mode 100644 index 00000000..d1974a32 --- /dev/null +++ b/clubs/migrations/0005_clubdiscountrequest.py @@ -0,0 +1,39 @@ +# Generated by Django 4.1.5 on 2023-04-23 17:48 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("clubs", "0004_club_active"), + ] + + operations = [ + migrations.CreateModel( + name="ClubDiscountRequest", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("old_discount_rate", models.FloatField(default=0)), + ("new_discount_rate", models.FloatField(default=0)), + ("reason", models.CharField(max_length=255)), + ("approved", models.BooleanField(default=False)), + ( + "club", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="discount_requests", + to="clubs.club", + ), + ), + ], + ), + ] diff --git a/clubs/migrations/__pycache__/0004_club_active.cpython-310.pyc b/clubs/migrations/__pycache__/0004_club_active.cpython-310.pyc index 8cc2f874f4f8b20e48c0923247044b34f491080d..870ff9209a08de00eb512aeab41f4daffee52971 100644 GIT binary patch delta 77 zcmeys@_~gbpO=@50SI=xPUJey7&Y<I9yVbhw@7&M6vj<j5GI%pB1C}1Ee@O9{FKt1 RR69l>ub2f$2r!8;0|44H5G()y delta 77 zcmeys@_~gbpO=@50SF>pCUPBTyfyLC9ySpmw@7626vj<j5GI%pB1D12Ee@O9{FKt1 RR69l>ub2f$2r!8;0|4J+5KjOA diff --git a/clubs/migrations/__pycache__/0005_clubdiscountrequest.cpython-310.pyc b/clubs/migrations/__pycache__/0005_clubdiscountrequest.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..62195a06fd88c9a58b3b81750475509a7e2ccd2c GIT binary patch literal 1076 zcmY*YOK;Oa5VqHj<G4xN@TkO%6H)|3MLZ4&As}fHLOfK85RoNolbNIr_HNj<3+WXO zT>3-!OMB(Sl?xJrmRXxp*wv2ao1LAV`F2)zI*~(TS8l;~-*LWJ@b4g-bB~tplK=<Y z%*ox6o3jyfEoPZF@*g_jf&b9~AKiK5gEwjbd*SpNU+Ij~V<yVenc_t%g*HJh0W<w{ zV)y<X9Rl}g=}#ok8M)w$7`QWc<e@*Oh~Qx`Z-P&=0Rc1*{V9WxY$3EDI&=xG{D<0v zTF`;jYHy8DL?>&{bwVrHo_FTKe09DCT{r`054|ay1#s?=(XH!no@&@IttThRQzeZ_ zR*tn<-`w21kyt(9lOo+mb9O*rnCgivMX`f#OVov7DeP_=_GsAiO`Dg6OeP9>fnZh^ zD$TiCCU0<QS{hZ#v-AK>dmq(UYD@&r(R5`73H%9~5QC^(BB$q?Cg7BpSz)>Y-~I1m z0=h#>@%6ZNjdK1z$xzISJrnZ9Ldktfz_-bp?rHEkWqlA;751&{d8Q>rLeGT-rKT{m zx!0+&LJ}Q*m1ZzaF$4Xy*EL~MZ6}F|l7wEm%#ieUlDsW>W}PhpT%Z6HlN7aLl%-i2 zRJ=T~t)V<?X+KD3_ldD>8`?zMndC*Sw+4G$)oS~Jlo@hy;v^NOGx3-x4Peg2Od1Ab z6IKOK^O@%JooBmSgIyEJ1^#Ks&yKoG7gpkj8s3g~mRwwXBxZX&kB4$n<|qmszZCS! zN~gs#evMpRydDp?UJT>Gt7~!j4zEtL^!?R|%*Uxfh${-?)25H9U2azGa>BQ&>FzI< z%Koq>Eq#kb=rHCV`wiwY&v!{y)BnkiR$HsCowV;pwe=S}V&D9u@VJW63rwr7x)0-u s)|$x+e~tb6>-A6gP?v1s_Wn}}YV8WyOn9e$z`M5RbU<RAh3<y;8wR98eE<Le literal 0 HcmV?d00001 diff --git a/clubs/models.py b/clubs/models.py index 19f13776..4df7ec2a 100644 --- a/clubs/models.py +++ b/clubs/models.py @@ -38,4 +38,11 @@ class Club(models.Model): null=True, blank=True ) - active = models.BooleanField(default=False) \ No newline at end of file + active = models.BooleanField(default=False) + +class ClubDiscountRequest(models.Model): + club = models.ForeignKey(Club, on_delete=models.PROTECT, related_name='discount_requests') + old_discount_rate = models.FloatField(default=0) + new_discount_rate = models.FloatField(default=0) + reason = models.CharField(max_length=255) + approved = models.BooleanField(default=False) \ No newline at end of file diff --git a/clubs/templates/clubs/create_club_discount_request.html b/clubs/templates/clubs/create_club_discount_request.html new file mode 100644 index 00000000..097e6041 --- /dev/null +++ b/clubs/templates/clubs/create_club_discount_request.html @@ -0,0 +1,32 @@ +{% extends 'base.html' %} {% block content %} +<div class="container"> + <div class="row"> + <div class="col-md-8 offset-md-2"> + <h1>Create Club Discount Request</h1> + <form method="post"> + {% csrf_token %} + <div class="form-group"> + <label for="{{ form.new_discount_rate.id_for_label }}" + >New Discount Rate:</label + > + {{ form.new_discount_rate }} {% if form.new_discount_rate.errors %} + <div class="invalid-feedback"> + {% for error in form.new_discount_rate.errors %} {{ error }} {% + endfor %} + </div> + {% endif %} + </div> + <div class="form-group"> + <label for="{{ form.reason.id_for_label }}">Reason:</label> + {{ form.reason }} {% if form.reason.errors %} + <div class="invalid-feedback"> + {% for error in form.reason.errors %} {{ error }} {% endfor %} + </div> + {% endif %} + </div> + <button type="submit" class="btn btn-primary">Submit</button> + </form> + </div> + </div> +</div> +{% endblock %} diff --git a/clubs/templates/clubs/manage_clubs.html b/clubs/templates/clubs/manage_clubs.html index f6a5726a..00680f72 100644 --- a/clubs/templates/clubs/manage_clubs.html +++ b/clubs/templates/clubs/manage_clubs.html @@ -137,6 +137,58 @@ {% endif %} </tbody> </table> + <h2>Club Discount Requests</h2> + <table class="table table-striped mt-3"> + <thead> + <tr> + <th>Club Name</th> + <th>Old Rate</th> + <th>Requested Rate</th> + <th>Reason</th> + <th>Action</th> + </tr> + </thead> + <tbody> + {% if discount_requests %} {% for request in discount_requests %} + <tr> + <td>{{ request.club.name }}</td> + <td>{{ request.old_discount_rate }}</td> + <td>{{ request.new_discount_rate }}</td> + <td>{{ request.reason }}</td> + <td> + <div class="dropdown"> + <button + class="btn btn-secondary dropdown-toggle" + type="button" + id="dropdownMenuButton" + data-toggle="dropdown" + aria-haspopup="true" + aria-expanded="false" + > + Actions + </button> + <div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> + <a + class="dropdown-item" + href="{% url 'approve_club_discount_request' pk=club.pk %}" + >Approve</a + > + <a + class="dropdown-item" + href="{% url 'deny_club_discount_request' pk=club.pk %}" + >Deny</a + > + </div> + </div> + </td> + </tr> + {% endfor %} {% else %} + <tr> + <td colspan="4">No Requests to display.</td> + </tr> + {% endif %} + </tbody> + </table> </div> {% endblock %} diff --git a/clubs/templates/clubs/view_club.html b/clubs/templates/clubs/view_club.html index 14014888..f1db7fb2 100644 --- a/clubs/templates/clubs/view_club.html +++ b/clubs/templates/clubs/view_club.html @@ -4,14 +4,14 @@ <ul class="list-group mt-3"> <li class="list-group-item">Representative: {{ representative.linked_user.first_name }}{{ representative.linked_user.last_name }}</li> <li class="list-group-item"> - Address: {{ club.street_number }} {{ club.street }}, {{ club.city }}, {{ - club.postcode }} + Address: {{ club.street_number }} {{ club.street }}, {{ club.city }}, {{ club.postcode }} </li> <li class="list-group-item"> Telephone Number: {{ club.telephone_number }} </li> <li class="list-group-item">Mobile Number: {{ club.mobile_number }}</li> <li class="list-group-item">Email Address: {{ club.email_address }}</li> + <li class="list-group-item">Discount Rate: {{ club.account.discount_rate }}</li> </ul> <div class="mt-4"> diff --git a/clubs/urls.py b/clubs/urls.py index 1e3fc065..ac52400b 100644 --- a/clubs/urls.py +++ b/clubs/urls.py @@ -12,4 +12,6 @@ urlpatterns = [ path('view_club/<int:pk>/', views.view_club, name='view_club'), path('deactivate_club/<int:pk>/', views.deactivate_club, name='deactivate_club'), path('activate_club/<int:pk>/', views.activate_club, name='activate_club'), + path('approve_club_discount_request/<int:pk>', views.approve_club_discount_request, name='approve_club_discount_request'), + path('deny_club_discount_request/<int:pk>', views.deny_club_discount_request, name='deny_club_discount_request'), ] diff --git a/clubs/views.py b/clubs/views.py index 2f2a91c8..6e7bcbff 100644 --- a/clubs/views.py +++ b/clubs/views.py @@ -4,8 +4,8 @@ from utils.custom_decorators import get_user_permissions, is_in_group from django.contrib.auth.decorators import login_required from django.contrib.auth.hashers import make_password from authentication.models import User -from .models import Club, ClubRepresentative -from .forms import ClubForm, ClubRepresentativeForm +from .models import Club, ClubRepresentative, ClubDiscountRequest +from .forms import ClubForm, ClubRepresentativeForm, ClubDiscountRequestForm from accounts.models import Account, ClubAccount import random import datetime @@ -19,9 +19,10 @@ def clubs_list(request): clubs = Club.objects.filter(active=True) clubs_for_approval = Club.objects.filter(active=False) + discount_requests = ClubDiscountRequest.objects.filter(approved=False) accounts = ClubAccount.objects.all() #representatives = User.objects.all().filter(club_rep=True) - context = {'user': request.user, 'clubs': clubs, 'inactive_clubs': clubs_for_approval,'accounts': accounts, 'perms': perms} + context = {'user': request.user, 'clubs': clubs, 'inactive_clubs': clubs_for_approval,'accounts': accounts, 'discount_requests': discount_requests, 'perms': perms} return render(request, 'clubs/manage_clubs.html', context) @login_required @@ -148,3 +149,36 @@ def representative_update(request, pk): context = {'form': form, 'user': request.user, 'club': club, 'representative': representative, 'perms': perms} return render(request, 'clubs/update_representative.html', context) +def create_club_discount_request(request): + perms = get_user_permissions(request) + if perms == '0': + return redirect('no_access') + if request.method == 'POST': + form = ClubDiscountRequestForm(request.POST) + if form.is_valid(): + club_discount_request = form.save(commit=False) + club_discount_request.save() + return redirect('index') + else: + form = ClubDiscountRequestForm() + return render(request, 'create_club_discount_request.html', {'perms': perms, 'form': form}) + +def approve_club_discount_request(request, pk): + perms = get_user_permissions(request) + if perms == '0' or perms == '1': + return redirect('no_access') + discount_request = get_object_or_404(ClubDiscountRequest, pk=pk) + club = discount_request.club + club.account.discount_rate = discount_request.discount_rate + club.account.save() + discount_request.delete() + return redirect('clubs_list') + +def deny_club_discount_request(request, pk): + perms = get_user_permissions(request) + if perms == '0' or perms == '1': + return redirect('no_access') + + discount_request = get_object_or_404(ClubDiscountRequest, pk=pk) + discount_request.delete() + return redirect('clubs_list') \ No newline at end of file diff --git a/db.sqlite3 b/db.sqlite3 index 3f6553891d5b750de43720ed88ac65deea25bb90..7564f958478eaf02706b30ade863491c242aab84 100644 GIT binary patch delta 6380 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 G*!T~Q8TB~; delta 1740 zcmZ{kduUTv9LLY==H8pfJx$VhV_lo{VY^go(!|%|W7!1P6>ZnKQi{|xO=C?-lbTj* zsjhV*Rhh0c$i;zHSpO^AoPnK9_NFqJQwz4RF*e4SFc9}*mf<MdNz*nCvft(W?(cri z_wYNvbM84KKUhXaEMr9$GzkEx<82FXkhjlYU+YC^^4<0^s&@15ihAx=Z063Unz-Kx zAEd;Bo^-8q5T+lP{faQI%q#oSr5=}3qRfF3sEmV^Jg~udWFQy}#}0M$EqEc-x30!o zhFvfmjYoPy!M+2DfoQzTm`bmkh3%=+?x5XngV+r_yF>A=M6f5?l??Sq6Y;){*E}SE z?WXCJ*z3?K(~4P{NPBvdrc}V`O-~<Nk8rzqDJ714#^*JwOJ5r8lDPa%N*t@@L^GxD zT-xBp?WP+kaXO=!H>PiV_sli@B%puLpXhZunKlP5QgflrBuK!<>x5v(rrOOqc6}Vy zkChpL8z`fO9kNS0D4y5d)LDdCVLO-yZsqIj!zw-KEr@WB_Vf_BK#T@7qkS_(Mk;vp zf?8S%PeuAe9kEDmJ#x_&&3us9wc;cZ+1Y+#L~Ppz^hHsjKz{`E5&e_?LVxCA5uesd zKKWNgHqnAAC6Cwd_4<7tj@>>e`@9~nug2r6@d_A1y)oluL&i&T#*2FPD2Vh<MWFWp z{hQ9w-|2mNj~9NIvU{(g@7+*hQ=g!1y~SiR(7`ESydoaQZZrg^O!3^qN<7$%S=ftY zNTieadA4;uE=AgJZP1}@A0T%%`V_W0T(3CxifUCAJaH^rcy`mXdmoOnm=6(103fTh z+egS*9^o@u`yd(B1AzWfT`qXCS!+y^Qf*=@@)>o#I$kFL$9E<~)^?N-$Og9}1!*I- zsENh5;qx5@3xcex<u5lcElw>ht7V$8DhT(4qmg(xqJ8u$Qj0O>8dv#ZC#VyQz=dt9 zsyet*;|mdB<SLfhQWxH-u_b(sjj?#$i%mU;cQ@}&Hio)4g<DyJiM;o0fliqL^cKBL z6Vy)yWrnByRADpwhzBZy@(|FQ^a2giYULrbTtR1y!!nd4C`vL8`2T9Uf3oC#Yqbm( zp(F%$4qoK;hSil1KKVEdeCy-3-ddFhS}L<p79}ZAw3uggh7D)4=Mq&c50`VWJRdB} z2TSuoXFljyfWr&L=Q5S#k=lwgkQ<-9AP9lhy05t1wmgy5{->x_GT{HX#F=5aQcKaY zP+qFuvNFqtxpEm=?RiF9)f~(zSLB1Xe6TPF4NKXr)+N{`8FJLJL?4IdJg~4J3;Bu| z3@A{Y-O)mtqxuEP9=?r@uw1_%DDWJhA5gQ>WGXYZ;yL+a*($npmvtt1&M;%}^Q&Yp zr2746K;<r}u2}<5+gN=+Ie^&JP1uf*^0Id82pNONwBR5)r9aViRLmUAQF-BD!spn* zB<X@Jq0U3G{$Ou18jh4XlaWx&+0gisv!Qv{uC>mx@PTNo^Zz>g`VVzR;`ztASldRt e2lDFx%&0ye92K<>50fvMe~36BS-J<_#Qy@C%C`;x -- GitLab From 2072ddaab7b32938f580123ce3a68a1f2b9d9032 Mon Sep 17 00:00:00 2001 From: ryaningham2001 <ryaningham2001@gmail.com> Date: Wed, 26 Apr 2023 14:16:09 +0100 Subject: [PATCH 2/2] student and club discount requests --- accounts/__pycache__/forms.cpython-310.pyc | Bin 1685 -> 2022 bytes accounts/__pycache__/models.cpython-310.pyc | Bin 1902 -> 2358 bytes accounts/__pycache__/urls.cpython-310.pyc | Bin 1042 -> 1358 bytes accounts/__pycache__/views.cpython-310.pyc | Bin 5241 -> 6318 bytes accounts/forms.py | 9 ++++- accounts/models.py | 11 +++++- .../create_student_discount_request.html | 31 +++++++++++++++ accounts/urls.py | 3 ++ accounts/views.py | 36 ++++++++++++++++-- cinema/__pycache__/models.cpython-310.pyc | Bin 2537 -> 2487 bytes clubs/__pycache__/urls.cpython-310.pyc | Bin 1070 -> 1162 bytes clubs/__pycache__/views.cpython-310.pyc | Bin 5346 -> 5445 bytes .../clubs/create_club_discount_request.html | 3 +- clubs/templates/clubs/manage_clubs.html | 4 +- clubs/templates/clubs/view_club.html | 4 ++ clubs/urls.py | 3 +- clubs/views.py | 7 +++- db.sqlite3 | Bin 307200 -> 307200 bytes 18 files changed, 98 insertions(+), 13 deletions(-) create mode 100644 accounts/templates/accounts/create_student_discount_request.html diff --git a/accounts/__pycache__/forms.cpython-310.pyc b/accounts/__pycache__/forms.cpython-310.pyc index b6ce4c7b6c3a22e58e1a4a233437ccad26e077fe..6f46ab7caf1f5c40769fc8bd6d36411d7152a0cb 100644 GIT binary patch delta 872 zcma)4&ubGw6rS14>~50XG)>a<M_gKpRu-Y)y$FI-JTwP;%O%9jSd>kIv%9u<38??T zGI$cNiYMvSbFcmbb64oaOA)WWHwm^#3J%Q2d*6KX-pqUNUHD@uoP=S8z<R&^NSqa6 zL{Ex4(R9RnoDx9<OWcvy^C)>p1Q+gGB3wzI`)^9UGBBR-f$`@|1(>p^08;^`3Yq|z zstAAy=1eHULlW1{F=b2*e>zd4^qitsGT!~+aFUNRQ=GO|P5Us*g&b!Oo~4$3EMMd@ zEzZ8Xb&#vN{zBD$1I+Gcrm9E<2q6N}Y9{+@Eu&Qi;IJ<kfKM9KGR3!bNBR1-^Ktr5 zAk?ZF!V<!wkeCZ^UAO=~VKksNe^)iHyRrfYSasDxKyL^em;O}xMI-%z-Jo0gE4$r} zfHdXN;H3X@kmOQrg0HspZx+?@Xy)IVkvI8HWXWyo19ao?YH9QlS1XJD(9u76hjriv zl%lD8Fk)t!mmSbmx}i^<^{Jr3IdXbjl%S97)!L=RHfbOFxqBe9fmt5Q<Gz^puCE4} zG_I0^bTaP7?$t-(Td{QiQRX$W2f7Uu+s0pC;k%$&MV+lMdfm9D>+YtqxlAxj@+ax; zXd+~iDi6+0`2ZdKfSn237Q?KMg;5w}(Eu2K55nY$yoY0);;;my1yj&)8oa^V{vYXU BsWbop delta 608 zcmZ`$ze~eF6uxVdOPVIOrYe*+RS=XQI6H`gMV;)RIM}7My%Z`bl?#>X;-LRPIr=XM zZjLUFPA)Dk0XGpl7kA&giip&M`*`1X@5jCO-ZMkT={k-@;1nLWd2Zl%v@uxoYLsxo zwNUS{Dx+kNaGkSj!dXC1jH_hT1jXPcDCW140wu*QP%Ka^@JaLZA@S`ICiiKqx4NPe zjVQ9j;Gr}azp)Guk&&-dlxM-L+-d^<BGL#p0?K0I_G4wyG68hBV-3J0E)}NSU>-H( zUE=2QPZo3(4#Et=w0u|y%SH^qBpS7;Dqa!pe<5@5pbF*C16dO;9{G~|qy_n;6=_L+ zXshJ{h;gb@@7K=iVJ{FKa8UxdNbmGd+v0rbIH-&Evq4Dv9=_pg0z)Q#%gR|E=qsKQ zmlOx6_|ETn$)PUhr}dVXMOHBKD#DgW#$qeBn_;gJt#`US2qS?#$EkfJyRaoST-8vl fDUPAjrWTu<kf9d_Te#K;H)fM8jLuEC`hxxiW7ccH diff --git a/accounts/__pycache__/models.cpython-310.pyc b/accounts/__pycache__/models.cpython-310.pyc index b396b29e48cfde618b32f972fbf4c204f494bcd4..610354c75ef7fcbc6f8a5d38775785db043a4e9a 100644 GIT binary patch literal 2358 zcmah~&5zqe6t^8Gwi73tq@|S4t_lK0qARLO91udgBwMJU+iE`qSdom^Gn;klk95Xv z8&pp8+W&w99Q%*(N6eK|&b@Jg-?OvJZa1hC&C9&sJimGKz9wt8n;M39{SN!Hp=o~+ zb9R_uHZkRIAWUO=tR=dq>$Emv!!z(-i))GLnY#A1#!Oa!rm;HLr}bZJUIR#jSwJk_ z0B?b}nFHP_c^iC_wZOMZ-U08jHu&~ZLla1ctpQnEA}t_Y)&tU8A}%xbv_XFX3$=l+ z8cD`@EO)T9CC~FHoyd^(&W_W2Z35+*r!&nncx`Gjof*${ua0$t)#yIY4bLjM#*(wa zIm}`<<eJRE*-d3_g<)2t`94l<%|w(0V(vfS^F<x{7Y4`+Lp77&iO-@*luOlNJcLy2 z&*C8Da^aBNKP0DDaxqUQ`SH%6rEK3%gM|COYWhAdSH!e-eg9z*#MO?V6O^-6<k{_r z$4nU!Q|_obqC~tli)3k{FM^zV)?p9_X~>l`JPt(lkx9y4XyQ#ME6LwKj6NUl&VzLQ zPC7XblJO`Di-f1S93Q07BQ9i=&&NOVK&;;ykGA(l<Kg!=$HilQ<0y`v+z7MeFiJTa z2bFW=xC+h2Y%VAO7N(^9vo%-m;Mdhl{6e&J$ZTT1bU{v{#dLVyP_1EH94@`T^P(o! zAR@X%dPGj|Qmw8M_BKcd^CcN!Yo=Zz|9h%<3u1KAf#l-kB=HWwmD=CKMxQp{B|_Y5 zHMfUwQxd#h_xsRx<y1Fu7j)MEZeq$$Ku&!1N@knLY|8Qmul;WQp?Nkl;mf+}+z;jy z-Vx7(D3*(Ls1R+C#buD4f%B?&Dec4?AfC&rZ^~5lF3l=Mei#Vmr$uteg>ptnyeb*5 zp4;b7W)aGTVSA-Vui*fSnY2MDSLi1Qy>NRfw@pm>6Uf=y^Qxk$y3vQ=51TvF=Cs9X zRK?(3s&3XmwYSf4opan8)%`Qg>n`j5(ss)39o@~+{CF>i{p3Bb#k0g;<~+*Y$x<I3 ziRWCog2#}8OQ_OxWifsf6mh<wDiBl;g6<en!k-NCF$HyqDaj4FHr1!bQ#9k}`Y-xZ zeOkjbuWD2d)b)(ngF#(<07+$Khf^M+-P9&LSFJqD(Q)JqMyh7T%z}sw49}G(*8Auj z&M9{$9#lH2U(6^>epcj=Ng0~!$7B~(QU_7_`J)vM*|_-8&Y-s{msIn1CU`VSzvWen zP}Xp3Z@4wu_N=8t#dWg7CM)tN;mV|ys^=LC=7Q2x+#s?6;<e70DLy55RXZS0tz$~+ z3AWZp8=_`}>lmdML%`?8X_DOsd_KvhD5<GcJ|Z=*dMNOSEK|&(2L<a^nNpN&dYNn; zBo*On%tj0yb!9Iv7?t6&WAE~Z1(&(k`>%yph!h{f0zug#C=7!7V_C4bcLv>64i+~_ zq6VVYwhs2c@elU4cm2EfM%&*h>;CS&{q5ntXUXb(L?h0EyeipV7Bf6vXWx)s${(MH z%3h!vf(J57mHSne#XLwW1$Ho-iR=+)D}(SEOrnk@=?b=XxvX)QUIf}1w3WlAK|0Ac z*kSqDiCchGYYB!~dQ{!2ewSYV@);?+df9*lb;`0~lmRVOuChYeUsUhwm*i4O+2m?A SOzE3lt7~@6zS(bFasLIea~mW8 delta 839 zcmZ`%KX21O6!+O@$4(qK4Z&$>+NuFnN~<DZKn#GyKso@C5Ms&D%H)nHm19e1XXw%j z!565GnT>^o0f~)I!DjIVvas+4_&rlm2?bmC)BC-@ckjKg&7VP#*6URR-|bK9V%I(o zx@V_g!VoMrW^BY5$!2Vh%mYJMg1<8am+aVjYmGQGws4?vBnP*_E5ZeLOYVSsq6%Iu zc?G;Cd~p9Fg9}Yv1keN*8c&4g3!}fXpgZ+h;mlGY<7_xSU+sJ`S&KO#3@X%J^RQz< zbZ|0yfou3Iz~5lX(w^1TpUoS019Dy=Xb}8~{VTOe>Hz9Ezc|1(I8z;jZ#-B7?VCmI zWhT|5@i?6)`A}Vha%q+>469^ZC+JcJwx-`$;r0K9Y{2ts8KMuZj{a^v@A;sM7GT)- z)IWDO$+e{i{OR7ZXKcbuPsv;W^@4u2slV}$ckm1^O^(n=najdgGLCX7j*@65(c+4b zucLXKFQ|)(`l%}Vy?wxX`iDKJT^4KWeW%TK^ke7V_L9pL)j_J{bdo%gCm6v8Cp_Cm zvceUpmQQE0;3O4xo{H#1U7<p|1bcu{EuH6C9wlO$Ow>N9FAJAaIjkNGTR0ijca0{d zO*0ReZz{6&tA!_yqhyla6t9#ldv*)@!hS}3q-bNxi7OhIq7f+STp7HqV&UG$2F_#o WkijjZE%FVQHF=}b;0@m7q4OJ16_{)Q diff --git a/accounts/__pycache__/urls.cpython-310.pyc b/accounts/__pycache__/urls.cpython-310.pyc index 6f802ce2d136f5e6765c930a099cbb11d9cd4281..b4957187ee71e435be11d8dc5445dca41c94c212 100644 GIT binary patch delta 448 zcmbQlagIwnpO=@50SH<ZJyQ}`85kaeILJT%$Z-JT;u90KXPTrkriiC9XYr;;q_Fie z19_4_9$$(SlqU`3@u$duc<DS*0x7b=44QHq&v7!<R~aQHC+C;ul@#kI7o{eaq{bJQ zl%}NSmBgoH7K0_?i&6_qQ;SRVZ8GyptO~O2^l!-%P+DaSH#D)JpeVl#r>XVG#wrj{ zTvBBKHy7x{N@AQUi&vo^lcwP0TTF9Qi#UKmS;Pq<K*4^CyR;~$AhDz*wJ5K6B|{M( bNP=&24|A519FWPw$iv9T%*Tiga(n>*fh~+K delta 110 zcmX@dHHkwzpO=@50SM0aN~dgQW?*;>;vfTFAjbiSi|0+$p2?NY8O56-9?YOAvGE5d x6SJQt-(*IXIbyfCON(*}5=%-_i}H$BG8AzGH574AKE#s6C^1==Rg#J0I{><*7}Ed% diff --git a/accounts/__pycache__/views.cpython-310.pyc b/accounts/__pycache__/views.cpython-310.pyc index a5d7598631a7df75b992dedca6be0819838d8f69..89daf999c01b4449eb610198f397b51bbcd2e97b 100644 GIT binary patch literal 6318 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 delta 2117 zcma)7&2Jk;6!-XJcfDS(9e;nsiSt=6v{j%=n$RW<iJD3@{RA$1v7DWyGTpVq>{>!d zkPAX8f<rV1xFNWpUbyteg%jdJxwERo-_R4{#(T5Db|MGxO22uYc{B6-z4!L*53l{z z();PO8i8N^=N-B<bF5ECUqp^CUOaLYQy~!=p>Zeas-`OJgp+bLQv+L~vXgdoQ+G3F z#?6{pF{e0FZqCfPc{A@8%z|4qi*Cs*iM>gu>{iT*uvMq(*325%DXM)MG3zu<br`2< zhGt=G(A6oL17n8fX#vJrTBIcyo3u<TFwW5`t-&}?>vS5%1=@H!V$AS$vcW$l_ehLC zCo54S!Rygm{G;fv4<(SuasYwcKX~7^d@qP~9EW9behMK9U`T<?><<RE=d%h<77<Da zWq?4o`aR$N(0>|X4gPiPaao61PXkbhDjuC^gv~yy#dk^0Ac17{UAOB8amyJTuvy+u zR7r(DNi5DGp&)U{x;>x8z-D=bDnbpx;J+o-q!gM<T$SF~siP@Ky@FN?VHM#5!Zbo- z2s2;>ddIT*gPz~EnBDR168}tEC2RbXe1rckeX-L-?>U5dfTtvg9zJGEp{aCxp5N(N zHk*YBBN1L_ptHDh9jyxgUS2#BkrfK!IEfKqD+nQXv|dNJf*?)^Bh7@M@E}|g=L%K- zs%3CUK?`p4Fc=DdOR11++)_GD6OS1RVps9+3H=Eq1Bu#>?b}9tB9rrC8E)F=E6F0+ z<a@~{*|XR3KavYM6dI@yL*I7op6@}h3hITiV2L<kx`Wsw+h-XhdkNuHg#U`uHabm; zQ)YB!+v$4#yWr?ykt-xi6#k>CkzM|a`sGm*PdFVcs8{u$lIc>mg&sE$-UKjGY!t*H zdA5V=3WCV*NXAHkJSn~#L2}5HZR7q)YH~xL_9MGzGl*t~Yg(P`@s{@I{U+`^ts!KM zRm?UJM*QVTH5?>7zYS%76MZYZpI%-+SLH~XC~ti0#p`lX-u!vmSQ)8Kjj6sRPDc<$ zE-u@~zb(G3x0WX<&yJLb72o5&eu>=X-|5Gba(6ac>iO9cI<DjOqTWW7mH$H-$fi$q z8vawJ*!Ucd^RT^&G9!9aCkoNwfo{0}>}BQwnQOx8nPeH!u+Z^EhAwAKy}W}Bz$lE7 zA2k(0RD@on7b`D_Vf!rL_9OznJAr)AaYXC7!oSTe-ALntXgT_rK5?bUhKT+hbh?Xh z58*z-1B8b>k)N-Mwsg89uy<hjE54oIl+n6tEb?0UD!0nj1yMmVOq!*E-*vppVgGFp zQ_2+nO}Tc2l!L^3edc;$vlJzTd;`htL!<G+ZYmO%h3W7^g<&=|{GfQ3Pu%d^5y;fG zx^Bk_<AIHjtsz`P*hJVx*h9Dtu*LS#MD}A}4xv(fK9uWl`oOWb2zYpl0ELJKT||SY NK&JU|r5M%He*+#NiEID> diff --git a/accounts/forms.py b/accounts/forms.py index 1e19538c..c95c0e71 100644 --- a/accounts/forms.py +++ b/accounts/forms.py @@ -1,5 +1,5 @@ from django import forms -from .models import Account, EndOfMonthStatement +from .models import Account, EndOfMonthStatement, StudentDiscountRequest from clubs.models import Club class AccountForm(forms.ModelForm): @@ -18,4 +18,9 @@ class CardForm(forms.Form): expiryMonth = forms.IntegerField(label = "Expiry Month (number)", max_value=12, min_value=1, required=True) expiryYear = forms.IntegerField(label = "Expiry Year", min_value=2000, max_value=3000, required=True) cvc = forms.CharField(label = "CVC", max_length=3, min_length=3, required=True) - cardHolderName = forms.CharField(label = "Cardholder Name", max_length=255, required=True) \ No newline at end of file + cardHolderName = forms.CharField(label = "Cardholder Name", max_length=255, required=True) + +class StudentDiscountForm(forms.Form): + class Meta: + model = StudentDiscountRequest + fields = ['new_discount_rate', 'reason'] \ No newline at end of file diff --git a/accounts/models.py b/accounts/models.py index f94f8f0b..31dfe911 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -1,5 +1,6 @@ from django.db import models import datetime +from django.conf import settings # from payments.models import PaymentReceipt # Create your models here. @@ -37,4 +38,12 @@ class EndOfMonthStatement(models.Model): def update_outstanding(statement_id): statement = EndOfMonthStatement.objects.get(pk=statement_id) - return statement.total_spent - statement.total_paid \ No newline at end of file + return statement.total_spent - statement.total_paid + + +class StudentDiscountRequest(models.Model): + student = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, related_name='discount_requests') + old_discount_rate = models.FloatField(default=0) + new_discount_rate = models.FloatField(default=0) + reason = models.CharField(max_length=255) + approved = models.BooleanField(default=False) \ No newline at end of file diff --git a/accounts/templates/accounts/create_student_discount_request.html b/accounts/templates/accounts/create_student_discount_request.html new file mode 100644 index 00000000..401daabe --- /dev/null +++ b/accounts/templates/accounts/create_student_discount_request.html @@ -0,0 +1,31 @@ +{% extends 'base.html' %} {% block content %} +<div class="container"> + <div class="row"> + <div class="col-md-8 offset-md-2"> + <h1>Create Student Discount Request</h1> + <form method="post"> + {% csrf_token %} + <div class="form-group"> + <label for="{{ form.new_discount_rate.id_for_label }}" + >New Discount Rate:</label + > + {{ form.new_discount_rate }} {% if form.new_discount_rate.errors %} + <div class="invalid-feedback"> + {%for error in form.new_discount_rate.errors%}{{ error }}{%endfor%} + </div> + {% endif %} + </div> + <div class="form-group"> + <label for="{{ form.reason.id_for_label }}">Reason:</label> + {{ form.reason }} {% if form.reason.errors %} + <div class="invalid-feedback"> + {% for error in form.reason.errors %} {{ error }} {% endfor %} + </div> + {% endif %} + </div> + <button type="submit" class="btn btn-primary">Submit</button> + </form> + </div> + </div> +</div> +{% endblock %} diff --git a/accounts/urls.py b/accounts/urls.py index 5c6874db..f01fbf85 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -12,4 +12,7 @@ urlpatterns = [ path('accounts/<int:pk>/manage_statements/<int:st_pk>/update/', views.statement_update, name='update_statement'), path('accounts/<int:pk>/manage_statements/<int:st_pk>/delete/', views.statement_delete, name='delete_statement'), path('accounts/<int:pk>/top_up_balance', views.top_up_balance, name='top_up_balance'), + path('accounts/create_student_discount_request/<int:pk>/', views.create_student_discount_request, name='create_student_discount_request'), + path('accounts/approve_student_discount_request/<int:pk>/', views.approve_student_discount_request, name='approve_student_discount_request'), + path('accounts/deny_student_discount_request/<int:pk>/', views.deny_student_discount_request, name='deny_student_discount_request'), ] diff --git a/accounts/views.py b/accounts/views.py index da7f8a68..d737d255 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -1,10 +1,11 @@ from django.shortcuts import render, redirect, get_object_or_404 from django.contrib import messages +from django.conf import settings from utils.custom_decorators import get_user_permissions, is_in_group from utils.create_statement import create_statement from stripePayments.views import create_charge -from .forms import AccountForm, EndOfMonthStatementForm, CardForm -from .models import Account, EndOfMonthStatement, UserAccount, CinemaAccount, ClubAccount +from .forms import AccountForm, EndOfMonthStatementForm, CardForm, StudentDiscountRequestForm +from .models import Account, EndOfMonthStatement, UserAccount, CinemaAccount, ClubAccount, StudentDiscountRequest from clubs.models import Club from decimal import Decimal @@ -183,4 +184,33 @@ def top_up_balance(request, pk): form = CardForm() - return render(request, 'accounts/top_up_balance.html', {'form' : form}) \ No newline at end of file + return render(request, 'accounts/top_up_balance.html', {'form' : form}) + +def create_student_discount_request(request, pk): + perms = get_user_permissions(request) + if request.method == 'POST': + student = get_object_or_404(settings.USER_AUTH_MODEL, pk=pk) + form = StudentDiscountRequestForm(request.POST) + if form.is_valid(): + student_discount_request = form.save(commit=False) + student_discount_request.student = student + student_discount_request.old_discount_rate = student.account.discount_rate + student_discount_request.save() + return redirect('index') + else: + form = StudentDiscountRequestForm() + return render(request, 'clubs/create_student_discount_request.html', {'perms': perms, 'form': form}) + +def approve_student_discount_request(request, pk): + perms = get_user_permissions(request) + if perms == '0' or perms == '1': + return redirect('no_access') + discount_request = get_object_or_404(StudentDiscountRequest, pk=pk) + student = discount_request.student + student.account.discount_rate = discount_request.discount_rate + student.account.save() + discount_request.delete() + return redirect('index') + +def deny_student_discount_request(request, pk): + pass diff --git a/cinema/__pycache__/models.cpython-310.pyc b/cinema/__pycache__/models.cpython-310.pyc index 45f294de5d601ee73a6ed7e5f0304cc5651e83ef..72940bfd6a69badcde2c4f937ea65ecfdd2da5e4 100644 GIT binary patch delta 942 zcmaJ=zi-n(6!!VIlQ@-}gce9jD^)}el!$BvgoqjfRYjL}Kv5+t<gUSy6Qi>u#FPR4 z0dxx^GaC~VZ2S|)z?_|hjrW`=%1~;{pWc1<?%w;}d!CoRmE72Ma|%4Sw~uK3qg$Je zU_lj1B4tc^gecDxs#5KPLN!K4>U*uH0i#m`7-Pxkz?jqm##%B4FgA67ah8k;OpfM( z$uAj;7ETr4onv&LNOK%h7A0T5SBdEX#Xa$xoEsXLx_F{ih$cR3Wf9wsNYwM^I=Yw$ z7Qnm(AQfNbHX0UX7yW6Jp7=%Xpbtvqc?1=qfZ!q&#isW1{vsZ(GpmGF836r~B7m(F zNP*b!7Klf98B!S%UD*1a_LcX`TsP({98QkeJC0JMb=W>VY<HeYa}ZA0xX*8jRDZaC zSq4?`uV4n4J!ar#@p%=ZZ;3zpmmMsEw3FBI+i)^Wcny|NNqsVnqOMQ)rubpZ8e7P! zQcqZPA+>m#E<~=BN-GGGlm|gW49zfK2Y2ox+z`La8fl2X=B<sDH*dmLQ`D{6*_F!q z4qkyp<huyjji^YP$$&F9k#47-va@i^x*>}w&*JWjPgdNziw7`{bc0|J^^;`4q9_Q~ z5^teP)~7wNs^Y-jC40*OInJ*QhxlnX8~@9+=e*%Doet8Y4#zh04YBQ9pIz3B1K555 zUxEX+7zY>xWKVosI&{>Z4C8zBRW@MKc!9&5b$n3+RL(Kg?8ussRbi$52>yU+#2!}& S_$4@d1;x`m+jBhY+V(#en6JhF delta 1056 zcmah|O>fgc5Z#SGlh|!ZXqAelrAU=<s|F}1KBdyMfDl{)5{fDr<K3pN9J|_eir|t1 zJ#wl1E9k8!egX&n!JfEq=$#+Hj1#pz6iBpBv(Mw1w{OSa>Zf%#b=?Yq-#xy`I!A7E zcmNwl7>!Avb}7ZU6qov1SEJ-9VH(p93DY^<(?4rn0~mvuz?fsk1jb@EF!q?SfGM*I zFqJW515;%VFwU4MGq*#$iBm$Z65>&1_EW}V36cIra&hu?j+%84ChGYQy1k%7Xu*;W zfK43gP#gYJRN#~F=*n#Fm$si7uo0LiY=F}>07bl#C}UtTz7q`M?3Fhm&;e0Jz=EQL z;37;QOy-*Q_Rgq1?u!U?5-|-h2}@$$xekZcsF=>bXgzA=zqOV1f7Vx(tyJ)+m%QK~ z3;oL4Snq7Cw>Om;MhWi+VlIEDKUlp?K@%D`Pyx0;1vT)&p`r=h8~IQD_&S=PY`L3$ zh?1TZ^RPu*lR+GBc~ms=V`I2Hi)=~hlE*trO9$ELkY^`Vmha0<`2K3%F{A2DNEgcp z*YfXXldj~y%!T1uwzv(C&~1s=F-2$SC#N$K(2~Ic_Zt6kd=X2dx#9*w(FsqgOc@H! z6XmvpjK7Zhd@JHH6NMhy$`7q{Z57`@0m}9LFb<>)c^v!xg%jPyl;Q%HAX><m>_r2k zVsM!Kq<Ud+@)P^k@Nf6mE$@qz4Z`esTi_gsDFEfPc^LJBxX{)$_C*x(3*FCcx)0fp zU`ZU$(fGjNAp6Rzs509Nl3v<k?+=QJ>`n)RY?mil6b4z8CauvoA~eWX#!LKQit!m4 lhjs}(R8jA;_R4+;6$UYXOd+ipVTU-SnqISO<(f4!{|B0q%W(hz diff --git a/clubs/__pycache__/urls.cpython-310.pyc b/clubs/__pycache__/urls.cpython-310.pyc index d43dadb87610beefc1456d98d8b824f130268854..0b054ef35fa6458410201503fe50806ac7c0f138 100644 GIT binary patch delta 190 zcmZ3-(Z#8q&&$ij00cP-o+%Sp7#JRdILLq>$Z-JT;$suFH%p{4rbwkSX9=W8r?B@j zr*lUMrpN>{Xv%JU(aOk{T$Gwvk~(<@lf0t-Eg1+eJ~^i}DLy5$I61#GuOz-GwXig` zxTH#baxRk^v;HkvAT2w26O%Ke(ByASv!#o8fmYq(E-lI_NGvHyEy^oi$xtK&6e|*% Tyqr0mQEoCni!2KtBga<&4Qw+{ delta 123 zcmeC;T*slE&&$ij00cext|@{n3=EG!9Av-;<TwCv@s5ewo4L}tq6AW;f*CZWH-2kn zoP3Z;jp>#wkdmFu&g{%6IN6(dw%9H1(xRM##FCQKqP*gj3`K%K-9>_v8ClX9WhQ5` J$TD$!0|5Ki9IyZY diff --git a/clubs/__pycache__/views.cpython-310.pyc b/clubs/__pycache__/views.cpython-310.pyc index bda26fe5d5d0aaef32874010a0c7408ee35a5b8f..49b6420cc8e790f8d53a036ed5875d1f16ee9f0c 100644 GIT binary patch delta 423 zcmW;H&r1S96bJBmvp-yQw{}hP5Y#0I3+)h85ZEsWB#J^h+FFhWO%!HViWuo2bO@xw zUOVWqTVek~bnhsg`Ww1Lm)>)R`ONTT-ecxF`@Zb79VfwXTrU*G=d1HE9sOADor%dl zuHYUCnPNTYa>WH)acPGjcn?aLHn`9**$A~zS0MC0?`olexrz66r4M35CfAkTu!JGZ zK6DMGDZ`H|t&wOX@nkDwU=0~C>=~n;Ev)acovt1_iU~_`rHl9z?`b8LO&rTKK1a?H zo5TuoAh*!5QE!Rb&FxaP*|`i>Bjx5#rX+nsYD9t137hbUNsDbdtr0n5k0>HzuiX^B zs0Y<{rxp70BCJI(Mh0@xmwUQ6k2fr!nE)G?g_@Jy0{&;lQXtEtLk|F+qodRu_)$Ie o2<OpnDxZ17+JIhRflGy)+Q`bNFtZEEGUn1JD$zswO!MsIKM7M<i~s-t delta 358 zcmXYrze)o^5XN_A?=EL@r@2eefPWyJXJMg@A}AtS3KHzjq*;rc5OH&b$Oen6#bR5F zTw^JQJb;zh_ym^rK7!y(aEAHqx5Iq1`@Zp=gx6tM6%^&ov1(1ikA-{S>wh?OdQ?YL z!;Fv%BMKOS0R>m6gB%nV(4lUIN>V4uC25Cd(BRlDg<dz9dCF1l1B|4RW3Ln-$mg+d zAahxW5#|*mRK<Y7MEOrx$c{+nPIZ%>)QgNA!inA^e!2aDy1cz>+kUiS-|F#}ulbK! zGWHn}gB|*SvCTk2;^;Q(Rl6IVt+hz{z*(jAA((0W_1qYAI(>-%;Mu;$%h0u-@grQ= kw6VD~A=faNS?g><UZ8u^vT+Etl(%;oJ^Rx<m-9jG4|AkLhX4Qo diff --git a/clubs/templates/clubs/create_club_discount_request.html b/clubs/templates/clubs/create_club_discount_request.html index 097e6041..15de5fef 100644 --- a/clubs/templates/clubs/create_club_discount_request.html +++ b/clubs/templates/clubs/create_club_discount_request.html @@ -11,8 +11,7 @@ > {{ form.new_discount_rate }} {% if form.new_discount_rate.errors %} <div class="invalid-feedback"> - {% for error in form.new_discount_rate.errors %} {{ error }} {% - endfor %} + {%for error in form.new_discount_rate.errors%}{{ error }}{%endfor%} </div> {% endif %} </div> diff --git a/clubs/templates/clubs/manage_clubs.html b/clubs/templates/clubs/manage_clubs.html index 00680f72..416c8037 100644 --- a/clubs/templates/clubs/manage_clubs.html +++ b/clubs/templates/clubs/manage_clubs.html @@ -170,12 +170,12 @@ <div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <a class="dropdown-item" - href="{% url 'approve_club_discount_request' pk=club.pk %}" + href="{% url 'approve_club_discount_request' pk=request.pk %}" >Approve</a > <a class="dropdown-item" - href="{% url 'deny_club_discount_request' pk=club.pk %}" + href="{% url 'deny_club_discount_request' pk=request.pk %}" >Deny</a > </div> diff --git a/clubs/templates/clubs/view_club.html b/clubs/templates/clubs/view_club.html index f1db7fb2..680200a4 100644 --- a/clubs/templates/clubs/view_club.html +++ b/clubs/templates/clubs/view_club.html @@ -40,5 +40,9 @@ >Delete Club</a > </div> + <div class="mt-4"> + <a href="{% url 'create_club_discount_request' club.pk %}" class="btn btn-danger mr-3" + >Request New Discount Rate</a> + </div> </div> {% endblock %} diff --git a/clubs/urls.py b/clubs/urls.py index ac52400b..1f9be967 100644 --- a/clubs/urls.py +++ b/clubs/urls.py @@ -12,6 +12,7 @@ urlpatterns = [ path('view_club/<int:pk>/', views.view_club, name='view_club'), path('deactivate_club/<int:pk>/', views.deactivate_club, name='deactivate_club'), path('activate_club/<int:pk>/', views.activate_club, name='activate_club'), - path('approve_club_discount_request/<int:pk>', views.approve_club_discount_request, name='approve_club_discount_request'), + path('create_club_discount_request/<int:pk>/', views.create_club_discount_request, name='create_club_discount_request'), + path('approve_club_discount_request/<int:pk>/', views.approve_club_discount_request, name='approve_club_discount_request'), path('deny_club_discount_request/<int:pk>', views.deny_club_discount_request, name='deny_club_discount_request'), ] diff --git a/clubs/views.py b/clubs/views.py index 6e7bcbff..f50cf3d5 100644 --- a/clubs/views.py +++ b/clubs/views.py @@ -149,19 +149,22 @@ def representative_update(request, pk): context = {'form': form, 'user': request.user, 'club': club, 'representative': representative, 'perms': perms} return render(request, 'clubs/update_representative.html', context) -def create_club_discount_request(request): +def create_club_discount_request(request, pk): perms = get_user_permissions(request) if perms == '0': return redirect('no_access') if request.method == 'POST': + club = get_object_or_404(Club, pk=pk) form = ClubDiscountRequestForm(request.POST) if form.is_valid(): club_discount_request = form.save(commit=False) + club_discount_request.club = club + club_discount_request.old_discount_rate = club.account.discount_rate club_discount_request.save() return redirect('index') else: form = ClubDiscountRequestForm() - return render(request, 'create_club_discount_request.html', {'perms': perms, 'form': form}) + return render(request, 'clubs/create_club_discount_request.html', {'perms': perms, 'form': form}) def approve_club_discount_request(request, pk): perms = get_user_permissions(request) diff --git a/db.sqlite3 b/db.sqlite3 index 7564f958478eaf02706b30ade863491c242aab84..443b5a5f2d813493372190708cc5bb6afd8b0a8f 100644 GIT binary patch delta 116 zcmZp8Ak^?cXo57O)<hX+My-trOXQh__(CVME2uDrZdNqV<YSdlXSU~@u2{h$*<7sG zUaZFm#7scUyuDbDWvU?)|Le_y4o~=nL^&80IT($?Qx(b+^GXylOIWuRuy80a@&5+O RzvrJAz{<qRx@-Z9003V6ANT+O delta 108 zcmZp8Ak^?cXo57O#zYxsMvaXLOXQga`HCmAE2uC=ZB{hU<dft3#vsSYH=jY0F)y_| zK0Y}!FEuwYzBnVlJTos{pt)GDy;zSCh?#(xd3&)Q%T&Y791cJEw=)*7uqyzWfB3hv JEMWP=4*&ybA|wC+ -- GitLab