Skip to content

Commit

Permalink
Fnugfald razzia (#381)
Browse files Browse the repository at this point in the history
* Added basic foobar razzia copy called fnugfald razzia

* Removed unused, duplicated element id: 'result'

* Added the razzia to admin menu.

* Moved .result div into each razzia type, to allow multiple results

* Implemented fnugfald razzia

* Made use of guard clauses

* Don't store razzia information on users who don't have a ticket

* Changed hardcoded values to actual values.

* Fixed crash issue when product id isn't recognized
  • Loading branch information
krestenlaust authored Nov 3, 2023
1 parent add394b commit 85b33b5
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 67 deletions.
5 changes: 3 additions & 2 deletions stregreport/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@

class BreadRazzia(models.Model):
class Meta:
permissions = (("host_razzia", "Can host a foobar or bread razzia"),)
permissions = (("host_razzia", "Can host a foobar, fnugfald or bread razzia"),)

BREAD = 'BR'
FOOBAR = 'FB'
RAZZIA_CHOICES = [(BREAD, "Brødrazzia"), (FOOBAR, "Foobar razzia")]
FNUGFALD = 'FF'
RAZZIA_CHOICES = [(BREAD, "Brødrazzia"), (FOOBAR, "Foobar razzia"), (FNUGFALD, "Fnugfald razzia")]
members = models.ManyToManyField(Member, through='RazziaEntry')
start_date = models.DateTimeField(auto_now_add=True)
razzia_type = models.CharField(max_length=2, choices=RAZZIA_CHOICES, default=BREAD)
Expand Down
4 changes: 4 additions & 0 deletions stregreport/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,16 @@
urlpatterns = [
re_path(r'^admin/stregsystem/razzia/bread/(?P<razzia_id>\d+)/$', views.razzia, {'razzia_type' : BreadRazzia.BREAD, 'title': 'Brødrazzia'}, name="bread_view"),
re_path(r'^admin/stregsystem/razzia/foobar/(?P<razzia_id>\d+)/$', views.razzia, {'razzia_type' : BreadRazzia.FOOBAR, 'title': 'Foobar razzia'}, name="foobar_view"),
re_path(r'^admin/stregsystem/razzia/fnugfald/(?P<razzia_id>\d+)/$', views.razzia, {'razzia_type' : BreadRazzia.FNUGFALD, 'title': 'Fnugfald razzia'}, name="fnugfald_view"),
re_path(r'^admin/stregsystem/razzia/bread/(?P<razzia_id>\d+)/members$', views.razzia_members, {'razzia_type' : BreadRazzia.BREAD, 'title': 'Brødrazzia'}),
re_path(r'^admin/stregsystem/razzia/foobar/(?P<razzia_id>\d+)/members$', views.razzia_members, {'razzia_type' : BreadRazzia.FOOBAR, 'title': 'Foobar razzia'}),
re_path(r'^admin/stregsystem/razzia/fnugfald/(?P<razzia_id>\d+)/members$', views.razzia_members, {'razzia_type' : BreadRazzia.FNUGFALD, 'title': 'Fnugfald razzia'}),
re_path(r'^admin/stregsystem/razzia/bread/$', views.razzia_menu, {'razzia_type' : BreadRazzia.BREAD, 'new_text': "New bread razzia", 'title': 'Brødrazzia'}),
re_path(r'^admin/stregsystem/razzia/foobar/$', views.razzia_menu, {'razzia_type' : BreadRazzia.FOOBAR, 'new_text': "New foobar razzia", 'title': 'Foobar razzia'}),
re_path(r'^admin/stregsystem/razzia/fnugfald/$', views.razzia_menu, {'razzia_type' : BreadRazzia.FNUGFALD, 'new_text': "New fnugfald razzia", 'title': 'Fnugfald razzia'}),
re_path(r'^admin/stregsystem/razzia/bread/new$', views.new_razzia, {'razzia_type' : BreadRazzia.BREAD}, name="razzia_new_BR"),
re_path(r'^admin/stregsystem/razzia/foobar/new$', views.new_razzia, {'razzia_type' : BreadRazzia.FOOBAR}, name="razzia_new_FB"),
re_path(r'^admin/stregsystem/razzia/fnugfald/new$', views.new_razzia, {'razzia_type' : BreadRazzia.FNUGFALD}, name="razzia_new_FF"),
re_path(r'^admin/stregsystem/razzia/wizard_guide/$', views.razzia_wizard),
re_path(r'^admin/stregsystem/razzia/wizard/$', views.razzia_view, name="razzia_view"),
re_path(r'^admin/stregsystem/report/sales/$', views.sales, name="salesreporting"),
Expand Down
103 changes: 67 additions & 36 deletions stregreport/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,32 +50,80 @@ def razzia(request, razzia_id, razzia_type=BreadRazzia.BREAD, title=None):
return razzia_view_single(request, razzia_id, None, razzia_type=razzia_type, title=title)


def _sales_to_user_in_period(username, start_date, end_date, product_list, product_dict):
result = (
Product.objects.filter(
sale__member__username__iexact=username,
id__in=product_list,
sale__timestamp__gte=start_date,
sale__timestamp__lte=end_date,
)
.annotate(cnt=Count("id"))
.values_list("name", "cnt")
)

products_bought = {product: count for product, count in result}

return {product: products_bought.get(product, 0) for product in product_dict}


@permission_required("stregreport.host_razzia")
def razzia_view_single(request, razzia_id, queryname, razzia_type=BreadRazzia.BREAD, title=None):
razzia = get_object_or_404(BreadRazzia, pk=razzia_id, razzia_type=razzia_type)
if queryname is not None:
result = list(Member.objects.filter(username__iexact=queryname))
if len(result) > 0:
member = result[0]
entries = list(razzia.razziaentry_set.filter(member__pk=member.pk).order_by('-time'))
already_checked_in = len(entries) > 0
wait_time = datetime.timedelta(minutes=30)
if already_checked_in:
last_entry = entries[0]
within_wait = last_entry.time > timezone.now() - wait_time
# if member has already checked in within the last hour, don't allow another check in
if already_checked_in and within_wait and razzia_type == BreadRazzia.FOOBAR:
drunkard = True
# time until next check in is legal
remaining_time_secs = int(((last_entry.time + wait_time) - timezone.now()).total_seconds() % 60)
remaining_time_mins = int(((last_entry.time + wait_time) - timezone.now()).total_seconds() // 60)
if not already_checked_in or (razzia_type == BreadRazzia.FOOBAR and not within_wait):
RazziaEntry(member=member, razzia=razzia).save()

templates = {
BreadRazzia.BREAD: 'admin/stregsystem/razzia/bread.html',
BreadRazzia.FOOBAR: 'admin/stregsystem/razzia/foobar.html',
BreadRazzia.FNUGFALD: 'admin/stregsystem/razzia/fnugfald.html',
}

if queryname is None:
return render(request, templates[razzia_type], locals())

result = list(Member.objects.filter(username__iexact=queryname))
if len(result) == 0:
return render(request, templates[razzia_type], locals())

member = result[0]

if razzia_type == BreadRazzia.FNUGFALD:
username = queryname
member_name = member.firstname + " " + member.lastname
start_date = dateparse.parse_date("2023-9-15")
end_date = dateparse.parse_date("2023-11-4")
product_list = [1910]
product_dict = {k.name: 0 for k in Product.objects.filter(id__in=product_list)}
sales_to_user = _sales_to_user_in_period(queryname, start_date, end_date, product_list, product_dict)
items_bought = sales_to_user.items()

try:
item_bought_count = sales_to_user[list(sales_to_user.keys())[0]]
if item_bought_count == 0:
return render(request, templates[razzia_type], locals())
except IndexError:
return render(request, templates[razzia_type], locals())

entries = list(razzia.razziaentry_set.filter(member__pk=member.pk).order_by('-time'))
already_checked_in = len(entries) > 0
wait_time = datetime.timedelta(minutes=30)
if already_checked_in:
last_entry = entries[0]
within_wait = last_entry.time > timezone.now() - wait_time
# if member has already checked in within the last hour, don't allow another check in
if (
already_checked_in
and within_wait
and (razzia_type == BreadRazzia.FOOBAR or razzia_type == BreadRazzia.FNUGFALD)
):
drunkard = True
# time until next check in is legal
remaining_time_secs = int(((last_entry.time + wait_time) - timezone.now()).total_seconds() % 60)
remaining_time_mins = int(((last_entry.time + wait_time) - timezone.now()).total_seconds() // 60)
if not already_checked_in or (
(razzia_type == BreadRazzia.FOOBAR or razzia_type == BreadRazzia.FNUGFALD) and not within_wait
):
RazziaEntry(member=member, razzia=razzia).save()

return render(request, templates[razzia_type], locals())


Expand All @@ -92,7 +140,7 @@ def new_razzia(request, razzia_type=BreadRazzia.BREAD):
razzia = BreadRazzia(razzia_type=razzia_type)
razzia.save()

views = {BreadRazzia.BREAD: 'bread_view', BreadRazzia.FOOBAR: 'foobar_view'}
views = {BreadRazzia.BREAD: 'bread_view', BreadRazzia.FOOBAR: 'foobar_view', BreadRazzia.FNUGFALD: 'fnugfald_view'}

return redirect(views[razzia_type], razzia_id=razzia.pk)

Expand All @@ -109,23 +157,6 @@ def razzia_members(request, razzia_id, razzia_type=BreadRazzia.BREAD, title=None
razzia_members = staff_member_required(razzia_members)


def _sales_to_user_in_period(username, start_date, end_date, product_list, product_dict):
result = (
Product.objects.filter(
sale__member__username__iexact=username,
id__in=product_list,
sale__timestamp__gte=start_date,
sale__timestamp__lte=end_date,
)
.annotate(cnt=Count("id"))
.values_list("name", "cnt")
)

products_bought = {product: count for product, count in result}

return {product: products_bought.get(product, 0) for product in product_dict}


@permission_required("stregreport.host_razzia")
def razzia_view(request):
default_start = timezone.now().today() - datetime.timedelta(days=-180)
Expand Down
5 changes: 5 additions & 0 deletions stregsystem/templates/admin/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<th scope="row"><a href = "/admin/stregsystem/razzia/fnugfald/">Fnugfald razzia</a></th>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<th scope="row"><a href = "/admin/stregsystem/razzia/wizard_guide/">Razzia wizard!</a></th>
<td>&nbsp;</td>
Expand Down
8 changes: 5 additions & 3 deletions stregsystem/templates/admin/stregsystem/razzia/bread.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Hjem</a>&nbsp;&rsaquo;&nbsp;<a href="../../../">Stregsystem</a>&nbsp;&rsaquo;&nbsp;<a href="../">Brødrazzia</a></div>{% endblock %}

{% block member_present %}
<div class="status">
<div class="fa {% if already_checked_in %} fa-minus-circle failure {% else %} fa-check-circle sucess {% endif %}" aria-hidden="true"></div>
<div class="result">
<div class="status">
<div class="fa {% if already_checked_in %} fa-minus-circle failure {% else %} fa-check-circle sucess {% endif %}" aria-hidden="true"></div>
</div>
{{member.firstname}} {{member.lastname}} ({{member.username}}) {% if already_checked_in %} already checked in at {{ last_entry.time }} {% endif %}
</div>
{{member.firstname}} {{member.lastname}} ({{member.username}}) {% if already_checked_in %} already checked in at {{ last_entry.time }} {% endif %}
{% endblock %}
64 changes: 64 additions & 0 deletions stregsystem/templates/admin/stregsystem/razzia/fnugfald.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{% extends "admin/stregsystem/razzia/razzia_search.html" %}

{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Hjem</a>&nbsp;&rsaquo;&nbsp;<a href="../../../">Stregsystem</a>&nbsp;&rsaquo;&nbsp;<a href="../">Fnugfald razzia</a></div>{% endblock %}

{% block member_present %}
<div class="result">
<div class="status">
{% if drunkard %}
<script>
// fade/flash background color to more easily notify foobar crew
let ofs = 0;
let el = document.body;
window.setInterval(function(){
el.style.background = 'rgba(255,255,0,'+Math.abs(Math.sin(ofs))+')';
ofs += 0.02;
}, 10);
</script>
<div class="fa fa-exclamation-triangle failure" aria-hidden="true"></div>
{% else %}
<div class="fa {% if already_used %} fa-exclamation-circle sucess {% else %} fa-check-circle sucess {% endif %}" aria-hidden="true"></div>
{% endif %}
</div>
{% if drunkard %}
{{member.firstname}} {{member.lastname}} ({{member.username}}) <b>wait {{ remaining_time_mins }}m {{ remaining_time_secs }}s </b> before next free beer
{% else %}
{{member.firstname}} {{member.lastname}} ({{member.username}}) {% if already_checked_in %} last checked in at {{last_entry.time}} {% endif %}
{% endif %}
</div>

{% if username %}
{% if member_name %}
{% if items_bought %}
{% for item, count in items_bought %}
<div class="result">
{% if count > 0 %}
<div class="status"><div class="fa fa-check-circle sucess fa-fw" aria-hidden="true"></div></div>
{% else %}
<div class="status"><div class="fa fa-times-circle failure fa-fw" aria-hidden="true"></div></div>
{% endif %}
{{ item }}: {{ count }}
</div>
{% endfor %}
{% else %}
<div class="result">
<div class="status"><div class="fa fa-times-circle failure fa-fw" aria-hidden="true"></div></div>
{{ member_name }} has not bought any products in the list
</div>
{% endif %}
{% else %}
<div class="result">
<div class="status"><div class="fa fa-times-circle failure fa-fw" aria-hidden="true"></div></div>
"{{ username }}" not found
</div>
{% endif %}

{% endif %}

{% endblock %}

{% block drunkard_present %}
fa-exclamation-triangle
{% if drunkard %} checked in within the previous hour, wait {{ remaining_time }}{% endif %}
{% endblock %}

37 changes: 19 additions & 18 deletions stregsystem/templates/admin/stregsystem/razzia/foobar.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,29 @@
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Hjem</a>&nbsp;&rsaquo;&nbsp;<a href="../../../">Stregsystem</a>&nbsp;&rsaquo;&nbsp;<a href="../">Foobar razzia</a></div>{% endblock %}

{% block member_present %}
<div class="status">
{% if drunkard %}
<script>
// fade/flash background color to more easily notify foobar crew
let ofs = 0;
let el = document.body;
window.setInterval(function(){
el.style.background = 'rgba(255,255,0,'+Math.abs(Math.sin(ofs))+')';
ofs += 0.02;
}, 10);
</script>
<div class="result">
<div class="status">
{% if drunkard %}
<script>
// fade/flash background color to more easily notify foobar crew
let ofs = 0;
let el = document.body;
window.setInterval(function(){
el.style.background = 'rgba(255,255,0,'+Math.abs(Math.sin(ofs))+')';
ofs += 0.02;
}, 10);
</script>
<div class="fa fa-exclamation-triangle failure" aria-hidden="true"></div>
{% else %}
{% else %}
<div class="fa {% if already_used %} fa-exclamation-circle sucess {% else %} fa-check-circle sucess {% endif %}" aria-hidden="true"></div>
{% endif %}
</div>
{% if drunkard %}
{{member.firstname}} {{member.lastname}} ({{member.username}}) <b>wait {{ remaining_time_mins }}m {{ remaining_time_secs }}s </b> before next free beer
{% else %}
{{member.firstname}} {{member.lastname}} ({{member.username}}) {% if already_checked_in %} last checked in at {{last_entry.time}} {% endif %}
{% endif %}
</div>
{% if drunkard %}
{{member.firstname}} {{member.lastname}} ({{member.username}}) <b>wait {{ remaining_time_mins }}m {{ remaining_time_secs }}s </b> before next free beer
{% else %}
{{member.firstname}} {{member.lastname}} ({{member.username}}) {% if already_checked_in %} last checked in at {{last_entry.time}} {% endif %}
{% endif %}

{% endblock %}

{% block drunkard_present %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ <h1>{{title|default:"Razzia"}}!</h1>
<a class="fember-link" href="./members">View registered fembers</a>
</div>
{% if queryname %}
<div id="result" class="result">
{% if member %}
{% block member_present %}{% endblock %}
{% else %}
{% block member_not_present %}
<div class="status">
<div class="fa fa-times-circle failure" aria-hidden="true"></div></div>
{{queryname}} is not a fember!!!
<div class="result">
<div class="status">
<div class="fa fa-times-circle failure" aria-hidden="true"></div></div>
{{queryname}} is not a fember!!!
</div>
{% endblock %}
{% endif %}
</div>
{% endif %}
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ <h1>{{ razzia_title }}</h1>
{% if username %}
{% if member_name %}
{% if items_bought %}
<div id="result" class="result">
<div class="result">
<div class="status"><div class="fa fa-user sucess fa-fw" aria-hidden="true"></div></div>
Bruger: {{ member_name }}
</div>
{% for item, count in items_bought %}
<div id="result" class="result">
<div class="result">
{% if count > 0 %}
<div class="status"><div class="fa fa-check-circle sucess fa-fw" aria-hidden="true"></div></div>
{% else %}
Expand All @@ -50,7 +50,7 @@ <h1>{{ razzia_title }}</h1>
{{ member_name }} has not bought any products in the list
{% endif %}
{% else %}
<div id="result" class="result">
<div class="result">
<div class="status"><div class="fa fa-times-circle failure fa-fw" aria-hidden="true"></div></div>
"{{ username }}" not found
</div>
Expand Down

0 comments on commit 85b33b5

Please sign in to comment.