Refactor order creation and add configuration endpoints

Refactored order creation logic to use new serializers and transaction handling, improving validation and modularity. Introduced admin and public endpoints for shop configuration with sensitive fields protected. Enhanced Zásilkovna (Packeta) integration, including packet widget template, new API fields, and improved error handling. Added django-silk for profiling, updated requirements and settings, and improved frontend Orval config for API client generation.
This commit is contained in:
David Bruno Vontor
2025-12-08 18:19:20 +01:00
parent 5b066e2770
commit 946f86db7e
18 changed files with 606 additions and 309 deletions

View File

@@ -34,23 +34,23 @@ class ZasilkovnaPacket(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
class STATE(models.TextChoices):
PENDING = "PENDING", "Podáno"
SENDED = "SENDED", "Odesláno"
ARRIVED = "ARRIVED", "Doručeno"
CANCELED = "CANCELED", "Zrušeno"
WAITING_FOR_ORDER = "WAITING_FOR_ORDERING_SHIPMENT", "cz#Čeká na objednání zásilkovny"
PENDING = "PENDING", "cz#Podáno"
SENDED = "SENDED", "cz#Odesláno"
ARRIVED = "ARRIVED", "cz#Doručeno"
CANCELED = "CANCELED", "cz#Zrušeno"
RETURNING = "RETURNING", "Posláno zpátky"
RETURNED = "RETURNED", "Vráceno"
RETURNING = "RETURNING", "cz#Posláno zpátky"
RETURNED = "RETURNED", "cz#Vráceno"
state = models.CharField(max_length=20, choices=STATE.choices, default=STATE.PENDING)
# ------- API -------
#TODO: změnit na nastavení adresy eshopu/obchodu z modelu konfigurace
# https://client.packeta.com/cs/senders (admin rozhraní)
addressId = models.IntegerField(help_text="ID adresy, v Widgetu zásilkovny který si vybere uživatel.")
addressId = models.IntegerField(null=True, blank=True, help_text="ID adresy/pointu, ve Widgetu zásilkovny který si vybere uživatel.")
packet_id = models.IntegerField(help_text="Číslo zásilky v Packetě (api)")
barcode = models.CharField(max_length=64, help_text="Čárový kód zásilky v Packetě")
packet_id = models.IntegerField(null=True, blank=True, help_text="Číslo zásilky v Packetě (vraceno od API od Packety)")
barcode = models.CharField(null=True, blank=True, max_length=64, help_text="Čárový kód zásilky od Packety")
weight = models.IntegerField(
default=0,
@@ -61,6 +61,7 @@ class ZasilkovnaPacket(models.Model):
return_routing = models.JSONField(
default=list,
blank=True,
null=True,
help_text="Seznam 2 routing stringů pro vrácení zásilky"
)
@@ -73,7 +74,13 @@ class ZasilkovnaPacket(models.Model):
size_of_pdf = models.CharField(max_length=20, choices=PDF_SIZE.choices, default=PDF_SIZE.A6_ON_A6)
def save(self, *args, **kwargs):
# workaroud to avoid circular import
return super().save(args, **kwargs)
def order_shippment(self):
if self.addressId is None:
raise ValidationError("AddressId must be set to order shipping.")
Carrier = apps.get_model('commerce', 'Carrier')
Order = apps.get_model('commerce', 'Order')
@@ -84,26 +91,27 @@ class ZasilkovnaPacket(models.Model):
if not self.packet_id:
response = packeta_client.create_packet(
address_id=self.addressId,
addressId=self.addressId, # ID z widgetu
weight=self.weight,
number=order.id,
name=order.first_name,
surname=order.last_name,
company=order.company,
email=order.email,
addressId=ShopConfiguration.get_solo().zasilkovna_address_id,
cod=order.total_price if cash_on_delivery else 0, # dobírka
value=order.total_price,
currency=ShopConfiguration.get_solo().currency,
currency=ShopConfiguration.get_solo().currency, #CZK
eshop= ShopConfiguration.get_solo().name,
)
self.packet_id = response['packet_id']
self.barcode = response['barcode']
else:
raise ValidationError("Přeprava už byla objednana!!!.")
return super().save(args, **kwargs)
return self.save()
def cancel_packet(self):
"""Cancel this packet via the Packeta API."""
packeta_client.cancel_packet(self.packet_id)