Premium Maatpakken vanaf €320|Boek Gratis Afspraak
Pomandi Men's Suits

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