Refactor frontend components and backend migrations

- Removed TradingGraph component from frontend/src/components/trading.
- Updated home page to import Services component and TradingGraph from new path.
- Modified PortfolioPage to return null instead of PortfolioGrid.
- Added initial migrations for account, advertisement, commerce, configuration, downloader, gopay, stripe, trading212, and zasilkovna apps in the backend.
- Created Services component with subcomponents for Kinematografie, Drone Service, and Website Service.
- Implemented TradingGraph component with dynamic data generation and canvas rendering.
- Updated DonationShop component to display donation tiers with icons and descriptions.
This commit is contained in:
2025-12-14 03:49:16 +01:00
parent 564418501c
commit 1751badb90
40 changed files with 796 additions and 165 deletions

View File

@@ -0,0 +1,30 @@
# Generated by Django 5.2.9 on 2025-12-14 02:23
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='DownloaderRecord',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('is_deleted', models.BooleanField(default=False)),
('deleted_at', models.DateTimeField(blank=True, null=True)),
('url', models.URLField()),
('download_time', models.DateTimeField(auto_now_add=True)),
('format', models.CharField(max_length=50)),
('length_of_media', models.IntegerField(help_text='Length of media in seconds')),
('file_size', models.BigIntegerField(help_text='File size in bytes')),
],
options={
'abstract': False,
},
),
]

View File

View File

@@ -0,0 +1,63 @@
# Generated by Django 5.2.9 on 2025-12-14 02:23
import django.db.models.deletion
import django.utils.timezone
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='GoPayPayment',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('gopay_id', models.CharField(db_index=True, max_length=64, unique=True)),
('order_number', models.CharField(blank=True, default='', max_length=128)),
('amount', models.BigIntegerField(help_text='Amount in minor units (e.g., CZK in haléř).')),
('currency', models.CharField(max_length=10)),
('status', models.CharField(db_index=True, default='', max_length=64)),
('preauthorized', models.BooleanField(default=False)),
('captured_amount', models.BigIntegerField(default=0)),
('request_payload', models.JSONField(blank=True, default=dict)),
('response_payload', models.JSONField(blank=True, default=dict)),
('created_at', models.DateTimeField(db_index=True, default=django.utils.timezone.now)),
('updated_at', models.DateTimeField(auto_now=True)),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='gopay_payments', to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='GoPayRefund',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('gopay_refund_id', models.CharField(blank=True, default='', max_length=64)),
('amount', models.BigIntegerField(help_text='Amount in minor units.')),
('status', models.CharField(blank=True, default='', max_length=64)),
('payload', models.JSONField(blank=True, default=dict)),
('created_at', models.DateTimeField(db_index=True, default=django.utils.timezone.now)),
('payment', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='refunds', to='gopay.gopaypayment')),
],
),
migrations.CreateModel(
name='GoPaySubscription',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('recurrence_id', models.CharField(blank=True, default='', max_length=64)),
('status', models.CharField(blank=True, default='', max_length=64)),
('interval', models.CharField(blank=True, default='', max_length=64)),
('next_payment_on', models.DateTimeField(blank=True, null=True)),
('payload', models.JSONField(blank=True, default=dict)),
('canceled', models.BooleanField(default=False)),
('canceled_at', models.DateTimeField(blank=True, null=True)),
('created_at', models.DateTimeField(db_index=True, default=django.utils.timezone.now)),
('parent_payment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subscriptions', to='gopay.gopaypayment')),
],
),
]

View File

View File

@@ -0,0 +1,26 @@
# Generated by Django 5.2.9 on 2025-12-14 02:23
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='StripeModel',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('status', models.CharField(choices=[('pending', 'cz#Čeká se na platbu'), ('paid', 'cz#Zaplaceno'), ('failed', 'cz#Neúspěšné'), ('cancelled', 'cz#Zrušeno'), ('refunding', 'cz#Platba se vrací'), ('refunded', 'cz#Platba úspěšně vrácena')], default='pending', max_length=20)),
('stripe_session_id', models.CharField(blank=True, max_length=255, null=True)),
('stripe_payment_intent', models.CharField(blank=True, max_length=255, null=True)),
('stripe_session_url', models.URLField(blank=True, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True, null=True)),
],
),
]

View File

View File

@@ -1,6 +1,6 @@
from django.urls import path
from .views import CreateCheckoutSessionView
from .views import StripeWebhook
urlpatterns = [
path("orders/create-checkout/", CreateCheckoutSessionView.as_view(), name="create-checkout"),
path("stripe-webhook/", StripeWebhook.as_view(), name="stripe-webhook"),
]

View File

@@ -9,7 +9,7 @@ from drf_spectacular.utils import extend_schema
import os
import logging
from .models import StripeTransaction
from .models import StripeModel
from commerce.models import Order, Payment
logger = logging.getLogger(__name__)
@@ -48,7 +48,7 @@ class StripeWebhook(APIView):
# ZAPLACENO
if event['type'] == 'checkout.session.completed':
stripe_transaction = StripeTransaction.objects.get(stripe_session_id=session.id)
stripe_transaction = StripeModel.objects.get(stripe_session_id=session.id)
if stripe_transaction:
stripe_transaction.paid()
@@ -60,7 +60,7 @@ class StripeWebhook(APIView):
# EXPIRACE (zrušení objednávky) uživatel nezaplatil do 24 hodin!
elif event['type'] == 'checkout.session.expired':
order = Order.objects.get(payment=Payment.objects.get(stripe=StripeTransaction.objects.get(stripe_session_id=session.id)))
order = Order.objects.get(payment=Payment.objects.get(stripe=StripeModel.objects.get(stripe_session_id=session.id)))
order.status = Order.STATUS_CHOICES.CANCELLED
order.save()
@@ -71,7 +71,7 @@ class StripeWebhook(APIView):
# REFUND POTVRZEN
elif event['type'] == 'payment_intent.refunded':
session = event['data']['object']
stripe_transaction = StripeTransaction.objects.get(stripe_payment_intent=session.id)
stripe_transaction = StripeModel.objects.get(stripe_payment_intent=session.id)
if stripe_transaction:
stripe_transaction.refund_confirmed()

View File

View File

@@ -0,0 +1,39 @@
# Generated by Django 5.2.9 on 2025-12-14 02:23
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='ZasilkovnaPacket',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('state', models.CharField(choices=[('WAITING_FOR_ORDERING_SHIPMENT', 'cz#Čeká na objednání zásilkovny'), ('PENDING', 'cz#Podáno'), ('SENDED', 'cz#Odesláno'), ('ARRIVED', 'cz#Doručeno'), ('CANCELED', 'cz#Zrušeno'), ('RETURNING', 'cz#Posláno zpátky'), ('RETURNED', 'cz#Vráceno')], default='PENDING', max_length=35)),
('addressId', models.IntegerField(blank=True, help_text='ID adresy/pointu, ve Widgetu zásilkovny který si vybere uživatel.', null=True)),
('packet_id', models.IntegerField(blank=True, help_text='Číslo zásilky v Packetě (vraceno od API od Packety)', null=True)),
('barcode', models.CharField(blank=True, help_text='Čárový kód zásilky od Packety', max_length=64, null=True)),
('weight', models.IntegerField(default=0, help_text='Hmotnost zásilky v gramech')),
('return_routing', models.JSONField(blank=True, default=list, help_text='Seznam 2 routing stringů pro vrácení zásilky', null=True)),
('size_of_pdf', models.CharField(choices=[('A6 on A6', '105x148 mm (A6) label on a page of the same size'), ('A7 on A7', '105x74 mm (A7) label on a page of the same size'), ('A6 on A4', '105x148 mm (A6) label on a page of size 210x297 mm (A4)'), ('A7 on A4', '105x74 mm (A7) label on a page of size 210x297 mm (A4)'), ('A8 on A8', '50x74 mm (A8) label on a page of the same size')], default='A6 on A6', max_length=20)),
],
),
migrations.CreateModel(
name='ZasilkovnaShipment',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('shipment_id', models.CharField(editable=False, help_text='ID zásilky v Packetě', max_length=255, unique=True)),
('barcode', models.CharField(help_text='Čárový kód zásilky v Packetě (format: )', max_length=64, validators=[django.core.validators.RegexValidator('D-***-XM-<id>', message='Neplatný formát čárového kódu.')])),
('packets', models.ManyToManyField(help_text='Seznam zásilek v této zásilce (packet_id)', related_name='shipments', to='zasilkovna.zasilkovnapacket')),
],
),
]

View File

View File

@@ -43,7 +43,7 @@ class ZasilkovnaPacket(models.Model):
RETURNING = "RETURNING", "cz#Posláno zpátky"
RETURNED = "RETURNED", "cz#Vráceno"
state = models.CharField(max_length=20, choices=STATE.choices, default=STATE.PENDING)
state = models.CharField(max_length=35, choices=STATE.choices, default=STATE.PENDING)
# ------- API -------
# https://client.packeta.com/cs/senders (admin rozhraní)

View File

@@ -35,7 +35,10 @@ class TrackingURLSerializer(serializers.Serializer):
# -- SHIPMENT --
class ZasilkovnaShipmentSerializer(serializers.ModelSerializer):
packets = serializers.PrimaryKeyRelatedField(many=True)
packets = serializers.PrimaryKeyRelatedField(
many=True,
queryset=ZasilkovnaPacket.objects.all()
)
class Meta:
model = ZasilkovnaShipment

View File

@@ -5,7 +5,7 @@ from django.template import loader
from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiResponse, OpenApiParameter, OpenApiTypes
from backend.configuration.models import SiteConfiguration
from configuration.models import SiteConfiguration
from .models import ZasilkovnaShipment, ZasilkovnaPacket
from .serializers import (