Skip to content

Commit

Permalink
Add start of status screen and add new picked up button
Browse files Browse the repository at this point in the history
  • Loading branch information
KiOui committed Mar 10, 2024
1 parent cfea329 commit 76be4b4
Show file tree
Hide file tree
Showing 12 changed files with 334 additions and 102 deletions.
14 changes: 13 additions & 1 deletion website/orders/api/v1/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,22 @@ class Meta:
"ready_at",
"paid",
"paid_at",
"picked_up",
"picked_up_at",
"type",
"priority",
]
read_only_fields = ["id", "created", "user", "product", "order_price", "ready_at", "paid_at"]
read_only_fields = [
"id",
"created",
"user",
"product",
"order_price",
"ready_at",
"paid_at",
"picked_up_at",
"prioritize",
]


class ShiftSerializer(WritableModelSerializer):
Expand Down
4 changes: 3 additions & 1 deletion website/orders/api/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def perform_create(self, serializer):
# Save the order while ignoring the order_type, user, paid and ready argument as the user does not have
# permissions to save orders for all users in the shift.
order = serializer.save(
shift=shift, type=Order.TYPE_ORDERED, user=self.request.user, paid=False, ready=False
shift=shift, type=Order.TYPE_ORDERED, user=self.request.user, paid=False, ready=False, picked_up=False
)
log_action(self.request.user, order, CHANGE, "Created order via API.")

Expand Down Expand Up @@ -108,6 +108,8 @@ class OrderRetrieveUpdateDestroyAPIView(LoggedRetrieveUpdateDestroyAPIView):
"ready": {"type": "boolean"},
"paid": {"type": "boolean"},
"priority": {"type": "number"},
"picked_up": {"type": "boolean"},
"deprioritize": {"type": "boolean"},
},
}
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 4.2.4 on 2023-11-12 09:32

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("orders", "0007_order_deprioritize"),
]

operations = [
migrations.AddField(
model_name="order",
name="picked_up",
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name="order",
name="picked_up_at",
field=models.DateTimeField(blank=True, null=True),
),
migrations.AlterField(
model_name="order",
name="picked_up",
field=models.BooleanField(default=False),
),
]
21 changes: 18 additions & 3 deletions website/orders/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,9 @@ def _clean(self):
elif old_instance is not None and not old_instance.finalized and self.finalized:
# Shift was not finalized yet but will be made finalized now
if not self.shift_done:
raise ValidationError({"finalized": "Shift can't be finalized if not all Orders are paid and ready"})
raise ValidationError(
{"finalized": "Shift can't be finalized if not all Orders are paid, ready and picked up."}
)

if self.end <= self.start:
raise ValidationError({"end": "End date cannot be before start date."})
Expand Down Expand Up @@ -545,7 +547,10 @@ class Order(models.Model):
paid = models.BooleanField(default=False)
paid_at = models.DateTimeField(null=True, blank=True)

type = models.PositiveIntegerField(choices=TYPES, default=TYPE_ORDERED)
picked_up = models.BooleanField(default=False)
picked_up_at = models.DateTimeField(null=True, blank=True)

type = models.PositiveIntegerField(choices=TYPES, default=0)

priority = models.PositiveIntegerField(choices=PRIORITIES, default=PRIORITY_NORMAL)

Expand Down Expand Up @@ -587,12 +592,22 @@ def venue(self):
"""
return self.shift.venue

@property
def completed(self) -> bool:
"""
Check if an Order is completed.
:return: True if this Order is paid, ready and picked up, False otherwise.
:rtype: boolean
"""
return self.paid and self.ready and self.picked_up

@property
def done(self):
"""
Check if an Order is done.
:return: True if this Order is paid and ready, False otherwise
:return: True if this Order is paid, ready and picked up, False otherwise
:rtype: boolean
"""
return self.paid and self.ready
Expand Down
16 changes: 14 additions & 2 deletions website/orders/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,15 @@ def execute_data_minimisation(dry_run=False):
return users


def add_scanned_order(product: Product, shift: Shift, ready=True, paid=True) -> Order:
def add_scanned_order(product: Product, shift: Shift, ready=True, paid=True, picked_up=True) -> Order:
"""
Add a single Scanned Order (of type TYPE_SCANNED).
:param product: A Product for which an Order has to be created
:param shift: The shift for which the Orders have to be created
:param ready: Whether the Order should be directly made ready
:param paid: Whether the Order should be directly made paid
:param picked_up: Whether the Order should be directly made picked up
:return: The created Order
"""
# Check if Shift is not finalized
Expand All @@ -79,7 +80,14 @@ def add_scanned_order(product: Product, shift: Shift, ready=True, paid=True) ->
raise OrderException("This Product is not available in this Shift")

return Order.objects.create(
product=product, shift=shift, type=Order.TYPE_SCANNED, user=None, user_association=None, ready=ready, paid=paid
product=product,
shift=shift,
type=Order.TYPE_SCANNED,
user=None,
user_association=None,
ready=ready,
paid=paid,
picked_up=picked_up,
)


Expand All @@ -90,6 +98,7 @@ def add_user_order(
priority: int = Order.PRIORITY_NORMAL,
paid: bool = False,
ready: bool = False,
picked_up: bool = False,
**kwargs,
) -> Order:
"""
Expand All @@ -101,6 +110,7 @@ def add_user_order(
:param priority: Which priority the Order should have
:param paid: Whether the order should be set as paid
:param ready: Whether the order should be set as ready
:param picked_up: Whether the order should be set as picked up
:return: The created Order
"""
# Check order permissions
Expand Down Expand Up @@ -147,6 +157,8 @@ def add_user_order(
paid=paid,
ready=ready,
priority=priority,
picked_up=picked_up,
priority=priority,
)


Expand Down
44 changes: 42 additions & 2 deletions website/orders/templates/orders/order_admin_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,20 @@ <h3 class="mt-3">Orders total</h3>
});
return orders_ready;
},
orders_picked_up() {
return this.orders.filter(order => order.picked_up);
},
orders_picked_up_grouped() {
let orders_picked_up = {};
this.orders_picked_up.forEach(order => {
if (order.product.name in orders_picked_up) {
orders_picked_up[order.product.name].amount += 1;
} else {
orders_picked_up[order.product.name] = {"product": order.product, "amount": 1};
}
});
return orders_picked_up;
},
orders_grouped() {
let orders_total = {};
this.orders.forEach(order => {
Expand All @@ -232,10 +246,10 @@ <h3 class="mt-3">Orders total</h3>
return orders_total;
},
orders_finished() {
return this.orders.filter(order => order.ready && order.paid && order.type !== 1);
return this.orders.filter(order => order.ready && order.paid && order.picked_up && order.type !== 1);
},
orders_to_process() {
return this.orders.filter(order => !order.ready || !order.paid && order.type !== 1);
return this.orders.filter(order => !order.ready || !order.picked_up || !order.paid && order.type !== 1);
},
orders_scanned() {
return this.orders.filter(order => order.type === 1);
Expand Down Expand Up @@ -378,6 +392,32 @@ <h3 class="mt-3">Orders total</h3>
}
}).catch(error => show_error_from_api(error));
},
toggle_picked_up(order) {
fetch(
`/api/v1/shifts/{{ shift.id }}/orders/${order.id}/`,
{
method: 'PATCH',
headers: {
"X-CSRFToken": get_csrf_token(),
"Accept": 'application/json',
"Content-Type": 'application/json',
},
body: JSON.stringify({
picked_up: !order.picked_up
})
}
).then(response => {
if (response.status === 200) {
return response;
} else {
throw response;
}
}).then(() => {
if (typeof (update_refresh_list) !== 'undefined') {
update_refresh_list();
}
}).catch(error => show_error_from_api(error));
},
delete_order(order) {
if (window.confirm('Do you want to delete this order?')) {
fetch(
Expand Down
51 changes: 29 additions & 22 deletions website/orders/templates/orders/order_admin_order.html
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
<ul class="row w-100">
<div class="col-auto col-lg-4 d-inline-flex">
<div class="col d-inline-flex">
<p class="item-counter">${ index + 1 }$.</p>
<p class="item-name">${ order.product.name }$ (€${ (Math.round(order.order_price * 100) /
100).toFixed(2) }$)</p>
<i v-if="order.product.icon !== null" :class="`fa-solid fa-${order.product.icon} item-icon`"></i>
</div>
<div class="col col-lg-5 d-inline-flex" style="min-width: 0">
<div class="ms-auto"></div>
<p v-if="order.user !== null" class="text-truncate" style="min-width: 0">
<i v-if="order.user !== null && {{ user.id }} === order.user.id"
class="fa-solid fa-user fa-xs"></i>
${ order.user.first_name }$ ${ order.user.last_name }$
</p>
<i v-if="order.user !== null && {{ user.id }} === order.user.id && order.deprioritize === false"
class="fa-solid fa-arrow-down-short-wide" style="font-size: 1.2em; cursor: pointer;" v-on:click="order_to_bottom_of_list(order)"></i>
<p><a target="_blank" :href="`{% url 'admin:orders_order_changelist' %}${order.id}/change/`"><i class="fa-solid fa-pen-to-square fa-xs text-white"></i></a></p>
</div>
<div v-if="!shift.finalized" class="col-12 col-lg-3 d-inline-flex gap-2">
<button v-if="order.paid" type="button" class="checkbox-paid btn col btn-success"
v-on:click="toggle_paid(order)">Paid <i class="fa-regular fa-circle-check"></i></button>
<button v-else type="button" class="checkbox-paid btn col btn-danger"
v-on:click="toggle_paid(order)">Paid <i class="fa-regular fa-circle-xmark"></i></button>

<button v-if="order.ready" type="button" class="checkbox-ready btn col btn-success"
v-on:click="toggle_ready(order)">Ready <i class="fa-regular fa-circle-check"></i></button>
<button v-else type="button" class="checkbox-ready btn col btn-danger"
v-on:click="toggle_ready(order)">Ready <i class="fa-regular fa-circle-xmark"></i></button>
<div class="col-lg-5">
<div class="row">
<div class="col d-inline-flex">
<div class="ms-auto"></div>
<p v-if="order.user !== null" class="text-truncate" style="min-width: 0">
<i v-if="order.user !== null && {{ user.id }} === order.user.id"
class="fa-solid fa-user fa-xs"></i>
${ order.user.first_name }$ ${ order.user.last_name }$
</p>
<p><a target="_blank" :href="`{% url 'admin:orders_order_changelist' %}${order.id}/change/`"><i class="fa-solid fa-pen-to-square fa-xs text-white"></i></a></p>
</div>
</div>
<div v-if="!shift.finalized" class="row">
<div class="col d-inline-flex gap-2">
<button v-if="order.paid" type="button" class="checkbox-paid btn col btn-success"
v-on:click="toggle_paid(order)">Paid <i class="fa-regular fa-circle-check"></i></button>
<button v-else type="button" class="checkbox-paid btn col btn-danger"
v-on:click="toggle_paid(order)">Paid <i class="fa-regular fa-circle-xmark"></i></button>
<button v-if="order.ready" type="button" class="checkbox-ready btn col btn-success"
v-on:click="toggle_ready(order)">Ready <i class="fa-regular fa-circle-check"></i></button>
<button v-else type="button" class="checkbox-ready btn col btn-danger"
v-on:click="toggle_ready(order)">Ready <i class="fa-regular fa-circle-xmark"></i></button>
<button v-if="order.picked_up" type="button" class="checkbox-picked-up btn col btn-success"
v-on:click="toggle_picked_up(order)">Picked up <i class="fa-regular fa-circle-check"></i></button>
<button v-else type="button" class="checkbox-picked-up btn col btn-danger"
v-on:click="toggle_picked_up(order)">Picked up <i class="fa-regular fa-circle-xmark"></i></button>
</div>
</div>
</div>
</ul>
Loading

0 comments on commit 76be4b4

Please sign in to comment.