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