From df7f9651cf75d823664f0c36003719e9e6ee782a Mon Sep 17 00:00:00 2001 From: koksnuss Date: Sun, 10 May 2020 17:15:09 +0200 Subject: [PATCH] add render_found() function, fix loads of bugs --- coinmanager/coinc/models.py | 8 +- coinmanager/coinc/static/coinc/main.js | 54 +++++- coinmanager/coinc/static/coinc/styles.css | 21 ++- coinmanager/coinc/templates/coinc/coin.html | 2 +- .../coinc/templates/coinc/controlbar.html | 7 + coinmanager/coinc/views.py | 175 +++++++++++++----- coinmanager/db.sqlite3 | Bin 188416 -> 200704 bytes 7 files changed, 205 insertions(+), 62 deletions(-) diff --git a/coinmanager/coinc/models.py b/coinmanager/coinc/models.py index 6d1e61a..fe09904 100644 --- a/coinmanager/coinc/models.py +++ b/coinmanager/coinc/models.py @@ -18,7 +18,7 @@ -from datetime import datetime +from datetime import datetime, date from django.db.models import BooleanField, CASCADE, CharField, DateField, ForeignKey, Model, PositiveIntegerField, PositiveSmallIntegerField, TextField @@ -49,7 +49,7 @@ class Country(Model): def __str__(self): - return f"{self.name} - {self.name_iso}" + return f"{self.name} {self.name_iso} {self.comment}" @@ -81,9 +81,9 @@ class Coin(Model): name = TextField('Name', default='', blank=True) - found_by = ForeignKey('User', on_delete=CASCADE) + found_by = ForeignKey('User', on_delete=CASCADE, null=True, blank=True) - found_on = DateField('Gefunden am', auto_now_add=True) + found_on = DateField('Eingetragen am', default=date.today) circulation = PositiveIntegerField('Auflage', default=0) diff --git a/coinmanager/coinc/static/coinc/main.js b/coinmanager/coinc/static/coinc/main.js index d3f0915..b27ecb6 100644 --- a/coinmanager/coinc/static/coinc/main.js +++ b/coinmanager/coinc/static/coinc/main.js @@ -78,7 +78,6 @@ function render_login_color(color) { function render_found() { let checked = $('#found').prop('checked'); if (checked) { - console.log(settings); $('#found_by option[selected=selected]').html(settings['found_by']); let found_on = '' if (settings['found_on']) { @@ -103,6 +102,41 @@ function render_found() { } +// update table cell according to settings +function render_response(td, set) { + let td_class = ''; + let div_class = ''; + + if (!set['exists']) { + td_class = 'noexist'; + } else if (set['buy_only']) { + td_class = 'buy_only'; + } else if (set['circulation'] && set['circulation'] < 1500000 && set['circulation'] != 0) { + td_class = 'rare'; + } else if ([10, 20, 50].includes(Number($(td).attr('value')))) { + td_class = 'brass'; + } else if (set['found_by']) { + td_class = 'found'; + } + + if (set['ec']) { + td_class += ' ec'; + } else if (set['checked']) { + td_class += ' checked'; + } + + if (set['found'] && set['found_by'] && set['exists']) { + div_class = set['found_by']; + // TODO remove marker before marker + $(td).find('div.coin').append('x'); + } + $(td).removeClass(); + $(td).addClass('coin ' + td_class); + $(td).find('div[type=overlay]').removeClass(); + $(td).find('div[type=overlay]').addClass('found ' + div_class); +} + + // save/update global settings function save_settings() { settings['circulation'] = $('#circulation').val(); @@ -113,17 +147,16 @@ function save_settings() { settings['found_on'] = get_datetime(); } let found_by = $('#found_by option[selected=selected]').html(); - console.log(found_by); if (found_by) { settings['found_by'] = found_by; } - let checkboxes = $('#found, #buy_only, #checked, #ec').map(function() { + let checkboxes = $('#found, #buy_only, #checked, #ec, #exists').map(function() { return { [$(this).prop('id')]: $(this).prop('checked') } }).get(); for (let box of checkboxes) { for (let item in box) { settings[item] = box[item]; } } - console.log(settings); + settings['exists'] = !settings['exists'] } @@ -155,6 +188,11 @@ $(document).ready(function() { let found_by = (settings['found'] === true) ? settings['found_by'] : '' let found_on = (settings['found'] === true) ? settings['found_on'] : '' let circulation = (settings['circulation'] == 'Auflage') ? 0 : settings['circulation']; + + // TODO it would be nicer if #circulation, #found_by and #found_on would have no value while #exists is checked. then this would also not be neccessary + if (settings['exists'] === false) { + circulation = 0; + } let data = { csrfmiddlewaretoken: csrf_token, value: value, @@ -170,16 +208,18 @@ $(document).ready(function() { ec: settings['ec'], exists: settings['exists'] } + $.ajax({ type: 'POST', url: 'add/coin', data: data, + dataType: 'json', + td: this, success: function(response) { - if (response.status === 0) { - console.log('yarp'); + render_response(this.td, settings); } else { - console.log('nope'); + alert(response.message); } } }); diff --git a/coinmanager/coinc/static/coinc/styles.css b/coinmanager/coinc/static/coinc/styles.css index e983b3c..c6c632b 100644 --- a/coinmanager/coinc/static/coinc/styles.css +++ b/coinmanager/coinc/static/coinc/styles.css @@ -56,6 +56,7 @@ table { th { position: sticky; + z-index: 1; } tr { @@ -123,7 +124,15 @@ td > * { } -td.exists { +td.buy_only { + background-color: #dd7e6b; +} + +td.rare { + background-color: #e69138; +} + +td.noexist { background-color: #434343; } @@ -131,12 +140,8 @@ td.brass, th.brass { background-color: #ffff99 !important; } -td.rare { - background-color: #e69138; -} - -td.buy_only { - background-color: #dd7e6b; +td.found { + background-color: white; } td.year { @@ -152,7 +157,7 @@ td.spacer { background-color: white; } -td.in_collector { +td.ec { color: #ff0000; font-weight: bold; } diff --git a/coinmanager/coinc/templates/coinc/coin.html b/coinmanager/coinc/templates/coinc/coin.html index e84b8f1..5297406 100644 --- a/coinmanager/coinc/templates/coinc/coin.html +++ b/coinmanager/coinc/templates/coinc/coin.html @@ -1 +1 @@ -
{{ marker }}
+
{{ marker }}
diff --git a/coinmanager/coinc/templates/coinc/controlbar.html b/coinmanager/coinc/templates/coinc/controlbar.html index 4502c53..3c6cd38 100644 --- a/coinmanager/coinc/templates/coinc/controlbar.html +++ b/coinmanager/coinc/templates/coinc/controlbar.html @@ -1,3 +1,10 @@ + diff --git a/coinmanager/coinc/views.py b/coinmanager/coinc/views.py index de9a8f0..9bd1899 100644 --- a/coinmanager/coinc/views.py +++ b/coinmanager/coinc/views.py @@ -17,7 +17,7 @@ # along with this program. If not, see . -from datetime import datetime +from datetime import datetime, date from json import dumps from django.http import HttpResponse, Http404 @@ -153,20 +153,24 @@ def show_coin(country, year, stamp, value): } td_class = '' - if coin.buy_only: + if not coin.exists: + td_class = 'noexist' + elif coin.buy_only: td_class = 'buy_only' elif coin.circulation and coin.circulation < 1500000: td_class = 'rare' - elif not coin.exists: - td_class = 'noexist' elif coin.value in [10, 20, 50]: td_class = 'brass' + elif coin.found_by: + td_class = 'found' if coin.in_collector: - td_class += ' in_collector' + td_class += ' ec' elif coin.checked: - td_class += ' coin_checked' + td_class += ' checked' + div_class = '' + marker = '' if coin.found_by: div_class = f"found {coin.found_by}" marker = 'x' @@ -201,63 +205,150 @@ def add_user(request, username, color): return HttpResponse(dumps({ 'status': status, 'message': message })) +def response(status=0, message=''): + ''' return generic json-formatted status output with http-headers ''' + return HttpResponse(dumps({ 'status': status, 'message': message })) + + def add_coin(request): - country = Country.objects.get(name_iso=request.POST['country']) + + status = 0 + message = '' try: - stamp = Stamp.objects.get(name_short=request.POST['stamp']) + value = int(request.POST['value']) + except ValueError: + status = 1 + message = f"Der Münzwert '{value}' ist keine gültige Zahl." + return response(status, message) + if value not in [1,2,5,10,20,50,100,200,201,202,203]: + status = 1 + message = f"Der Münzwert '{value}' muss eine Zahl aus der Menge [1, 2, 5, 10, 20, 50, 100, 200, 201, 202, 203] sein." + return response(status, message) + + try: + year = int(request.POST['year']) + except ValueError: + status = 1 + message = f"Das Jahr '{year}' ist keine gültige Zahl." + return response(status, message) + if year < 1999: + status = 1 + message = "Das Jahr '{year}' ist kleiner als 1999." + return response(status, message) + if year > 2098: + status = 1 + message = f"Bitte den 2100-Jahrhundert-Datumsbug fixen. :-)" + return response(status, messae) + + try: + country = Country.objects.get(name_iso=request.POST['country']) + except Country.DoesNotExist: + status = 1 + message = f"Das Land mit ISO-Kürzel '{name_iso}' existiert nicht." + return response(status, message) + + stamp = request.POST['stamp'] + try: + stamp = Stamp.objects.get(name_short=stamp) except Stamp.DoesNotExist: + if stamp: + status = 1 + message = f"Die Prägerei '{stamp}' existiert nicht." + return response(status, message) stamp = None + try: + name = str(request.POST['name']) + except Exception as e: + status = 1 + message = f"Der Münzenname '{name}' ist kein gültiger Name. {e}" + return response(status, message) + + found_by = request.POST['found_by'] if request.POST['found_by'] else None + if found_by: + try: + found_by = User.objects.get(name=found_by) + except User.DoesNotExist: + status = 1 + message = f"Der Nutzer '{found_by}' existiert nicht." + return response(status, message) + + found_on = request.POST['found_on'] if request.POST['found_on'] else None + if found_on: + try: + print(f"found_on before: {found_on}") + found_on = datetime.strptime(found_on, '%d.%m.%Y') + found_on = found_on.strftime('%Y-%m-%d') + print(f"found_on after: {found_on}") + except ValueError: + status = 1 + message = f"Das Datum '{found_on}' entspricht nicht dem Format DD.MM.YYYY" + return response(status, message) + else: + found_on = date.today().strftime('%Y-%m-%d') try: - found_by = User.objects.get(name=request.POST['found_by']) - except User.DoesNotExist: - if not request.POST['exists']: - print('errorrr') - exit(0) - found_by = None + circulation = int(request.POST['circulation']) + except ValueError: + circulation = 0 + if circulation != 0: + if circulation < 0: + status = 1 + message = f"Die Münzauflage '{circulation}' muss 0 oder positiv sein." + return response(status, message) + elif circulation > 1000000000: + status = 1 + message = f"Die Münzauflage '{circulation}' ist unrealistisch." + return response(status, message) buy_only = True if request.POST['buy_only'] == 'true' else False - checked = True if request.POST['checked'] == 'true' else False - ec = True if request.POST['ec'] == 'true' else False - exists = True if request.POST['exists'] == 'true' else False + checked = True if request.POST['checked'] == 'true' else False + + ec = True if request.POST['ec'] == 'true' else False + + exists = True if request.POST['exists'] == 'true' else False + if not exists: + name = '' + found_by = None + found_on = date.today().strftime('%Y-%m-%d') + circulation = 0 + buy_only = False + checked = False + ec = False try: - print('update') - Coin.objects.update( - value=int(request.POST['value']), - year=int(request.POST['year']), + coin = Coin.objects.get( + value=value, + year=year, + country=country, + stamp=stamp) + coin.name=name + coin.found_by=found_by + coin.found_on=found_on + coin.circulation=circulation + coin.buy_only=buy_only + coin.checked=checked + coin.in_collector=ec + coin.exists=exists + coin.save() + except Coin.DoesNotExist: + Coin.objects.create( + value=value, + year=year, country=country, stamp=stamp, - name=request.POST['name'], + name=name, found_by=found_by, - found_on=request.POST['found_on'], - circulation=request.POST['circulation'], + found_on=found_on, + circulation=circulation, buy_only=buy_only, checked=checked, in_collector=ec, exists=exists) - except Coin.DoesNotExist: - print('new') - Coin.objects.create( - value=int(request.POST['value']), - year=int(request.POST['year']), - country=country, - stamp=stamp, - name=request.POST['name'], - found_by=found_by, - found_on=request.POST['found_on'], - circulation=request.POST['circulation'], - buy_only=buy_only, - checked=checked, - in_collector=ec, - exists=exists - ) - - return HttpResponse(dumps({'status': 'ok'})) + return response() # TODO diff --git a/coinmanager/db.sqlite3 b/coinmanager/db.sqlite3 index 4051a5848073d7026ebd7a2f8f8fa691969d6004..3e8245cc9344e46c3261c53ed1a0f591d33612de 100644 GIT binary patch delta 15098 zcmb_jcbpVe*6ptDo|&%Dji4Z47%;55FjTJU!7x3t=Je^xu5K98h@>G1NVF(0!z!RK zW>Hxc6=YBuF@XsaiaB9cRE(gAiN)`}d#kELO_%=&KhB}~Ij7%yb>6-A-B-?9C(K$R z&hOEgtBS>93jFbZEn3h=<+!T0K})lVp6TPSsP3dC(-)_YZ*!%z)4yjb)~$bj=-3f0 zLuFZ!n+8vsIJQZZRarLRlVa*7`_NZ5`YLj*qSxzYy`t3RRLe5W{ymC+Sk9IIu&!#w zKdjcPTD>OM={e1^RjoVx@IB9VKeVdr390Os>8GQTrs_0(}CR+z2Z2p zCWZ&^5l{4sdp|U0#PA7&Cyp4~a!$`xa=hUTCfq3&%Y5`l|88?H&2aI3+T0%To7Z)k zJ%9E5c%oA>9#3E1TD>H0InqngbJCO2T4{}RkF;F6O}a_CR$3%oE?pwck!DKgO5>$b zQnS<~ogtkjohThG<)!|TA@!3EmiCkOmbyw=sYZ&6zlh(9Ux}N=_ry2E7sY49$HWK4 zd&TAAt>TU1RpJ8iQgMzrL!2bGh{MG};u+$p;_>1D@i5Ub#eU*JVlT0W*hLh@l(0+q zQP?VM5k3+&39kyz3+sio!u>*)umEX>P&40?j&%epP#6QbF&OgN8$FJaTBZ^G+Yet7&(=6qi8#l_<3ur}*l$F;i2g^kljv8XUxy-D;2(d$I75xq+E3en3%FA=>+w2|lqqUVV= z06FmW&(X(ciJl>Pn&>H_^+Zn+Jwfz1(PKo960IXzOY{iQ!$c1eJxKHbBZrHvp^x_y zwG*u-x{v5yqI-x|5w#JmB)Xeu1<`V%yNK>2x`SvL(d|f1>^Ay%E75<6mJ;1UbTiRS zL`#TnB)WmI8Hm#nry)*7oPu~R;$*~0h!YXd zL7ad%9&sGvSca!?E%;#!;%LNCh$9h4AfAml9Puo~X2fBLLlK7{4sL&AdAtt?v6`RO zTD>y zai_RL+$w${egYBwP4Q)MgScLF)`<^5P+uY5F5WC&CoUG}Ls&mwJWre=P7p_nXF*^; zQ~axVl6Z{RC>|=BqAVUF?l0~m?kRSL*j^>ZgkOa1!Z*U_5Z&JqUKd^zo)w-D9)bA2 zO1Mk7RahciBU}j){$gRaFhiIuj1xvejQ_Xrci~jw1mUOwLIZ?(U8oZd5_$`J30)!3 z^For}#s9>A$A1N({saDP{#E`3{%QU(2==S_mHZw2QvL@1DhT)U_zU@2{IoWATn*SE z4S^al#xV99;x5GhA?`%{74a9upAmmT{1I^n;tz=15x+W@+zd`&u<*={( z3O{^__yyt?#Lp2wL;MtRGvX(RA0vK*_#xs4i0>o5hxjhyJBXVQ-$r~3@y%4ifvN62 z2jVis+YxU=ycO}kh)WS~LA)99Cd4I(HzMAEcs=5Eh}R-sgLpNfa}`o6;$p-_h*u(B zfw&NH0pfhb%MmX_{14(h#JPxc7{Xw1d#^|0AICeVvYT0z+%NlUc1Lzw_RH+%dv=@kayBEoW8k0v>}r6A zOl{w>F)q~l^>kMMqkp%#?`Gl~7PwC@oS(ce$?a@fEOW_$taksSzbUH+-?exg*FBxA zo|T=G*~vZH=3dKHS63$vhCl83`CRWr`=^t*{p0be3*1QwH$JM>IhUKgUzd^9-Fo$k z&mBK;@Q~5Xg>y*ZZ%X_AQ#hMzT{Ddv)U8i#@3Y2EY8lovWNOohVZCcdv`lOs-aMi8 zg=yTLt@EaFhqQN}&V8InxXCfCGaSx{|EX1RxbCgb!QZ**qg!{K$EmGt4%eggIEU-E zdKQ=LlrUqLwpP#Q`pZ=xR$X6pMpf6;E2;UZlT(@GhU6v50m)e6!NlZ*!hOvxA2X{BC(Eo{krv;@}8q)N5v)q8qZV<;=$B(ZfeHx6}@4 zuC1+wW207k(%6>fS~x9oiTspk3C+-TJ7<+kC``ifHO`IJPz_twb9T9gOv6ywFd8Q_ zi6bk{L@{!HHBe*{h;*sE9I^qw6j?4+k!5cn25L-<)R1$AuIh@cFb$`8 zQN59%$dTtTk&3gCZ9_HTB(Iha#PA;s8_AIqqD3s*u}oEwwQ?1`Sfz1%^n5JUR4hf- z%SAko(8C$mv4-RMOg2qJhxr&4L}*RMMo-6-bsHW|WwYX%v=oat#Z3=%ybMprfRTj! zsur)wkz5=zd_1wQj66wj;%6Br&X0O8Cmcnky}{=htPG!LebKP!46 zWbmmOILseHFbRc8G)GE67&0|K93IwE>uY%aQXwFL#<1VffUPg*T90q#_I4VF!hahM zeEzB#wx%i&Z~UF*f1kH(^nHy(qBShtGQdS0X`Bdo08$4Gx^Zx{h-q1{$ID&hKR*?c z3YTa`vX5kEWa~3OWmabSRkAv z2yhs=fNx0eOy8eACtX*wrDkbOQ%#TR*Qys(pIDu)T32Wi*4ZbuMTX24zlXo>XosgmZ)CdtvwskGE#eFm3 z4tLcKmn6_I%$#Xxp$!fi4&_%;QKD6J2ot6rJYg?MLvqF>?LA>v{v8q6&zc@QV#il0 ziF=K1zi1UrF;r{jGx75;ANYJ%||oF#P0*5{Gmk;b0#g zQ<4F(SB4!}J`8Uv7`EJlnMTDWHEi3|p$sdR2ogPvBkvwmq~Vm@2hccdHD?=o$gM&2 zLy6jBW8`H{}iV=9#UsQiVFr&E#L=VJNU;`WFPW5xE z>X69((ISR!>AF#FRDU*D9yhrAF^!5wHFT(LEu-A1jxR!ww|De7AU~VBQOT%Omb$%| zMkvSo8^%yA$j^rFRHwYwr@hM%~GcpH0TWG_UK5YprP4XPAQaMxMK<$Sfl6N?nN3M?0;Q_e5aeG zPA!OdF58odRCF1Xv?heZQl}O)yu#S+#wz0|6*!S>NqO*3*wLT!^bGh!ndOn?l~2dRZ?WJr2v1;bdCLt4giI=28=_0o9qU+oi#^Fc*r? z)zK0Li~$boqZ9WtrkxnvSfgaX7LDE(zPoP|8<2QembUW5cF*j7%< zSDLunX#EbPfT*b$*^&ny;hiUk8vax$crN{d1g%wkaz zYECY#$*`&C8Omm}}8OOJ?gK%Yu4J32rp4yMA!(dgo>N2tza zPnK=nI!FmJ>u8rh+aN2j&EM$ay+?;CC<2XFI6Z{ohu=NGwp-rCn~!|ZHg&xB_guLoSQ)JRfL57@87_BYsfEUUY-Y z?mkMZF&0XKp+KIrA-I>XtnYYMI^)ooQntM*O3le#)JFx5G^F*z@JY%-Zxo0yicxb56ZZVY!w z{ImGd_@H>t*z2){3-Vo|C(G_#q9y_Fvg&H({epXLG}EZ)Q6*5mZd2rGp2%dx_96b!h#mq21ye9f!d#Um_%+CuHZKty8{hy_iae7k2v+ zv80BoL%kmC6~A>@+z4%O+3iaQ<8ZwC0j`mtVW)-mik~5HE_f?ba-=K{Vz6Z)KWHJR z`n^<;XmrajWgL1x+Ye%jCc}YJ3pq82>#WvpbUVJ42}D#lL+RlfBoLuIHHfW9<-o2e zssUCFoa!%YphCI3spEC^msQrF+SNi%_1#Wq!hc6*!X3y&LfbAF2(+hjVY3&-vAlbF#bH2U2Xld=eg|(m_^aWSWPhzF z!Zh?;4jPXkqX!zSDV29mE7x%R|2@MX5e?c$A*cHR)f>pE#&h zu?==#7B0Mlp^(ba6;wPChy%J3F1&*WL?TBOi-g}6vZ0e;sfE(p&wGJyX;uDGtP*-# z$W~Rz8wLx8if%b@K z4b#?TsD2xpozj;eJrVDCb@=ayK%>VBm%pC#J&nVnH5>z4njO@?f!lC4henG)-3o>a z6~LZNa3GCtf2I*SB00gc(R8>X3Kzh^veM?M?@%QWfr~RZA%zSZh>-1b1(A;KL@c<( zgUij3V}s4Z44ZfD=tY4eI5ancK_3=HgKI=Vn~c27A7&8^B)5 c=9mA`zuVj_pX9g31}tzJxzuTG?#ZeD2cES^_W%F@ delta 1124 zcmZvaTSyd97{|}~&di+I+k9G@tf4uST`X(c5Q`ovd#Q)&sfQlI)!jvm((ai?yOZ=_ zz9?M|6oi3D5K+@Y6A@ccL2HmfU`APx(S@WaBIp7&Gs{A|IxxTg8Rj>0zHjDB4)~LI ze0}9JNSY9`)IM`ZPydoIkhB>YL>BZsILV7vm`1NB^&q%TnYBsAkGKh=cpJ}RFJ8gt zxC-k{V>T|wi+F^TQN~nkNB(RcsLXe z)rRV7L#s-4-xOuIQ1MPtGKGp~8fCmVZzsFEx&6kRgwCgNU*@U0GL7;gPpOiN2+eCv z=FjsDX{urOzU9B>t5~5@!V9*6LL#UP2dhnELb0j^ zyihB>IBpMQhTw1ffnRYF-`gWOhEMS^W-wz9X#J_lY0&M?ZvS#bx71KEM( LfH{Dns}TAJqkQnT