test

from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from .models import Randevu, BlockedDates, GenkRandevu, BrasschaatRandevu, WorkingHours, Settings

class RandevuAdmin(admin.ModelAdmin):
    list_display = ('isim', 'email', 'lokasyon', 'get_tarih_saat', 'aciklama')
    list_filter = ['lokasyon', 'tarih', 'saat']
    search_fields = ['isim', 'email']

    def get_tarih_saat(self, obj):
        return f"{obj.tarih} {obj.saat}"
    get_tarih_saat.short_description = 'Tarih ve Saat'

admin.site.register(Randevu, RandevuAdmin)

class SettingsAdmin(admin.ModelAdmin):
    list_display = ('interval',)

admin.site.register(Settings, SettingsAdmin)

class UserAdmin(BaseUserAdmin):
    list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')

class GenkRandevuAdmin(admin.ModelAdmin):
    list_display = ('isim', 'email', 'get_tarih_saat', 'aciklama')
    list_filter = ['tarih', 'saat']
    search_fields = ['isim', 'email']

    def get_tarih_saat(self, obj):
        return f"{obj.tarih} {obj.saat}"
    get_tarih_saat.short_description = 'Tarih ve Saat'

    def get_queryset(self, request):
        return super().get_queryset(request).filter(lokasyon='genk')

class BrasschaatRandevuAdmin(admin.ModelAdmin):
    list_display = ('isim', 'email', 'get_tarih_saat', 'aciklama')
    list_filter = ['tarih', 'saat']
    search_fields = ['isim', 'email']

    def get_tarih_saat(self, obj):
        return f"{obj.tarih} {obj.saat}"
    get_tarih_saat.short_description = 'Tarih ve Saat'

    def get_queryset(self, request):
        return super().get_queryset(request).filter(lokasyon='brasschaat')

@admin.register(WorkingHours)
class WorkingHoursAdmin(admin.ModelAdmin):
    list_display = ('lokasyon', 'day', 'start_time', 'end_time')
    ordering = ['lokasyon', 'day']

admin.site.unregister(User)
admin.site.register(User, UserAdmin)
admin.site.register(GenkRandevu, GenkRandevuAdmin)
admin.site.register(BrasschaatRandevu, BrasschaatRandevuAdmin)

@admin.register(BlockedDates)
class BlockedDatesAdmin(admin.ModelAdmin):
    list_display = ('date',), admin.py dosyasi, 
from django.conf import settings
from django import forms
from .models import Randevu
from django.utils.translation import gettext_lazy as _

class LanguageForm(forms.Form):
    language = forms.ChoiceField(choices=[(code, name) for code, name in settings.LANGUAGES], label=_("Dil"))

class RandevuForm(forms.ModelForm):
    isim = forms.CharField(
        label=_('İsim'),
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': _('İsim')})
    )
    email = forms.EmailField(
        label=_('E-posta'),
        widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': _('E-posta')})
    )
    telefon = forms.CharField(
        label=_('Telefon'),
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': _('Telefon')})
    )
    tarih = forms.DateField(
        label=_('Tarih'),
        widget=forms.DateInput(attrs={'class': 'form-control datepicker', 'type': 'date', 'placeholder': _('Tarih')})
    )
    saat = forms.TimeField(
        label=_('Saat'),
        widget=forms.TimeInput(attrs={'class': 'form-control timepicker', 'type': 'text', 'placeholder': _('Saat')})
    )
    aciklama = forms.CharField(
        label=_('Açıklama'),
        widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': _('Kaç kişi için randevu alıyorsunuz?')})
    )

    class Meta:
        model = Randevu
        fields = ['isim', 'email', 'telefon', 'tarih', 'saat', 'aciklama']

,forms.py dosyasi, 
from django.db import models
from django.utils.translation import gettext as _

LOKASYON_CHOICES = [
    ('genk', 'Pomandi Genk'),
    ('brasschaat', 'Pomandi Brasschaat'),
]

class Randevu(models.Model):
    lokasyon = models.CharField(max_length=50, choices=LOKASYON_CHOICES, null=False, blank=False)
    isim = models.CharField(max_length=50, null=False, blank=False)
    email = models.EmailField(max_length=255, null=False, blank=False)
    telefon = models.CharField(max_length=20, null=False, blank=False)
    tarih = models.DateField(null=True)
    saat = models.TimeField(null=True)
    aciklama = models.TextField(max_length=500, null=True, blank=True)

    def save(self, *args, **kwargs):
        if not self.lokasyon:
            if self._meta.model_name == "genkrandevu":
                self.lokasyon = 'genk'
            elif self._meta.model_name == "brasschaatrandevu":
                self.lokasyon = 'brasschaat'
        super(Randevu, self).save(*args, **kwargs)

    def __str__(self):
        return self.isim

class WorkingHours(models.Model):
    max_appointments = models.PositiveIntegerField(default=1, help_text="Bu saat dilimi için maksimum randevu sayısı")

    DAY_CHOICES = [
        (0, 'Pazartesi'),
        (1, 'Salı'),
        (2, 'Çarşamba'),
        (3, 'Perşembe'),
        (4, 'Cuma'),
        (5, 'Cumartesi'),
        (6, 'Pazar'),
    ]

    lokasyon = models.CharField(max_length=50, choices=LOKASYON_CHOICES, null=True, blank=True)
    day = models.PositiveSmallIntegerField(choices=DAY_CHOICES)
    start_time = models.TimeField()
    end_time = models.TimeField()

    class Meta:
        unique_together = ['lokasyon', 'day']

    def __str__(self):
        return f"{self.get_lokasyon_display()} - {self.get_day_display()} - {self.start_time} - {self.end_time}"

class GenkRandevu(Randevu):
    class Meta:
        proxy = True
        verbose_name = 'Genk Randevu'
        verbose_name_plural = 'Genk Randevular'

class BrasschaatRandevu(Randevu):
    class Meta:
        proxy = True
        verbose_name = 'Brasschaat Randevu'
        verbose_name_plural = 'Brasschaat Randevular'

class BlockedDates(models.Model):
    lokasyon = models.CharField(max_length=50, choices=LOKASYON_CHOICES, null=False, blank=False)
    date = models.DateField()

    class Meta:
        unique_together = ['lokasyon', 'date']

    def __str__(self):
        return f"{self.get_lokasyon_display()} - {self.date.strftime('%Y-%m-%d')}"


class Settings(models.Model):
    lokasyon = models.CharField(max_length=50, choices=LOKASYON_CHOICES, null=True, blank=True)
    interval = models.PositiveIntegerField(default=20)
,models.py dosyasi, 
from django.http import JsonResponse
from django.shortcuts import render, redirect
from .models import Randevu, BlockedDates, WorkingHours, Settings
from .forms import RandevuForm, LanguageForm
from django.utils.translation import gettext as _
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.conf import settings
from django.utils import translation

def set_language(request):
    if request.method == "POST":
        form = LanguageForm(request.POST)
        if form.is_valid():
            user_language = form.cleaned_data['language']
            translation.activate(user_language)
            request.session["django_language"] = user_language
            return redirect('location_choice')
        else:
            print("Form geçerli değil!")
            print(form.errors)
    else:
        form = LanguageForm()
    return render(request, 'randevu_uygulamasi/set_language.html', {'form': form})

def location_choice(request):
    if request.method == "POST":
        chosen_location = request.POST.get('location')
        request.session['chosen_location'] = chosen_location
        return redirect('randevu_olustur')
    return render(request, 'randevu_uygulamasi/location_choice.html')

def randevu_listesi(request):
    randevular = Randevu.objects.all().order_by('tarih', 'saat')
    return render(request, 'randevu_uygulamasi/randevu_listesi.html', {'randevular': randevular})

def randevu_olustur(request, lokasyon=None):
    if not lokasyon:
        lokasyon = request.session.get('chosen_location', 'default_lokasyon')
        return redirect('randevu_olustur', lokasyon=lokasyon)

    if request.method == "POST":
        form = RandevuForm(request.POST)
        if form.is_valid():
            tarih = form.cleaned_data['tarih']
            saat = form.cleaned_data['saat']

            # Blocked Dates Kontrolü
            if BlockedDates.objects.filter(date=tarih).exists():
                form.add_error('tarih', 'Bu tarih için randevu alınamaz.')
                return render(request, 'randevu_uygulamasi/randevu_olustur.html', {'form': form, 'lokasyon': lokasyon})

            # Çalışma Saatleri ve Günleri Kontrolü
            day_of_week = tarih.weekday()
            try:
                working_hours = WorkingHours.objects.get(day=day_of_week, lokasyon=lokasyon)
                if saat < working_hours.start_time or saat > working_hours.end_time:
                    form.add_error('saat', 'Seçilen saat çalışma saatleri dışında.')
                    return render(request, 'randevu_uygulamasi/randevu_olustur.html', {'form': form})
            except WorkingHours.DoesNotExist:
                form.add_error('tarih', 'Seçilen gün için çalışma saati tanımlı değil.')
                return render(request, 'randevu_uygulamasi/randevu_olustur.html', {'form': form})

            randevu = form.save(commit=False)
            randevu.lokasyon = lokasyon
            randevu.save()
            return redirect('randevu_detay', randevu_id=randevu.id)
    else:
        form = RandevuForm()
    return render(request, 'randevu_uygulamasi/randevu_olustur.html', {'form': form})
def get_working_hours(request, lokasyon, day_of_week):
    # lokasyon bilgisini URL'den alıyoruz, bu yüzden aşağıdaki satıra gerek yok.
    # lokasyon = request.session.get('chosen_location', 'default_lokasyon')
    try:
        working_hours = WorkingHours.objects.get(day=day_of_week, lokasyon=lokasyon)
        return JsonResponse({
            'start': working_hours.start_time.strftime('%H:%M'),
            'end': working_hours.end_time.strftime('%H:%M')
        })
    except WorkingHours.DoesNotExist:
        return JsonResponse({'error': 'Working hours not set for this day'}, status=404)

def get_working_days(request, lokasyon):
    # lokasyon bilgisini URL'den alıyoruz, bu yüzden aşağıdaki satıra gerek yok.
    # lokasyon = request.session.get('chosen_location', 'default_lokasyon')
    working_days = WorkingHours.objects.filter(lokasyon=lokasyon).values_list('day', flat=True)
    return JsonResponse(list(working_days), safe=False)


def randevu_detay(request, randevu_id):
    randevu = Randevu.objects.get(id=randevu_id)
    return render(request, 'randevu_uygulamasi/randevu_detay.html', {'randevu': randevu})

def blocked_dates(request):
    # Kullanıcının seçtiği lokasyon bilgisini alın
    lokasyon = request.session.get('chosen_location', 'default_lokasyon')

    # Lokasyona göre engellenen tarihleri filtreleyin
    dates = BlockedDates.objects.filter(lokasyon=lokasyon).values_list('date', flat=True)

    print(dates)  # Bu satırı buraya taşıyın

    # Tarihleri string formatına dönüştürün
    date_strings = [date.isoformat() for date in dates]

    # Sonuçları JSON formatında döndürün
    return JsonResponse(date_strings, safe=False)




def get_appointments_for_date(request):
    selected_date = request.GET.get('date')
    appointments = Randevu.objects.filter(tarih=selected_date).values_list('saat', flat=True)
    return JsonResponse(list(appointments), safe=False)

def get_appointment_interval(request, lokasyon):
    settings = Settings.objects.filter(lokasyon=lokasyon).first()
    interval = settings.interval if settings else 20  # Eğer ayarlar yapılmamışsa varsayılan olarak 20 dakika
    return JsonResponse({"interval": interval})

,views.py dosyasi, 
# randevu_uygulamasi/urls.py

from django.urls import path
from . import views
from django.conf.urls.i18n import i18n_patterns

urlpatterns = [
   
    path('', views.randevu_listesi, name='randevu_listesi'),
   path('randevu/<str:lokasyon>/', views.randevu_olustur, name='randevu_olustur'),
    path('randevu_detay/<int:randevu_id>/', views.randevu_detay, name='randevu_detay'),
    path('blocked_dates/', views.blocked_dates, name='blocked_dates'),
    path('set-language/', views.set_language, name='set_language'),
    path('location_choice/', views.location_choice, name='location_choice'),
    path('nl/get_working_hours/<str:lokasyon>/<int:day_of_week>/', views.get_working_hours, name='get_working_hours'),
    path('nl/get_working_days/<str:lokasyon>/', views.get_working_days, name='get_working_days'),
    path('get_appointments_for_date/', views.get_appointments_for_date, name='get_appointments_for_date'),
    path('get_appointment_interval/', views.get_appointment_interval, name='get_appointment_interval'),



]

,urls.py dosyasi,

<!DOCTYPE html>
{% load static %}
{% load i18n %}

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">

<!-- Your custom CSS -->
<link rel="stylesheet" href="{% static 'randevu_uygulamasi/css/styles.css' %}">

<!-- Flatpickr CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">

<!-- Bootstrap JavaScript and jQuery -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>

<!-- Flatpickr JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>

<div class="container py-5">
    <h1 class="mb-5 text-center display-4">{% trans "Yeni Randevu" %}</h1>

    <div class="row justify-content-center">
        <div class="col-12 col-md-8">
            <!-- Form başlangıç etiketi burada -->
            <form method="post">


                {% csrf_token %}
                {% for field in form %}
                <div class="form-group">
                    <label for="displayedTime" class="col-lg-2 control-label display-4">{{ field.label }}</label>
                    <div class="col-lg-10">
                        {% if field.name != "saat" %}
                        {{ field }}
                        {% else %}
                        <!-- Saat için seçilen değeri gösteren input alanı -->
                        <input type="text" id="displayedTime" class="form-control" readonly>
                        <!-- Saat seçimi için butonları burada gösteriyoruz -->
                        <div id="timeButtonsContainer"></div>
                        <!-- Saat input alanını gizli olarak ekliyoruz -->
                        <input type="hidden" id="id_saat" name="saat" autocomplete="off"> <!-- autocomplete özelliği eklendi -->
                        {% endif %}
                        <!-- Form alanı hatalarını göstermek için eklenen kısım -->
                        {% if field.errors %}
                        <div class="alert alert-danger">
                            {{ field.errors|join:", " }}
                        </div>
                        {% endif %}
                        <!-- Hata gösterimi için eklenen kısım sonu -->
                       
                    </div>
                </div>
                {% endfor %}
                <div class="form-group">
                    <div class="col-lg-offset-2 col-lg-10">
                        <button class="btn btn-primary btn-lg btn-block">{% trans "Randevu olustur" %}</button>
                    </div>
                </div>
            </form> <!-- Form son etiketi burada -->
        </div>
    </div>
</div>

<style>
    .flatpickr-day.disabled, .flatpickr-day.disabled:hover {
        background: red !important;
        cursor: not-allowed;
    }
</style>

<script>
    $(document).ready(function() {
        $("#timeButtonsContainer").hide();  // Sayfa yüklendiğinde saat seçim butonlarını gizle

        // Engellenen tarihleri al
        $.getJSON('{% url "blocked_dates" %}', function(blockedDates) {
            // Çalışma günlerini al
            $.getJSON('{% url "get_working_days" %}', function(workingDays) {
                // Engellenen tarihlerle çalışma günlerini birleştir
                var disabledDates = getDisabledDates(blockedDates, workingDays);
               
                // Flatpickr ayarları
                $("#id_tarih").flatpickr({
                    dateFormat: "Y-m-d",
                    disable: disabledDates,
                    minDate: "today",
                    onChange: function(selectedDates, dateStr, instance) {
                        if (selectedDates.length > 0) {
                            var dayOfWeek = selectedDates[0].getDay();
                            $.getJSON('{% url "get_working_hours" day_of_week=0 %}'.replace('0', dayOfWeek), function(workHours) {
                                var availableTimes = generateTimeSlots(workHours.start, workHours.end);
   
                                // Seçilen tarihte alınmış randevuları kontrol et
                                $.getJSON('/get_appointments_for_date/', {date: dateStr}, function(takenTimes) {
                                    availableTimes = availableTimes.filter(function(time) {
                                        return !takenTimes.includes(time);
                                    });
   
                                    populateTimeButtons(availableTimes);
                                });
                            });
                        }
                    }
                });
            });
        });
    });
   
    // Engellenen tarihlerle çalışma günlerini birleştir
    function getDisabledDates(blockedDates, workingDays) {
        var disabledDates = blockedDates.slice(); // Engellenen tarihleri kopyala
        var currentDate = new Date();
        for (var i = 0; i < 365; i++) { // Bir yıl içindeki tüm tarihleri kontrol et
            var dayOfWeek = currentDate.getDay();
            if (!workingDays.includes(dayOfWeek)) {
                disabledDates.push(formatDate(currentDate));
            }
            currentDate.setDate(currentDate.getDate() + 1);
        }
        return disabledDates;
    }
   
    // Tarihi "YYYY-MM-DD" formatına dönüştür
    function formatDate(date) {
        var day = date.getDate();
        var month = date.getMonth() + 1;
        var year = date.getFullYear();
        return year + '-' + (month < 10 ? '0' : '') + month + '-' + (day < 10 ? '0' : '') + day;
    }
   
    function populateTimeButtons(availableTimes) {
        var container = $("#timeButtonsContainer");
        container.empty();  // Önceki butonları temizle
   
        availableTimes.forEach(function(time) {
            var button = $("<button>")
                .addClass("btn btn-primary time-button")
                .text(time)
                .click(function() {
                    $("#id_saat").val(time);  // Gizli saat input alanını doldur
                    $("#displayedTime").val(time);  // Seçilen saati göster
                    container.hide();  // Saat seçim butonlarını gizle
                });
            container.append(button);
        });
   
        container.show();  // Saat butonlarını göster
   
        // Saat seçim butonları gösterildiğinde, dış tıklama ile gizleme işlevini ekleyin
        $(document).click(function(event) {
            if (!$(event.target).closest("#id_tarih, .time-button").length) {
                container.hide();
            }
        });
    }
   
   


    function generateTimeSlots(start, end) {
        var timeSlots = [];
        var currentTime = new Date(`1970-01-01 ${start}:00`);
        var endTime = new Date(`1970-01-01 ${end}:00`);
       
        // Interval değerini API'den alın
        $.ajax({
            url: '/get_appointment_interval/',
            async: false,
            dataType: 'json',
            success: function(data) {
                var interval = data.interval * 60000;  // dakikayı milisaniyeye çevir
   
                while (currentTime < endTime) {
                    var hours = String(currentTime.getHours()).padStart(2, '0');
                    var minutes = String(currentTime.getMinutes()).padStart(2, '0');
                    timeSlots.push(`${hours}:${minutes}`);
                    currentTime = new Date(currentTime.getTime() + interval);
                }
            }
        });
   
        return timeSlots;
    }

    // Lokasyon değerini dinamik olarak formun action attribute'una ekleyen fonksiyon
function updateFormActionWithLocation() {
    var lokasyonValue = "{{ request.session.chosen_location }}";  // Django template dilini kullanarak session'dan lokasyon değerini alıyoruz
    var formActionURL = "{% url 'randevu_olustur' lokasyon='PLACEHOLDER' %}".replace('PLACEHOLDER', lokasyonValue);
    $("form").attr("action", formActionURL);
}

// Formun submit edilmesi öncesinde lokasyon değerini formun action attribute'una ekleyin
$("form").submit(function() {
    updateFormActionWithLocation();
});

   
</script>
,randevuolustur.html dosyasi