diff --git a/FRONTEND/fastparking/fastparking/settings.py b/FRONTEND/fastparking/fastparking/settings.py index 994814e8..39a7e32e 100644 --- a/FRONTEND/fastparking/fastparking/settings.py +++ b/FRONTEND/fastparking/fastparking/settings.py @@ -79,6 +79,8 @@ ] AUTH_USER_MODEL = "users.CustomUser" +PARKING_SPACES_COUNT = 100 + MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", diff --git a/FRONTEND/fastparking/parking/forms.py b/FRONTEND/fastparking/parking/forms.py new file mode 100644 index 00000000..6d8c5e58 --- /dev/null +++ b/FRONTEND/fastparking/parking/forms.py @@ -0,0 +1,12 @@ +from django import forms +from .models import Registration + +class RegistrationForm(forms.ModelForm): + class Meta: + model = Registration + fields = ['parking', 'car_number_in', 'car'] + + def clean(self): + cleaned_data = super().clean() + # Додайте власні перевірки, якщо потрібно + return cleaned_data diff --git a/FRONTEND/fastparking/parking/migrations/0003_remove_parkingspace_registration_id_and_more.py b/FRONTEND/fastparking/parking/migrations/0003_remove_parkingspace_registration_id_and_more.py new file mode 100644 index 00000000..75346847 --- /dev/null +++ b/FRONTEND/fastparking/parking/migrations/0003_remove_parkingspace_registration_id_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 5.0.4 on 2024-04-15 09:56 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('parking', '0002_remove_parkingspace_user_remove_registration_payment_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='parkingspace', + name='registration_id', + ), + migrations.AddField( + model_name='parkingspace', + name='reserved', + field=models.BooleanField(default=False), + ), + ] diff --git a/FRONTEND/fastparking/parking/migrations/0004_entryregistration_exitregistration_and_more.py b/FRONTEND/fastparking/parking/migrations/0004_entryregistration_exitregistration_and_more.py new file mode 100644 index 00000000..3afc5f13 --- /dev/null +++ b/FRONTEND/fastparking/parking/migrations/0004_entryregistration_exitregistration_and_more.py @@ -0,0 +1,41 @@ +# Generated by Django 5.0.4 on 2024-04-15 12:36 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('parking', '0003_remove_parkingspace_registration_id_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='EntryRegistration', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('entry_datetime', models.DateTimeField(auto_now_add=True)), + ('car_number_in', models.CharField(max_length=16)), + ('parking', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='parking.parkingspace')), + ], + ), + migrations.CreateModel( + name='ExitRegistration', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('exit_datetime', models.DateTimeField()), + ('car_number_out', models.CharField(max_length=16)), + ('entry_registration', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='parking.entryregistration')), + ('parking', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='parking.parkingspace')), + ], + ), + migrations.CreateModel( + name='CombinedRegistration', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('entry_registration', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='parking.entryregistration')), + ('exit_registration', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='parking.exitregistration')), + ], + ), + ] diff --git a/FRONTEND/fastparking/parking/templates/parking/base.html b/FRONTEND/fastparking/parking/templates/parking/base.html index 4e4434bc..20acdca7 100644 --- a/FRONTEND/fastparking/parking/templates/parking/base.html +++ b/FRONTEND/fastparking/parking/templates/parking/base.html @@ -44,6 +44,10 @@

Sidebars examples

Accounts + + + Registration +
  • diff --git a/FRONTEND/fastparking/parking/templates/parking/index.html b/FRONTEND/fastparking/parking/templates/parking/index.html index 30335479..adfefa04 100644 --- a/FRONTEND/fastparking/parking/templates/parking/index.html +++ b/FRONTEND/fastparking/parking/templates/parking/index.html @@ -4,9 +4,13 @@

    Fast Parking

    -

    Швидка паркова

    +

    Швидка паркова

    diff --git a/FRONTEND/fastparking/parking/templates/parking/parking_plan.html b/FRONTEND/fastparking/parking/templates/parking/parking_plan.html new file mode 100644 index 00000000..f6ee8c3f --- /dev/null +++ b/FRONTEND/fastparking/parking/templates/parking/parking_plan.html @@ -0,0 +1,29 @@ + + + + + + План парковки + + + + {% for row in parking_rows %} +
    + {% for space in row %} +
    + {% endfor %} +
    + {% endfor %} + + diff --git a/FRONTEND/fastparking/parking/templates/parking/registration_list.html b/FRONTEND/fastparking/parking/templates/parking/registration_list.html new file mode 100644 index 00000000..c4379a1a --- /dev/null +++ b/FRONTEND/fastparking/parking/templates/parking/registration_list.html @@ -0,0 +1,35 @@ + + + + + + Combined Registration List + + +

    Combined Registration List

    + + + + + + + + + + + + + {% for combined_registration in combined_registrations %} + + + + + + + + + {% endfor %} + +
    Registration IDParking SpaceEntry DatetimeExit DatetimeCar Number InCar Number Out
    {{ combined_registration.id }}{{ combined_registration.entry_registration.parking }}{{ combined_registration.entry_registration.entry_datetime }}{{ combined_registration.exit_registration.exit_datetime }}{{ combined_registration.entry_registration.car_number_in }}{{ combined_registration.exit_registration.car_number_out }}
    + + diff --git a/FRONTEND/fastparking/parking/urls.py b/FRONTEND/fastparking/parking/urls.py index 24c69a9e..4b36733e 100644 --- a/FRONTEND/fastparking/parking/urls.py +++ b/FRONTEND/fastparking/parking/urls.py @@ -5,5 +5,8 @@ urlpatterns = [ path('', views.main, name='main'), - + path('parking_plan/', views.parking_plan_view, name='parking_plan'), + path('registration/', views.registration_list, name='registration_list'), + ] + diff --git a/FRONTEND/fastparking/parking/views.py b/FRONTEND/fastparking/parking/views.py index 8885eabe..fed4e076 100644 --- a/FRONTEND/fastparking/parking/views.py +++ b/FRONTEND/fastparking/parking/views.py @@ -1,28 +1,94 @@ -from django.shortcuts import render - -# Create your views here. - +from django.shortcuts import render, redirect +from .models import ParkingSpace +from django.conf import settings +from django.utils import timezone +from .models import Registration +from .models import ParkingSpace def main(request): + total_parking_spaces = settings.PARKING_SPACES_COUNT + occupied_parking_spaces = ParkingSpace.objects.filter(status=True).count() + free_parking_spaces = total_parking_spaces - occupied_parking_spaces + active_menu = "home" return render( request, "parking/index.html", - {"title": "Fast Parking", "active_menu": active_menu}, + { + "title": "Fast Parking", + "active_menu": active_menu, + "total_parking_spaces": total_parking_spaces, + "free_parking_spaces": free_parking_spaces, + }, ) -from parking.models import Registration -# from .models import Sessions - def generate_report(request): user = request.user entry_datetime = request.GET.get('start_date') exit_datetime = request.GET.get('end_date') car = car - # entries = Sessions.objects.all()[:10] + parking_entries = Registration.objects.filter(user=user, entry_time__range=[entry_datetime, exit_datetime]) return render(request, 'accounts/report.html', {'car': car, 'start_date': entry_datetime, 'end_date': exit_datetime}) +def parking_plan_view(request): + parking_spaces = ParkingSpace.objects.all() + + # Розбиття місць на рядки + row_length = 10 # Довжина рядка (кількість місць у рядку) + parking_rows = [parking_spaces[i:i+row_length] for i in range(0, len(parking_spaces), row_length)] + + return render(request, 'parking/parking_plan.html', {'parking_rows': parking_rows}) + +def registration_list(request): + registrations = Registration.objects.all() + return render(request, 'parking/registration_list.html', {'registrations': registrations}) + + +def entry_registration(request): + if request.method == 'POST': + # Отримання даних з форми + parking_id = request.POST.get('parking_id') + car_number_in = request.POST.get('car_number_in') + + # Створення реєстрації заїзду + parking = ParkingSpace.objects.get(id=parking_id) + entry_registration = EntryRegistration.objects.create(parking=parking, car_number_in=car_number_in) + + # Перенаправлення на сторінку з реєстрацією виїзду + return redirect('exit_registration', entry_id=entry_registration.id) + + return render(request, 'entry_registration_form.html') + +def exit_registration(request, entry_id): + if request.method == 'POST': + # Отримання даних з форми + exit_datetime = timezone.now() + car_number_out = request.POST.get('car_number_out') + + # Отримання реєстрації заїзду + entry_registration = EntryRegistration.objects.get(id=entry_id) + + # Створення реєстрації виїзду + exit_registration = ExitRegistration.objects.create( + parking=entry_registration.parking, + entry_registration=entry_registration, + exit_datetime=exit_datetime, + car_number_out=car_number_out + ) + + # Створення об'єднаної реєстрації + combined_registration = CombinedRegistration.create_combined_registration(entry_registration, exit_registration) + + # Перенаправлення на іншу сторінку + return redirect('some_other_view') + + return render(request, 'exit_registration_form.html') + + +def registration_table(request): + registrations = EntryRegistration.objects.all() + return render(request, 'registration_table.html', {'registrations': registrations}) diff --git a/FRONTEND/fastparking/repository.py b/FRONTEND/fastparking/repository.py new file mode 100644 index 00000000..1fe8edc3 --- /dev/null +++ b/FRONTEND/fastparking/repository.py @@ -0,0 +1,61 @@ +# from .models import Registration +from django.core.exceptions import ObjectDoesNotExist +from django.db.models import Q +from .models import Tariff +from .services import compare_plates +from .models import Registration + + +def get_registration_instance(id: int) -> Registration | None: + try: + return Registration.objects.get(pk=id) + except ObjectDoesNotExist: + return None + + +def find_registered_plate(num_auto: str, max_results: int = 1000) -> int | None: + try: + reg = Registration.objects.get( + car_number_out__isnull=True, car_number_in__contains=num_auto + ) + if reg: + return reg.id + except Registration.DoesNotExist: + return None + + unclosed_registration = Registration.objects.filter(car_number_out__isnull=True)[ + :max_results + ] + for reg in unclosed_registration: + reg_num_auto = reg.car_number_in + result, sim = compare_plates(num_auto, reg_num_auto) + if result: + return reg.id +from .models import Payment +# from parking.repository import get_registration_instance + +def save_payment(registration_id: int, amount: float) -> Payment: + registration = get_registration_instance(registration_id) + if registration: + payment = Payment(registration=registration, amount=amount) + payment.save() + return payment + else: + raise ValueError("Registration does not exist.") + + + +def calculate_current_invoice(registration_id: int) -> float: + registration = get_registration_instance(registration_id) + if registration: + # Assuming duration is calculated somewhere + duration = 2 # Placeholder for duration calculation + tariff = Tariff.objects.first() # Placeholder for fetching current tariff + if tariff: + price_per_hour = tariff.price_per_hour + result = duration * price_per_hour + return result + else: + raise ValueError("No tariff found.") + else: + raise ValueError("Registration does not exist.") \ No newline at end of file diff --git a/FRONTEND/fastparking/users/models.py b/FRONTEND/fastparking/users/models.py index 2aa6ae2c..32e2875f 100644 --- a/FRONTEND/fastparking/users/models.py +++ b/FRONTEND/fastparking/users/models.py @@ -7,7 +7,7 @@ class CustomUser(AbstractUser): # cars = models.TextField(blank=True, null=True) - telegram_nickname = models.CharField(max_length=20, blank=True, null=True) + telegram_nickname = models.CharField(max_length=20, unique=True, blank=True, null=True) phone_number = models.CharField(max_length=20, blank=True, null=True) telegram_id = models.CharField(max_length=50, blank=True, null=True) cars = models.ManyToManyField(Car, related_name='owners', blank=True) # Додано поле багато-до-багатьох для прив'язки автомобілів до користувача