Skip to content

Commit

Permalink
Merge 20240720-1
Browse files Browse the repository at this point in the history
  • Loading branch information
jlaunonen committed Jul 20, 2024
2 parents 49e3c6b + 950c881 commit d3e9559
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 33 deletions.
18 changes: 9 additions & 9 deletions constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ asgiref==3.8.1
# via django
build==1.2.1
# via pip-tools
certifi==2024.2.2
certifi==2024.7.4
# via requests
charset-normalizer==3.3.2
# via requests
click==8.1.7
# via pip-tools
coverage==7.5.3
coverage==7.6.0
# via pytest-cov
django==4.2.13
django==4.2.14
# via kirppu (pyproject.toml)
django-environ==0.11.2
# via kirppu (pyproject.toml)
Expand Down Expand Up @@ -44,18 +44,18 @@ oauthlib==3.2.2
# via
# kirppu (pyproject.toml)
# requests-oauthlib
packaging==24.0
packaging==24.1
# via
# build
# gunicorn
# pytest
pillow==10.3.0
pillow==10.4.0
# via kirppu (pyproject.toml)
pip-tools==7.4.1
# via kirppu (pyproject.toml)
pluggy==1.5.0
# via pytest
psycopg==3.1.19
psycopg==3.1.20
# via kirppu (pyproject.toml)
pubcode==1.1.0
# via kirppu (pyproject.toml)
Expand Down Expand Up @@ -85,11 +85,11 @@ requests-oauthlib==2.0.0
# via kirppu (pyproject.toml)
six==1.16.0
# via python-dateutil
sqlparse==0.5.0
sqlparse==0.5.1
# via django
typing-extensions==4.12.0
typing-extensions==4.12.2
# via psycopg
urllib3==2.2.1
urllib3==2.2.2
# via requests
wheel==0.43.0
# via pip-tools
Expand Down
39 changes: 30 additions & 9 deletions kirppu/forms.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import re

from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AbstractUser
Expand All @@ -8,6 +10,7 @@
from .fields import ItemPriceField, SuffixField, StripField
from .models import (
AccessSignup,
Box,
Clerk,
Event,
ReceiptItem,
Expand Down Expand Up @@ -312,6 +315,10 @@ def clean_receipt(self):

def clean_code(self):
data = self.cleaned_data["code"]
if box_match := re.match(r"box[_ -]?(\d+)$", data):
if not Box.objects.filter(pk=int(box_match[1])).exists():
raise forms.ValidationError("Box {} not found".format(box_match[1]))
return data
if not Item.is_item_barcode(data):
raise forms.ValidationError("Value is not an item barcode")
if not Item.objects.filter(code=data, vendor__event=self._event).exists():
Expand All @@ -320,22 +327,36 @@ def clean_code(self):


@transaction.atomic
def remove_item_from_receipt(request, item_or_code, receipt_id, update_receipt=True):
if isinstance(item_or_code, Item):
item = item_or_code
else:
item = Item.objects.select_for_update().get(code=item_or_code)

if item.state not in (Item.SOLD, Item.STAGED):
raise ValueError("Item is not sold or staged, but {}".format(item.state))

def remove_item_from_receipt(
request, item_or_code: str | Item, receipt_id: int | Receipt, update_receipt=True
):
if isinstance(receipt_id, Receipt):
receipt = receipt_id
assert receipt.type == Receipt.TYPE_PURCHASE, "This function cannot be used for non-purchase receipts."
else:
receipt = Receipt.objects.select_for_update().get(pk=receipt_id, type=Receipt.TYPE_PURCHASE)
assert update_receipt, "Receipt must be updated if accessed by id."

if isinstance(item_or_code, Item):
item = item_or_code
else:
if box_match := re.match(r"box[_ -]?(\d+)$", item_or_code):
box_number = int(box_match[1])
receipt_box_item = ReceiptItem.objects.filter(
receipt=receipt,
action=ReceiptItem.ADD,
item__box__box_number=box_number,
).order_by("-add_time")[0:1]
if not receipt_box_item:
raise ValueError("Box item not found on receipt")
item = receipt_box_item[0].item
item = Item.objects.select_for_update().get(pk=item.pk)
else:
item = Item.objects.select_for_update().get(code=item_or_code)

if item.state not in (Item.SOLD, Item.STAGED):
raise ValueError("Item is not sold or staged, but {}".format(item.state))

last_added_item = ReceiptItem.objects \
.filter(receipt=receipt, item=item, action=ReceiptItem.ADD) \
.select_for_update() \
Expand Down
2 changes: 2 additions & 0 deletions kirppu/templates/kirppu/help_lisp.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ <h2>Help for the subset of Lisp language</h2>
<h3>Examples</h3>
<h4>0.50 per sold item</h4>
<pre><code>(* 0.5 (.count sold_and_compensated))</code></pre>
<h4>5 % of sold items</h4>
<pre><code>(* 0.05 (.sumBy 'price sold_and_compensated))</code></pre>
<h4>0.50 per sold item under price of 5, and 1 per sold item of and over price of 5</h4>
<pre><code>(begin
(define under (.count (.filter sold_and_compensated '(< price 5))))
Expand Down
65 changes: 65 additions & 0 deletions kirppu/tests/test_receipt_removals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from django.test import TestCase

from . import ResultMixin

from ..models import ReceiptItem, Item, Receipt
from .factories import BoxFactory, ReceiptItemFactory, ItemFactory, UserFactory


class ReceiptRemovalTests(TestCase, ResultMixin):
def setUp(self):
self.receipt_item: ReceiptItem = ReceiptItemFactory()
self.item = self.receipt_item.item
self.item.state = Item.SOLD
self.item.save(update_fields=["state"])

vendor = self.item.vendor
self.event = vendor.event
self.receipt = self.receipt_item.receipt

self.other_item = ItemFactory(vendor=vendor, state=Item.SOLD)
self.other_receipt_item = ReceiptItemFactory(
item=self.other_item, receipt=self.receipt
)

self.receipt.calculate_total()
self.receipt.status = Receipt.FINISHED
self.receipt.save(update_fields=["status", "total"])
self.assertEqual(250, self.receipt.total_cents)

user = UserFactory(is_superuser=True, is_staff=True)
self.client.force_login(user)

def _refresh(self):
self.item.refresh_from_db()
self.other_item.refresh_from_db()
self.receipt.refresh_from_db()

def _perform(self, code: str):
data = {
"code": code,
"receipt": self.receipt.id,
}
self.assertResult(
self.client.post(f"/kirppu/{self.event.slug}/remove_item", data=data),
expect=302,
)

def test_item_removal(self):
self._perform(self.item.code)
self._refresh()

self.assertEqual(Item.BROUGHT, self.item.state)
self.assertEqual(Item.SOLD, self.other_item.state)
self.assertEqual(125, self.receipt.total_cents)

def test_box_item_removal(self):
box = BoxFactory(adopt=True, items=[self.item, self.other_item])

self._perform(f"box{box.box_number}")
self._refresh()

result_states = [self.item.state, self.other_item.state]
self.assertTrue(Item.BROUGHT in result_states)
self.assertTrue(Item.SOLD in result_states)
self.assertEqual(125, self.receipt.total_cents)
8 changes: 2 additions & 6 deletions kirppu/views/ui_text_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ def ui_text_vars(event) -> dict[str, typing.Any]:
"event.end.date": _date(event.end_date),
"event.homepage": event.home_page,
"registration.end.datetime": _datetime(event.registration_end),
"registration.end.date": _date(event.registration_end)
if event.registration_end
else "",
"registration.end.time": _time(event.registration_end)
if event.registration_end
else "",
"registration.end.date": _date(event.registration_end),
"registration.end.time": _time(event.registration_end),
}
18 changes: 9 additions & 9 deletions requirements-github.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ asgiref==3.8.1
# via django
build==1.2.1
# via pip-tools
certifi==2024.2.2
certifi==2024.7.4
# via requests
charset-normalizer==3.3.2
# via requests
click==8.1.7
# via pip-tools
coverage==7.5.3
coverage==7.6.0
# via pytest-cov
django==4.2.13
django==4.2.14
# via kirppu (pyproject.toml)
django-environ==0.11.2
# via kirppu (pyproject.toml)
Expand Down Expand Up @@ -44,18 +44,18 @@ oauthlib==3.2.2
# via
# kirppu (pyproject.toml)
# requests-oauthlib
packaging==24.0
packaging==24.1
# via
# build
# gunicorn
# pytest
pillow==10.3.0
pillow==10.4.0
# via kirppu (pyproject.toml)
pip-tools==7.4.1
# via kirppu (pyproject.toml)
pluggy==1.5.0
# via pytest
psycopg==3.1.19
psycopg==3.1.20
# via kirppu (pyproject.toml)
pubcode==1.1.0
# via kirppu (pyproject.toml)
Expand Down Expand Up @@ -85,11 +85,11 @@ requests-oauthlib==2.0.0
# via kirppu (pyproject.toml)
six==1.16.0
# via python-dateutil
sqlparse==0.5.0
sqlparse==0.5.1
# via django
typing-extensions==4.12.0
typing-extensions==4.12.2
# via psycopg
urllib3==2.2.1
urllib3==2.2.2
# via requests
wheel==0.43.0
# via pip-tools
Expand Down

0 comments on commit d3e9559

Please sign in to comment.