Merge branch 'master' into display-threading
Conflicts: client-barcode/freitagslib/network.py
This commit is contained in:
commit
028d03456f
|
@ -16,7 +16,7 @@
|
|||
inkscape:version="0.48.2 r9819"
|
||||
sodipodi:docname="freitagskasse.svg">
|
||||
<title
|
||||
id="title3609">HOWTO Freitagskasse v3.1</title>
|
||||
id="title3609">HOWTO Freitagskasse v3.2</title>
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
|
@ -53,9 +53,9 @@
|
|||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.49497475"
|
||||
inkscape:cx="370.73312"
|
||||
inkscape:cy="362.70358"
|
||||
inkscape:zoom="0.7"
|
||||
inkscape:cx="67.266124"
|
||||
inkscape:cy="265.56241"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
|
@ -73,7 +73,7 @@
|
|||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>HOWTO Freitagskasse v3.1</dc:title>
|
||||
<dc:title>HOWTO Freitagskasse v3.2</dc:title>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Sebastian Pipping <sebastian@pipping.org></dc:title>
|
||||
|
@ -1054,7 +1054,8 @@
|
|||
id="rect3535-9" /></flowRegion><flowPara
|
||||
id="flowPara3537-0">1 Euro</flowPara></flowRoot> </g>
|
||||
<g
|
||||
id="g6092">
|
||||
id="g6092"
|
||||
transform="translate(-1.09375e-6,0)">
|
||||
<g
|
||||
id="g4397"
|
||||
inkscape:label="ink_ext_XXXXXX"
|
||||
|
@ -1352,7 +1353,7 @@
|
|||
id="flowPara3537-0-75">10 Euro</flowPara></flowRoot> </g>
|
||||
<g
|
||||
id="g8994"
|
||||
transform="translate(-4,0)">
|
||||
transform="translate(-3.9999988,0)">
|
||||
<g
|
||||
id="g3261"
|
||||
inkscape:label="ink_ext_XXXXXX"
|
||||
|
@ -1545,7 +1546,7 @@
|
|||
id="flowPara3537-0-75-8">COMMIT</flowPara></flowRoot> </g>
|
||||
<g
|
||||
id="g8958"
|
||||
transform="translate(-4,0)">
|
||||
transform="translate(-19.933595,0)">
|
||||
<g
|
||||
id="g3163"
|
||||
inkscape:label="ink_ext_XXXXXX"
|
||||
|
@ -1705,7 +1706,7 @@
|
|||
height="87.14286"
|
||||
width="178.57143"
|
||||
id="rect3535-9-1-9" /></flowRegion><flowPara
|
||||
id="flowPara3537-0-75-7">UNDO</flowPara></flowRoot> </g>
|
||||
id="flowPara3537-0-75-7">STORNO</flowPara></flowRoot> </g>
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="color:#000000;fill:#000000;stroke:#000000;stroke-width:5.4000001;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
|
|
Before Width: | Height: | Size: 158 KiB After Width: | Height: | Size: 158 KiB |
|
@ -283,9 +283,15 @@ class Status:
|
|||
% ('', '', color(balance), sign(balance, plus),
|
||||
abs(balance), COLOR_RESET))
|
||||
|
||||
def shorten(text, length):
|
||||
if len(text) <= length:
|
||||
return text
|
||||
else:
|
||||
return text[:length - 3] + '...'
|
||||
|
||||
def show_item(position, diff, label, color):
|
||||
print('%2d) %-40s %s%c %6.2f Euro%s' \
|
||||
% (position, label, color, sign(diff),
|
||||
% (position, shorten(label, 40), color, sign(diff),
|
||||
abs(diff), COLOR_RESET))
|
||||
|
||||
def show_bar():
|
||||
|
@ -342,7 +348,7 @@ class Status:
|
|||
print_display('\x0b\nKonto: %5.2f!' % (self.balance) )
|
||||
print()
|
||||
|
||||
print(COLOR_SOME + 'Committen nicht vergessen.' + COLOR_RESET)
|
||||
print(COLOR_MUCH + 'Committen nicht vergessen.' + COLOR_RESET)
|
||||
else:
|
||||
print('Kontostand beträgt: %s%.2f Euro%s' % (COLOR_MUCH, self.balance, COLOR_RESET))
|
||||
display_screen("KONTOSTAND","%s: %.2f Euro" % (self.login_name,self.balance))
|
||||
|
|
|
@ -55,7 +55,7 @@ class BuyCommand(object):
|
|||
return self._item.name
|
||||
|
||||
def commodity_label(self):
|
||||
if self._deposit:
|
||||
if self._deposit or self.deposit_value() <= 0:
|
||||
return self._item.name
|
||||
else:
|
||||
return "%s (exkl. Pfand)" % self._item.name
|
||||
|
|
|
@ -23,7 +23,6 @@ DEPOSIT_CASH = 1
|
|||
DEPOSIT_BANK = 2
|
||||
|
||||
|
||||
_BASE_URL = 'http://devcat.someserver.de:13805/api2/'
|
||||
_BASE_URL = 'https://k4ever.freitagsrunde.org:443/api2/'
|
||||
|
||||
_auth = base64.encodestring('%s:%s' % (os.environ['BARCODE_PLUGIN_USER'], os.environ['BARCODE_PLUGIN_PASS'])).rstrip()
|
||||
|
|
46
devel/README
46
devel/README
|
@ -1,13 +1,55 @@
|
|||
Kassensystem
|
||||
############
|
||||
|
||||
Preamble
|
||||
========
|
||||
For ages there has been the discussion - Kassensystem!
|
||||
|
||||
So many attempts have been made, so many things have been discussed
|
||||
and overengineered... But oh well, here is our attempt!
|
||||
|
||||
|
||||
Mighty Kassensystem, finally!
|
||||
|
||||
Dependencies
|
||||
============
|
||||
- python-django >= 1.3
|
||||
- python-django-auth-ldap
|
||||
- python-django-piston
|
||||
- easy-thumbnails
|
||||
https://github.com/SmileyChris/easy-thumbnails.git
|
||||
|
||||
|
||||
Installation Process
|
||||
====================
|
||||
|
||||
1. Webserver
|
||||
|
||||
Some sort of Webserver is needed to host the django part. All about deploying
|
||||
django can be found at https://docs.djangoproject.com/en/dev/howto/deployment/
|
||||
Mostly this will be apache2 + mod_wsgi.
|
||||
|
||||
k4ever has static files which should be served by the webserver directly, so
|
||||
be sure to turn off python for the media/ directory.
|
||||
|
||||
For development there is also djangos builtin webserver. You can use it via
|
||||
./manage.py runserver but THIS SHOULD NEVER BE USED IN A PRODOCTIVE
|
||||
ENVIRONMENT.
|
||||
|
||||
|
||||
|
||||
2. The database
|
||||
- edit settings.py for database
|
||||
- Add Usergroups: ('Normal User', 'Plugin') ( to be renamed)
|
||||
- ./manage.py syncdb
|
||||
- install script for needed data will be written.
|
||||
|
||||
|
||||
API
|
||||
===
|
||||
Documentation
|
||||
=============
|
||||
|
||||
Yes, there is more documentation than this readme! It is present
|
||||
at k4ever/docs/, but if you want (and have python-sphinx) installed,
|
||||
you can compile it to nice html (or pdf, ...) pages. There is a
|
||||
``Makefile`` present to your assistance.
|
||||
|
||||
|
|
36
devel/TODO
36
devel/TODO
|
@ -11,25 +11,25 @@ Noch zu tun:
|
|||
[x] doku
|
||||
[x] API(wget)-Beispiele
|
||||
[ ] Authblob erlaubt momentan beliebige größe - beschrängen auf 10kb o.ä.
|
||||
[ ] API erlauben mehrere Items auf eine Order zu setzen (und damit auch deposit zu getränk zu kaufen)
|
||||
[x] API erlauben mehrere Items auf eine Order zu setzen (und damit auch deposit zu getränk zu kaufen)
|
||||
|
||||
Todo bis release:
|
||||
- artikel in datenbank (wir oder gemeinschaftlich am freitag?)
|
||||
- barcode client (sping)
|
||||
- pfand fuer barcode client
|
||||
- guter erklärender plugintext
|
||||
- startseite (konrad?)
|
||||
- beliebte items mit kaufoption, eventuell sortiert nach drei gruppen wie (Getränke, Essen, [Anderes]) oder (Getränke, Süßes, Salziges, [Anderes])
|
||||
- einkaufsseite
|
||||
- alle items, sortierung nach preis/alphabet
|
||||
- suchfeld fixen (konrad?)
|
||||
[x] image aspect ration checking und/oder irgendwo hinschreiben (seba)
|
||||
- transaktionsseite schöner machen
|
||||
- pluginseite (einstellungen) schöner machen
|
||||
- history: items durch bilder ersetzen, pfand drunterschreiben wenn pfand...
|
||||
[/] artikel in datenbank (wir oder gemeinschaftlich am freitag?)
|
||||
[ ] barcode client (sping)
|
||||
[x] pfand fuer barcode client
|
||||
[ ] guter erklärender plugintext
|
||||
[x] startseite
|
||||
[x] beliebte items mit kaufoption, eventuell sortiert nach drei gruppen wie (Getränke, Essen, [Anderes]) oder (Getränke, Süßes, Salziges, [Anderes])
|
||||
[x] einkaufsseite
|
||||
[x] alle items, sortierung nach preis/alphabet
|
||||
[x] suchfeld fixen (konrad?)
|
||||
[x] image aspect ration checking und/oder irgendwo hinschreiben (seba)
|
||||
[x] transaktionsseite schöner machen
|
||||
[x] pluginseite (einstellungen) schöner machen
|
||||
[x] history: items durch bilder ersetzen, pfand drunterschreiben wenn pfand...
|
||||
- apidocs probelesen
|
||||
- icons auf startseite unter loginfeld
|
||||
- blabla zum kassensystem fuer docs (tannek, seba)
|
||||
[ ] blabla zum kassensystem fuer docs
|
||||
|
||||
|
||||
Nice-to-haf:
|
||||
|
@ -48,8 +48,6 @@ Open for discussion:
|
|||
- 15, besser 20:Man sucht auf ja nach etwas und will sich nicht totklicken ~~~TKroenert
|
||||
|
||||
Konrad:
|
||||
Abmeldebutton rechts oder rot?
|
||||
- die liste der zu einkaufenden items ist doof :(
|
||||
- /store/history/ ist noch kaputt + zeit unformatiert
|
||||
- /transaction/ sehen die gemachten transactions noch nicht so cool aus
|
||||
- in js verhindern, das wer durch doppelklick auf "KAUFEN" das ding 2x kauft(also 2x http request abgesetzt werden)
|
||||
- BUG: Auf der HOME-seite ist das Bild direkt neben "SNACKS" nicht als link anklickbar
|
||||
- BUG: directBuy-anzeige ist z.B. auf der HOME-seite hinter den "Kauf"-Buttons
|
||||
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
|||
django gibt tabellenstruktur vor
|
||||
|
||||
webinterface
|
||||
mit django
|
||||
fuer
|
||||
adminsistration
|
||||
user preferences
|
||||
kaufen
|
||||
undsoweiter
|
||||
d.h. voller funktionsumfang
|
||||
|
||||
|
||||
-- milestone 2
|
||||
touchinterface am kuehlschrank
|
||||
möglichst simpel
|
|
@ -0,0 +1,54 @@
|
|||
<html><head><title>New Map</title><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" type="text/javascript"></script><script type="text/javascript">
|
||||
jQuery.noConflict();
|
||||
</script>
|
||||
<script src="http://vue.tufts.edu/htmlexport-includes/jquery.maphilight.min.js" type="text/javascript"></script><script src="http://vue.tufts.edu/htmlexport-includes/v3/tooltip.min.js" type="text/javascript"></script><script type="text/javascript">jQuery(function() {jQuery.fn.maphilight.defaults = {
|
||||
fill: false,
|
||||
fillColor: '000000',
|
||||
fillOpacity: 0.2,
|
||||
stroke: true,
|
||||
strokeColor: '282828',
|
||||
strokeOpacity: 1,
|
||||
strokeWidth: 4,
|
||||
fade: true,
|
||||
alwaysOn: false
|
||||
}
|
||||
jQuery('.example2 img').maphilight();
|
||||
});
|
||||
</script>
|
||||
<style type="text/css">
|
||||
#tooltip{
|
||||
position:absolute;
|
||||
border:1px solid #333;
|
||||
background:#f7f5d1;
|
||||
padding:2px 5px;
|
||||
color:#333;
|
||||
display:none;
|
||||
}
|
||||
</style>
|
||||
</head><body>
|
||||
<div class="example2"><img class="map" src="map.png" width="771.0" height="847.0" usemap="#vuemap"><map name="vuemap"> <area id="node0" shape="rect" coords="24,433,243,521"></area>
|
||||
<area class="tooltip" title="deprecated (json-)
|
||||
api from Konrad;
|
||||
used by the
|
||||
webinterface" id="node1" shape="rect" coords="429,26,515,66"></area>
|
||||
<area class="tooltip" title="new all-in-one
|
||||
REST-Api" id="node2" shape="rect" coords="424,113,521,152"></area>
|
||||
<area class="tooltip" title="/App/ for buyables
|
||||
like mate,kitkat" id="node3" shape="rect" coords="409,202,534,242"></area>
|
||||
<area class="tooltip" title="/App/ for login,
|
||||
register,settings" id="node4" shape="rect" coords="421,307,524,346"></area>
|
||||
<area class="tooltip" title="/App/ for
|
||||
moneytransfers" id="node5" shape="rect" coords="396,398,548,437"></area>
|
||||
<area class="tooltip" title="stores webstuff
|
||||
(images,css,js)" id="node6" shape="rect" coords="415,527,529,567"></area>
|
||||
<area class="tooltip" title="django-default" id="node7" shape="rect" coords="401,621,545,661"></area>
|
||||
<area class="tooltip" title="django-default
|
||||
(empty)" id="node8" shape="rect" coords="401,784,545,824"></area>
|
||||
<area class="tooltip" title="maps URLs to
|
||||
python-(views.py)
|
||||
functions " id="node9" shape="rect" coords="417,693,527,733"></area>
|
||||
<area id="node10" shape="rect" coords="695,486,745,518"></area>
|
||||
<area id="node11" shape="rect" coords="695,537,746,570"></area>
|
||||
<area id="node12" shape="rect" coords="702,595,737,627"></area>
|
||||
|
||||
</map></div></body></html>
|
Binary file not shown.
After Width: | Height: | Size: 104 KiB |
|
@ -92,6 +92,10 @@ class BuyableItemHandler(BaseHandler):
|
|||
amount = getInt(request.data, 'amount', 1)
|
||||
if amount < 1:
|
||||
return rc.BAD_REQUEST
|
||||
if amount > 30:
|
||||
ret = rc.BAD_REQUEST
|
||||
ret.write("\nYou are trying to buy more than 30 items at once. This is not permitted. If you think it should, mail the admins / fix this in the handlers.py\n");
|
||||
return ret
|
||||
if (not item.hasDeposit() and deposit != self.BUY_ITEM) or \
|
||||
deposit not in (self.BUY_ITEM, self.BUY_DEPOSIT, self.BUY_ITEM_AND_DEPOSIT):
|
||||
return rc.BAD_REQUEST
|
||||
|
@ -145,6 +149,11 @@ class BuyableItemHandler(BaseHandler):
|
|||
ret.write("\nThe items/deposists parameter have to be a list.\n")
|
||||
return ret
|
||||
|
||||
if len(itemList) > 30:
|
||||
ret = rc.BAD_REQUEST
|
||||
ret.write("\nYou are trying to buy more than 30 items at once. This is not permitted. If you think it should, mail the admins / fix this in the handlers.py\n");
|
||||
return ret
|
||||
|
||||
if len(itemList) == 0:
|
||||
ret = rc.BAD_REQUEST
|
||||
ret.write("\nYour request contains no items/deposits.\n")
|
||||
|
@ -251,9 +260,9 @@ class TransactionTransactHandler(BaseHandler):
|
|||
amount = getDecimal(request.POST, 'amount', Decimal(0))
|
||||
tTypeId = getInt(request.POST, 'type', -1)
|
||||
|
||||
if amount <= 0:
|
||||
if amount < Decimal("0.01"):
|
||||
ret = rc.BAD_REQUEST
|
||||
rc.write("\nA negative amount is not supported right now (there has not been put enough thought into the 'lending money' process\n")
|
||||
ret.write("\nA negative amount (or zeroed) is not supported right now (there has not been put enough thought into the 'lending money' process\n")
|
||||
return ret
|
||||
tType = None
|
||||
try:
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
{% extends "base.html" %}
|
||||
{% load thumbnail %}
|
||||
|
||||
|
||||
{% block "content" %}
|
||||
{% if history %}
|
||||
<h1>Frühere Einkäufe von {{ user }}</h1>
|
||||
<div style="width:800px">
|
||||
<h1>Frühere Einkäufe von {{ user }}</h1>
|
||||
</div>
|
||||
<div class="pagination" style="width:800px; text-align:center; margin-top:25px">
|
||||
<table width="100%">
|
||||
<tr>
|
||||
|
@ -51,7 +55,7 @@
|
|||
{% for item in order.purchase_set.all %}
|
||||
<td width="80px">
|
||||
{% if not item.isDeposit %}
|
||||
<img src="{{ MEDIA_URL }}{{ item.buyable.image }}" width=64 height=64>
|
||||
<img src="{% thumbnail item.buyable.image 64x64 %}" width=64 height=64>
|
||||
{% else %}
|
||||
<b>{{ item.buyable.name }} Pfand</b>
|
||||
{% endif %}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
{% load thumbnail %}
|
||||
|
||||
{% if buyables %}
|
||||
<table class="showitem">
|
||||
<tbody>
|
||||
{% for buyable in buyables %}
|
||||
<tr>
|
||||
<td class="productImage">
|
||||
<a href="/store/show/{{ buyable.id }}"><img src="{% thumbnail buyable.image 64x64 %}"/></a>
|
||||
</td>
|
||||
<td class="name"><a href="/store/show/{{ buyable.id }}">{{ buyable.name }}</a></td>
|
||||
<td class="actions">
|
||||
{% if buyable.hasDeposit %}
|
||||
<a class="buyButton includingPrice" href="/store/buy/{{ buyable.id }}"
|
||||
title="Kaufen (Ohne Pfand)">
|
||||
<span><span>{{ buyable.price|floatformat:2 }} €</span></span>
|
||||
</a>
|
||||
|
||||
<a class="buyButton includingDeposit includingPrice"
|
||||
href="/store/buy/{{ buyable.id }}/with/deposit" title="Kaufen (Mit Pfand)">
|
||||
<span><span>{{ buyable.price|floatformat:2 }} € / {{ buyable.deposit|floatformat:2 }} €</span></span>
|
||||
</a>
|
||||
|
||||
<a class="buyButton onlyDeposit includingPrice"
|
||||
href="/store/buy/{{ buyable.id }}/only/deposit" title="Kaufen (Nur Pfand)">
|
||||
<span><span>{{ buyable.deposit|floatformat:2 }} €</span></span>
|
||||
</a>
|
||||
|
||||
{% else %}
|
||||
<a class="buyButton includingPrice" href="/store/buy/{{ buyable.id }}"
|
||||
title="Kaufen">
|
||||
<span><span>{{ buyable.price|floatformat:2 }} €</span></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p>{{ default|default_if_none:"Noch keine gekauft" }}</p>
|
||||
{% endif %}
|
|
@ -1,4 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
{% load thumbnail %}
|
||||
|
||||
|
||||
{% block "content" %}
|
||||
<p><a href="/store/">Zur Liste aller Items</a></p>
|
||||
|
@ -10,7 +12,7 @@
|
|||
<tr>
|
||||
<td colspan="2" align="center">
|
||||
<div style="font-size:large">{{ item.name }}</div>
|
||||
<img src="{{ MEDIA_URL }}{{ item.image }}">
|
||||
<img src="{% thumbnail item.image 400x400 %}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
|
@ -1,46 +1,8 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block "content" %}
|
||||
<div style="float:left; width=200;">
|
||||
<table class="showitem" width="864px" style="border-width:0px">
|
||||
{% for item in items %}
|
||||
<tr>
|
||||
<td width="64px">
|
||||
<a href="/store/show/{{ item.id }}"><img WIDTH=64 HEIGHT=64 src="{{ MEDIA_URL }}{{ item.image }}"></a>
|
||||
</td>
|
||||
<th width="200px" align="center">
|
||||
<span style="font-size: large">{{ item.name }}</span><br/>
|
||||
<a href="/store/show/{{ item.id }}">Details</a>
|
||||
</th>
|
||||
<td width="200px">
|
||||
<a class="button" href="/store/buy/{{ item.id }}/">Kaufen für {{ item.price|floatformat:2 }} €<br/>{% if item.hasDeposit %} (Ohne Pfand){% endif %}</a>
|
||||
</td>
|
||||
<td width="200px">
|
||||
{% if item.hasDeposit %}
|
||||
<a class="button" href="/store/buy/{{ item.id }}/with/deposit/">Kaufen für {{ item.price|floatformat:2 }} € <br/>+ {{ item.deposit|floatformat:2 }} € Pfand</a>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</td>
|
||||
<td width="200px">
|
||||
{% if item.hasDeposit %}
|
||||
<a class="button" href="/store/buy/{{ item.id }}/only/deposit/">Kaufen <br/>nur {{ item.deposit|floatformat:2 }} € Pfand</a>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% comment %}
|
||||
Buy <a href="/store/buy/{{ item.id }}/">it!</a>
|
||||
{% if item.hasDeposit %}
|
||||
<a href="/store/buy/{{ item.id }}/with/deposit/">it+deposit!</a>
|
||||
<a href="/store/buy/{{ item.id }}/only/deposit/"> only deposit!</a>
|
||||
{% endif %}
|
||||
</br> (
|
||||
{% for type in item.buyableType.all %}
|
||||
{{ type }}
|
||||
{% endfor %} )
|
||||
</div>{% endcomment %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
Sortieren nach <a href="/store/">Letzte Änderung</a> | <a href="?order=alphabet">Alphabet</a> | <a href="?order=price">Preis</a><br/>
|
||||
<div style="width:800px">
|
||||
{% include "buyables/product_list.html" with buyables=items %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -11,6 +11,17 @@ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger, Invali
|
|||
def showItems(request):
|
||||
# FIXME: Implement pagination here
|
||||
items = Buyable.objects.all()
|
||||
|
||||
try:
|
||||
order_by = request.GET.get('order', 'date')
|
||||
except ValueError:
|
||||
order_by = 'date'
|
||||
|
||||
if order_by == 'alphabet':
|
||||
items = items.order_by('name')
|
||||
if order_by == 'price':
|
||||
items = items.order_by('price')
|
||||
|
||||
return render_to_response("buyables/showItems.html", {'items': items}, RequestContext(request))
|
||||
|
||||
@login_required
|
||||
|
|
|
@ -1,31 +1,29 @@
|
|||
{% load thumbnail %}
|
||||
|
||||
{% if buyables %}
|
||||
{% if removeWrapper == None %}
|
||||
<table width=100%>
|
||||
<table width=100% class="showitem">
|
||||
<tbody>
|
||||
{% endif %}
|
||||
{% for buyable in buyables %}
|
||||
<tr>
|
||||
<td class="productImage">
|
||||
<a href="/store/show/{{ buyable.buyable__id }}"><img src="{{ MEDIA_URL }}{{ buyable.buyable__image }}" /></a>
|
||||
<a href="/store/show/{{ buyable.buyable__id }}"><img src="{% thumbnail buyable.buyable__image 64x64 %}" /></a>
|
||||
</td>
|
||||
<td class="name"><span>{{ buyable.buyable__name }}</span> ({{ buyable.num_buys }} mal gekauft)</td>
|
||||
<td>
|
||||
<td class="name"><span>{{ buyable.buyable__name }}</span> {% if buyable.num_buys %}({{ buyable.num_buys }} mal gekauft){% endif %}</td>
|
||||
<td class="actions">
|
||||
{% if buyable.buyable__deposit > 0 %}
|
||||
<a class="buyButton" href="/store/buy/{{ buyable.buyable__id }}" title="Kaufen (Ohne Pfand)"><span>Kaufen (Ohne Pfand)</span></a>
|
||||
<a class="buyButton includingDeposit" href="/store/buy/{{ buyable.buyable__id }}/with/deposit" title="Kaufen (Mit Pfand)"><span>Kaufen (Mit Pfand)</span></a>
|
||||
<a class="buyButton includingPrice" href="/store/buy/{{ buyable.buyable__id }}" title="Kaufen (Ohne Pfand)"><span><span>{{ buyable.buyable__price|floatformat:2 }}€</span></span></a>
|
||||
<a class="buyButton includingDeposit includingPrice" href="/store/buy/{{ buyable.buyable__id }}/with/deposit" title="Kaufen (Mit Pfand)"><span><span>{{ buyable.buyable__price|floatformat:2 }} € / {{ buyable.buyable__deposit|floatformat:2 }}€</span></span></a>
|
||||
{% if includeDeposit %}
|
||||
<a class="buyButton onlyDeposit" href="/store/buy/{{ buyable.buyable__id }}/only/deposit" title="Kaufen (Nur Pfand)"><span>Kaufen (Nur Pfand)</span></a>
|
||||
<a class="buyButton onlyDeposit" href="/store/buy/{{ buyable.buyable__id }}/only/deposit" title="Kaufen (Nur Pfand)"><span><span>{{ buyable.buyable__deposit|floatformat:2 }}€</span></span></a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<a class="buyButton" href="/store/buy/{{ buyable.buyable__id }}" title="Kaufen"><span>Kaufen</span></a>
|
||||
<a class="buyButton" href="/store/buy/{{ buyable.buyable__id }}" title="Kaufen"><span><span>{{ buyable.buyable__price|floatformat:2 }}€</span></span></a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if removeWrapper == None %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<p>{{ default|default_if_none:"Noch keine gekauft" }}</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<form method="post" action="/what/do/i/know">
|
||||
<form method="get" action="#">
|
||||
<input placeholder="Suche und kaufe..." class="autocomplete"
|
||||
type="search" name="search_term" value="Lade Daten..."
|
||||
disabled="disabled" />
|
||||
<input type="submit" value="Suchen" />
|
||||
</form>
|
||||
</form>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{% block "content" %}
|
||||
{% if allMostDrinks or allMostSnacks %}
|
||||
<table class="showitem">
|
||||
<table style="border: 0 none; width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<td role="presentation"> </td>
|
||||
|
@ -14,25 +14,25 @@
|
|||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Getränke</th>
|
||||
<td>
|
||||
<td style="vertical-align:top">
|
||||
{% include "main/product_list.html" with buyables=allMostDrinks %}
|
||||
</td>
|
||||
<td>
|
||||
<td style="vertical-align:top">
|
||||
{% include "main/product_list.html" with buyables=usersMostDrinks %}
|
||||
</td>
|
||||
<td>
|
||||
<td style="vertical-align:top">
|
||||
{% include "main/product_list.html" with buyables=usersLastDrinks %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr style="border-top: 2px solid #ECECEC">
|
||||
<th scope="row">Snacks</th>
|
||||
<td>
|
||||
<td style="vertical-align.top">
|
||||
{% include "main/product_list.html" with buyables=allMostSnacks %}
|
||||
</td>
|
||||
<td>
|
||||
<td style="vertical-align:top">
|
||||
{% include "main/product_list.html" with buyables=usersMostSnacks %}
|
||||
</td>
|
||||
<td>
|
||||
<td style="vertical-align:top">
|
||||
{% include "main/product_list.html" with buyables=usersLastSnacks %}
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -18,4 +18,10 @@
|
|||
|
||||
<input type="submit" value="Anmelden" />
|
||||
<input type="hidden" name="next" value="{{ next }}" />
|
||||
</form>
|
||||
</form>
|
||||
|
||||
|
||||
<div class="notice">
|
||||
<h2>Das Kassensystem ist 'Aktiv' - nutzt euren Frunden-Account</h2>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block "content" %}
|
||||
<h2>Passwort</h2>
|
||||
<hr />
|
||||
<div style="width:800px">
|
||||
<h1>Passwort</h1>
|
||||
Da die meisten der Nutzer dieses Systems über den LDAP der Freitagsrunde laufen, kann man hier sein Passwort nicht ändern. Wenn du dein Passwort trotzdem ändern möchstest (und dieses System nicht über einen Freitagsrundenaccount benutzt), wende dich bitte an einen der Freitagsrunden-Admins. (lies: not implemented)
|
||||
<br />
|
||||
<br />
|
||||
<h2>Plugin Berechtigungen</h2>
|
||||
<hr />
|
||||
</div>
|
||||
<div style="width:800px; margin-top: 25px">
|
||||
<h1>Pluginberechtigungen</h1>
|
||||
{% if pluginerror %}
|
||||
<font color="red">{{ pluginerror|safe }}</font>
|
||||
{% endif %}
|
||||
|
@ -15,28 +14,33 @@
|
|||
<font color="green">{{ pluginmsg|safe }}</font>
|
||||
{% endif %}
|
||||
<p>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Author</th>
|
||||
<th>Version</th>
|
||||
<th>Beschreibung</th>
|
||||
<th>AuthBlob</th>
|
||||
<th>Erlauben/Verbieten</th>
|
||||
<table style="border: 2px solid #BBBBBB; -moz-border-radius: 3px; -webkit-border-radius: 3px; -khtml-border-radius: 3px; border-radius: 3px">
|
||||
<tr style="height: 40px">
|
||||
{% if permissions %}
|
||||
<th rowspan={{ permissions|length|add:"1"}} style="vertical-align:middle; text-align:center; color:#0cb31c; -moz-transform: rotate(270deg); -webkit-transform: rotate(270deg); -ms-transform: rotate(270deg); -o-transform: rotate(270deg); transform: rotate(270deg)">Erlaubt</th>
|
||||
{% else %}
|
||||
<th> </th>
|
||||
{% endif %}
|
||||
<th width="100px" style="vertical-align:middle">Name</th>
|
||||
<th width="100px" style="vertical-align:middle">Author</th>
|
||||
<th style="vertical-align:middle">Beschreibung</th>
|
||||
<th width="100px" style="vertical-align:middle">AuthBlob</th>
|
||||
<th width="150px" style="vertical-align:middle">Erlauben/Verbieten</th>
|
||||
</tr>
|
||||
{% for p in permissions %}
|
||||
<tr style="background: green">
|
||||
<td style="vertical-align:middle">{{ p.plugin.name }}</td>
|
||||
<td style="vertical-align:middle">{{ p.plugin.author }}</td>
|
||||
<td style="vertical-align:middle">{{ p.plugin.version }}</td>
|
||||
<td style="vertical-align:top">{{ p.plugin.descr }}</td>
|
||||
<td>
|
||||
<tr>
|
||||
<td style="vertical-align:middle; text-align:center">{{ p.plugin.name }}<br/>{{ p.plugin.version }}</td>
|
||||
<td style="vertical-align:middle; text-align:center">{{ p.plugin.author }}</td>
|
||||
<td style="vertical-align:middle; text-align:center"><div style="margin: 5px">{{ p.plugin.descr }}</div></td>
|
||||
<td style="text-align:center">
|
||||
{% if p.plugin.userCanWriteAuthblob %}
|
||||
<form method="post" action="/user/settings/plugin/authblob/{{ p.plugin.id }}/">
|
||||
{% csrf_token %}
|
||||
<textarea name="authblob">{{ p.authblob }}</textarea>
|
||||
<input type="submit" value="Speichern">
|
||||
</form>
|
||||
<div style="margin:5px">
|
||||
<form method="post" action="/user/settings/plugin/authblob/{{ p.plugin.id }}/">
|
||||
{% csrf_token %}
|
||||
<textarea name="authblob">{{ p.authblob }}</textarea>
|
||||
<input type="submit" value="Speichern">
|
||||
</form>
|
||||
</div>
|
||||
{% else %}
|
||||
{% if p.plugin.userCanReadAuthblob %}
|
||||
{{ p.authblob }}
|
||||
|
@ -45,20 +49,22 @@
|
|||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="vertical-align:middle"><a href="/user/settings/plugin/deny/{{ p.plugin.id }}/">Plugin verbieten</a></td>
|
||||
<td style="vertical-align:middle; text-align:center"><a href="/user/settings/plugin/deny/{{ p.plugin.id }}/" class="button" style="color: #e61e1e; margin-bottom: 35px">Plugin verbieten</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% for plugin in unallowed %}
|
||||
<tr style="background: red">
|
||||
<td style="vertical-align:middle">{{ plugin.name }}</td>
|
||||
<td style="vertical-align:middle">{{ plugin.author }}</td>
|
||||
<td style="vertical-align:middle">{{ plugin.version }}</td>
|
||||
<td style="vertical-align:top">{{ plugin.descr }}</td>
|
||||
<td> </td>
|
||||
<td style="vertical-align:middle"><a href="/user/settings/plugin/allow/{{ plugin.id }}/">Plugin erlauben</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
{% if unallowed %}
|
||||
<tr style="border-top: 1px solid #BBBBBB">
|
||||
<th rowspan={{ unallowed|length}} style="vertical-align:middle; text-align:center; color:#e61e1e; -moz-transform: rotate(270deg); -webkit-transform: rotate(270deg); -ms-transform: rotate(270deg); -o-transform: rotate(270deg); transform: rotate(270deg)">Verboten</th>
|
||||
{% for plugin in unallowed %}
|
||||
<td style="vertical-align:middle; text-align:center">{{ plugin.name }}<br/>{{ plugin.version }}</td>
|
||||
<td style="vertical-align:middle; text-align:center">{{ plugin.author }}</td>
|
||||
<td style="vertical-align:middle; text-align:center"><div style="margin:5px">{{ plugin.descr }}</div></td>
|
||||
<td> </td>
|
||||
<td style="vertical-align:middle; text-align:center"><a class="button" href="/user/settings/plugin/allow/{{ plugin.id }}/" style="color: #0cb31c; margin-buttom: 35px">Plugin erlauben</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</table>
|
||||
</p>
|
||||
{% endblock %}
|
||||
|
|
|
@ -20,18 +20,20 @@ def startpage(request):
|
|||
|
||||
allMostDrinks = allMost.filter(buyable__in=drinks).annotate(num_buys=Count('buyable')).order_by('-num_buys')
|
||||
allMostSnacks = allMost.filter(buyable__in=snacks).annotate(num_buys=Count('buyable')).order_by('-num_buys')
|
||||
|
||||
|
||||
usersMostDrinks = allMost.filter(buyable__in=drinks).filter(order__user=request.user.id).annotate(num_buys=Count('buyable')).order_by('-num_buys')
|
||||
usersMostSnacks = allMost.filter(buyable__in=snacks).filter(order__user=request.user.id).annotate(num_buys=Count('buyable')).order_by('-num_buys')
|
||||
|
||||
# usersLastDrinks = allMost.filter(buyable__in=drinks).filter(order__user=request.user.id).annotate(num_buys=Count('buyable')).order_by('-order__dateTime')
|
||||
# usersLastSnacks = allMost.filter(buyable__in=snacks).filter(order__user=request.user.id).annotate(num_buys=Count('buyable')).order_by('-order__dateTime')
|
||||
usersLastDrinks = allMost.filter(buyable__in=drinks).filter(order__user=request.user.id).annotate(num_buys=Count('buyable')).order_by('-order__dateTime')
|
||||
usersLastSnacks = allMost.filter(buyable__in=snacks).filter(order__user=request.user.id).annotate(num_buys=Count('buyable')).order_by('-order__dateTime')
|
||||
|
||||
usersLastDrinks = allMost.distinct().filter(buyable__in=drinks).filter(order__user=request.user.id).order_by('-order__dateTime')
|
||||
usersLastSnacks = allMost.distinct().filter(buyable__in=snacks).filter(order__user=request.user.id).order_by('-order__dateTime')
|
||||
|
||||
usersLastDrinks = allMost.filter(buyable__in=drinks).filter(order__user=request.user.id).order_by('-order__dateTime')
|
||||
usersLastSnacks = allMost.filter(buyable__in=snacks).filter(order__user=request.user.id).order_by('-order__dateTime')
|
||||
|
||||
#if someone knows a better way to do this, just replace this code
|
||||
#purpose: filter usersLast so that it only contains unique items
|
||||
#hint: distinct() does not work because dateTime is included due to order_by(), so all items appear distinct
|
||||
|
||||
usersLastDrinks_unique = []
|
||||
for x in usersLastDrinks:
|
||||
if not x in usersLastDrinks_unique:
|
||||
|
@ -43,9 +45,10 @@ def startpage(request):
|
|||
for x in usersLastSnacks:
|
||||
if not x in usersLastSnacks_unique:
|
||||
usersLastSnacks_unique.append(x)
|
||||
#usersLastSnacks_unique = usersLastSnacks.distinct()
|
||||
usersLastSnacks = usersLastSnacks_unique
|
||||
|
||||
return render_to_response("main/startpage.html", {'allMostDrinks' : allMostDrinks[:5], 'allMostSnacks' : allMostSnacks[:5], 'usersMostDrinks': usersMostDrinks[:5], 'usersMostSnacks': usersMostSnacks[:5], 'usersLastDrinks' : usersLastDrinks[:10], 'usersLastSnacks' : usersLastSnacks[:10]}, RequestContext(request))
|
||||
return render_to_response("main/startpage.html", {'allMostDrinks' : allMostDrinks[:5], 'allMostSnacks' : allMostSnacks[:5], 'usersMostDrinks': usersMostDrinks[:5], 'usersMostSnacks': usersMostSnacks[:5], 'usersLastDrinks' : usersLastDrinks[:5], 'usersLastSnacks' : usersLastSnacks[:5]}, RequestContext(request))
|
||||
|
||||
def register(request):
|
||||
""" The "no registration available" page... """
|
||||
|
@ -122,9 +125,13 @@ def pluginAuthblob(request, pluginId):
|
|||
d['pluginerror'] = "Der Authblob darf für dieses Plugin nicht vom User verändert werden (oder der Authblob war kaputt)"
|
||||
return render_to_response("settings/settings.html", d, RequestContext(request))
|
||||
|
||||
if p.plugin.uniqueAuthblob and PluginPermission.objects.filter(plugin=plugin, authblob=request.POST["authblob"]).count() > 0:
|
||||
pluginsWithAuthblob = PluginPermission.objects.filter(plugin=plugin, authblob=request.POST["authblob"])
|
||||
if p.plugin.uniqueAuthblob and pluginsWithAuthblob.count() > 0:
|
||||
d = getPluginDict(request)
|
||||
d['pluginerror'] = "Achtung! Dein Authblob wird bereits von einer anderen Person benutzt. Bitte wähle einen anderen (eindeutigen) Authblob!"
|
||||
if pluginsWithAuthblob[0].user == request.user:
|
||||
d['pluginerror'] = "Das ist der gleiche Authblob, den du vorher auch hattest."
|
||||
else:
|
||||
d['pluginerror'] = "Achtung! Dein Authblob wird bereits von einer anderen Person benutzt. Bitte wähle einen anderen (eindeutigen) Authblob!"
|
||||
return render_to_response("settings/settings.html", d, RequestContext(request))
|
||||
|
||||
p.authblob = request.POST['authblob']
|
||||
|
|
|
@ -38,10 +38,15 @@ body {
|
|||
line-height: 1;
|
||||
}
|
||||
|
||||
|
||||
h1, h2, h3, h4, h5, h6, th {
|
||||
clear: both;
|
||||
font-weight: bold;
|
||||
font-family: "Istok Web", inherit;
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
/* Sans-Serif? Srsly???
|
||||
font-family: "Istok Web", inherit; */
|
||||
|
||||
}
|
||||
|
||||
ol, ul, li {
|
||||
|
@ -396,7 +401,7 @@ table.showitem td.productImage img {
|
|||
table.showitem th {
|
||||
font-size: 20px;
|
||||
text-align:center;
|
||||
}
|
||||
}*/
|
||||
|
||||
table.showitem td.name {
|
||||
padding: 0 10px;
|
||||
|
@ -407,6 +412,19 @@ table.showitem td.name span {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
table.showitem td.name a {
|
||||
display: block;
|
||||
font: 20px "Istok Web", inherit;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table.showitem tbody tr:nth-child(even) td.name,
|
||||
table.showitem tbody tr:nth-child(even) td.actions {
|
||||
background-color: #ececec;
|
||||
}
|
||||
|
||||
table.showitem td, table.showitem th {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
@ -429,11 +447,14 @@ table.showitem th[scope="row"] {
|
|||
a.buyButton {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
margin: 10px 10px 15px 0;
|
||||
position: relative;
|
||||
height: 32px;
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
z-index: 2;
|
||||
text-decoration: none;
|
||||
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#666666), to(#111111));
|
||||
background-image: -webkit-linear-gradient(top, #666666, #111111);
|
||||
|
@ -448,7 +469,12 @@ a.buyButton {
|
|||
box-shadow: 0 1px 3px 0 black;
|
||||
}
|
||||
|
||||
a.buyButton:hover {
|
||||
a.buyButton.includingPrice {
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.content a.buyButton:hover {
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#555555), to(#000000));
|
||||
background-image: -webkit-linear-gradient(top, #555555, #000000);
|
||||
background-image: -moz-linear-gradient(top, #555555, #000000);
|
||||
|
@ -465,15 +491,52 @@ a.buyButton:active {
|
|||
box-shadow: 0 1px 3px 0 black, 0 1px 3px 0 black inset;
|
||||
}
|
||||
|
||||
a.buyButton.includingDeposit span {
|
||||
a.buyButton.includingDeposit > span {
|
||||
background-image: url("img/payment_deposit.png");
|
||||
min-width: 65px;
|
||||
}
|
||||
|
||||
a.buyButton span {
|
||||
a.buyButton.onlyDeposit > span {
|
||||
background-image: url("img/deposit.png");
|
||||
}
|
||||
|
||||
a.buyButton > span {
|
||||
display: block;
|
||||
height: 100%;
|
||||
min-width: 32px;
|
||||
background: url("img/payment.png") no-repeat center center transparent;
|
||||
text-indent: -10000px;
|
||||
}
|
||||
|
||||
.content a {
|
||||
color: #3398CC;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.content a:hover {
|
||||
color: white;
|
||||
background: #3398CC;
|
||||
}
|
||||
|
||||
.content a.button {
|
||||
display: block;
|
||||
margin-top: 7px;
|
||||
padding: 0 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a.buyButton > span > span {
|
||||
position: absolute;
|
||||
bottom: -15px;
|
||||
left: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
border-bottom-left-radius: 6px;
|
||||
border-bottom-right-radius: 6px;
|
||||
background-color: #3398cc;
|
||||
color: white;
|
||||
|
||||
-moz-box-shadow: 0 1px 3px 0 black, 0 1px 1px 0 black inset;
|
||||
-webkit-box-shadow: 0 1px 3px 0 black, 0 1px 1px 0 black inset;
|
||||
box-shadow: 0 1px 3px 0 black, 0 1px 1px 0 black inset;
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../docs/_build/html/
|
|
@ -74,7 +74,7 @@ LOGIN_REDIRECT_URL = '/'
|
|||
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
# 'main.backend.CustomLDAPBackend',
|
||||
# 'django_auth_ldap.backend.LDAPBackend',
|
||||
'django_auth_ldap.backend.LDAPBackend',
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
)
|
||||
|
||||
|
@ -129,4 +129,5 @@ INSTALLED_APPS = (
|
|||
'main',
|
||||
# Uncomment the next line to enable the admin:
|
||||
'django.contrib.admin',
|
||||
'easy_thumbnails',
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue