Skip to content

Commit

Permalink
Merge pull request #959 from ae-utbm/counter-click-step-4
Browse files Browse the repository at this point in the history
Make counter click client side first
  • Loading branch information
klmp200 authored Dec 27, 2024
2 parents 4b88190 + 43f47e2 commit 11702d3
Show file tree
Hide file tree
Showing 21 changed files with 1,460 additions and 881 deletions.
8 changes: 0 additions & 8 deletions core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -578,14 +578,6 @@ def get_display_name(self) -> str:
return "%s (%s)" % (self.get_full_name(), self.nick_name)
return self.get_full_name()

def get_age(self):
"""Returns the age."""
today = timezone.now()
born = self.date_of_birth
return (
today.year - born.year - ((today.month, today.day) < (born.month, born.day))
)

def get_family(
self,
godfathers_depth: NonNegativeInt = 4,
Expand Down
43 changes: 8 additions & 35 deletions core/static/core/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ body {
a.btn {
display: inline-block;
}

.btn {
font-size: 15px;
font-weight: normal;
Expand Down Expand Up @@ -336,7 +337,8 @@ body {
margin-left: -125px;
box-sizing: border-box;
position: fixed;
z-index: 1;
z-index: 10;
/* to get on top of tomselect */
left: 50%;
top: 60px;
text-align: center;
Expand Down Expand Up @@ -431,12 +433,17 @@ body {
flex-wrap: wrap;

$col-gap: 1rem;
$row-gap: 0.5rem;

&.gap {
column-gap: var($col-gap);
row-gap: var($row-gap);
}

@for $i from 2 through 5 {
&.gap-#{$i}x {
column-gap: $i * $col-gap;
row-gap: $i * $row-gap;
}
}
}
Expand Down Expand Up @@ -1242,40 +1249,6 @@ u,
text-decoration: underline;
}

#bar-ui {
padding: 0.4em;
display: flex;
flex-wrap: wrap;
flex-direction: row-reverse;

#products {
flex-basis: 100%;
margin: 0.2em;
overflow: auto;
}

#click_form {
flex: auto;
margin: 0.2em;
}

#user_info {
flex: auto;
padding: 0.5em;
margin: 0.2em;
height: 100%;
background: $secondary-neutral-light-color;

img {
max-width: 70%;
}

input {
background: white;
}
}
}

/*-----------------------------USER PROFILE----------------------------*/

.user_mini_profile {
Expand Down
2 changes: 1 addition & 1 deletion core/templates/core/macros.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
{% endif %}
{% if user.date_of_birth %}
<div class="user_mini_profile_dob">
{{ user.date_of_birth|date("d/m/Y") }} ({{ user.get_age() }})
{{ user.date_of_birth|date("d/m/Y") }} ({{ user.age }})
</div>
{% endif %}
</div>
Expand Down
19 changes: 10 additions & 9 deletions counter/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def as_p(self):

def clean(self):
cleaned_data = super().clean()
cus = None
customer = None
if cleaned_data["code"] != "":
if len(cleaned_data["code"]) == StudentCard.UID_SIZE:
card = (
Expand All @@ -96,17 +96,18 @@ def clean(self):
.first()
)
if card is not None:
cus = card.customer
if cus is None:
cus = Customer.objects.filter(
customer = card.customer
if customer is None:
customer = Customer.objects.filter(
account_id__iexact=cleaned_data["code"]
).first()
elif cleaned_data["id"] is not None:
cus = Customer.objects.filter(user=cleaned_data["id"]).first()
if cus is None or not cus.can_buy:
elif cleaned_data["id"]:
customer = Customer.objects.filter(user=cleaned_data["id"]).first()

if customer is None or not customer.can_buy:
raise forms.ValidationError(_("User not found"))
cleaned_data["user_id"] = cus.user.id
cleaned_data["user"] = cus.user
cleaned_data["user_id"] = customer.user.id
cleaned_data["user"] = customer.user
return cleaned_data


Expand Down
17 changes: 17 additions & 0 deletions counter/migrations/0029_alter_selling_label.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.2.17 on 2024-12-22 22:59

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("counter", "0028_alter_producttype_comment_and_more"),
]

operations = [
migrations.AlterField(
model_name="selling",
name="label",
field=models.CharField(max_length=128, verbose_name="label"),
),
]
39 changes: 35 additions & 4 deletions counter/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from datetime import date, datetime, timedelta
from datetime import timezone as tz
from decimal import Decimal
from typing import Self, Tuple
from typing import Self

from dict2xml import dict2xml
from django.conf import settings
Expand Down Expand Up @@ -138,7 +138,7 @@ def can_buy(self) -> bool:
return (date.today() - subscription.subscription_end) < timedelta(days=90)

@classmethod
def get_or_create(cls, user: User) -> Tuple[Customer, bool]:
def get_or_create(cls, user: User) -> tuple[Customer, bool]:
"""Work in pretty much the same way as the usual get_or_create method,
but with the default field replaced by some under the hood.
Expand Down Expand Up @@ -327,6 +327,8 @@ def is_owned_by(self, user):
class Product(models.Model):
"""A product, with all its related information."""

QUANTITY_FOR_TRAY_PRICE = 6

name = models.CharField(_("name"), max_length=64)
description = models.TextField(_("description"), default="")
product_type = models.ForeignKey(
Expand Down Expand Up @@ -525,7 +527,7 @@ def is_owned_by(self, user: User) -> bool:
if user.is_anonymous:
return False
mem = self.club.get_membership_for(user)
if mem and mem.role >= 7:
if mem and mem.role >= settings.SITH_CLUB_ROLES_ID["Treasurer"]:
return True
return user.is_in_group(pk=settings.SITH_GROUP_COUNTER_ADMIN_ID)

Expand Down Expand Up @@ -657,6 +659,34 @@ def customer_is_barman(self, customer: Customer | User) -> bool:
# but they share the same primary key
return self.type == "BAR" and any(b.pk == customer.pk for b in self.barmen_list)

def get_products_for(self, customer: Customer) -> list[Product]:
"""
Get all allowed products for the provided customer on this counter
Prices will be annotated
"""

products = self.products.select_related("product_type").prefetch_related(
"buying_groups"
)

# Only include age appropriate products
age = customer.user.age
if customer.user.is_banned_alcohol:
age = min(age, 17)
products = products.filter(limit_age__lte=age)

# Compute special price for customer if he is a barmen on that bar
if self.customer_is_barman(customer):
products = products.annotate(price=F("special_selling_price"))
else:
products = products.annotate(price=F("selling_price"))

return [
product
for product in products.all()
if product.can_be_sold_to(customer.user)
]


class RefillingQuerySet(models.QuerySet):
def annotate_total(self) -> Self:
Expand Down Expand Up @@ -761,7 +791,8 @@ def annotate_total(self) -> Self:
class Selling(models.Model):
"""Handle the sellings."""

label = models.CharField(_("label"), max_length=64)
# We make sure that sellings have a way begger label than any product name is allowed to
label = models.CharField(_("label"), max_length=128)
product = models.ForeignKey(
Product,
related_name="sellings",
Expand Down
25 changes: 25 additions & 0 deletions counter/static/bundled/counter/basket.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { Product } from "#counter:counter/types";

export class BasketItem {
quantity: number;
product: Product;
quantityForTrayPrice: number;
errors: string[];

constructor(product: Product, quantity: number) {
this.quantity = quantity;
this.product = product;
this.errors = [];
}

getBonusQuantity(): number {
if (!this.product.hasTrayPrice) {
return 0;
}
return Math.floor(this.quantity / this.product.quantityForTrayPrice);
}

sum(): number {
return (this.quantity - this.getBonusQuantity()) * this.product.price;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export class CounterProductSelect extends AutoCompleteSelectBase {
return ["FIN", "ANN"];
}

public getSelectedProduct(): [number, string] {
return parseProduct(this.widget.getValue() as string);
}

protected attachBehaviors(): void {
this.allowMultipleProducts();
}
Expand Down
Loading

0 comments on commit 11702d3

Please sign in to comment.