from flask import Flask, render_template, request, redirect, url_for, session, jsonify
import os
from flask_sqlalchemy import SQLAlchemy  
from datetime import datetime
from zoneinfo import ZoneInfo
from math import radians, cos, sin, sqrt, atan2
from flask import jsonify
from flask import send_from_directory



import requests
def send_whatsapp_message(number, message, image_url=None):
    url = "http://localhost:5560/send"
    data = {
        "number": number,
        "message": message
    }

    if image_url:
        data["image"] = image_url

    try:
        response = requests.post(url, json=data)
        result = response.json()
        return result
    except Exception as e:
        return {"error": str(e)}




app = Flask(__name__, template_folder=os.path.join(os.getcwd(), "templates"))
app.secret_key = "gizli_anahtar"


# PDF için   
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
import os




# Veritabanı yapılandırması  
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///izin_takip.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)



class Bolum(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), unique=True, nullable=False)  # 📌 Bölüm adı benzersiz ve boş olamaz

    def __repr__(self):
        return f"<Bolum {self.name}>"


# Kullanıcı modeli
from flask_sqlalchemy import SQLAlchemy
import json


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(50), nullable=False)
    last_name = db.Column(db.String(50), nullable=False)
    password = db.Column(db.String(50), nullable=False)
    department = db.Column(db.String(50))
    phone_number = db.Column(db.String(50))
    email = db.Column(db.String(100), unique=True, nullable=True)
    role = db.Column(db.String(20), default="personel")
    active = db.Column(db.Boolean, default=True)
    calisma_gunleri = db.Column(db.String(255))  # Çalışma günleri, string olarak tutulacak
    calisma_saatleri = db.Column(db.Text)  # JSON formatında saklanacak
    is_shift_worker = db.Column(db.Boolean, default=False)  # Yeni eklenen alan

    def get_calisma_saatleri(self):
        if self.calisma_saatleri:
            return json.loads(self.calisma_saatleri)
        return {}

    def set_calisma_saatleri(self, saatler_dict):
        self.calisma_saatleri = json.dumps(saatler_dict)




# Maaşlar için
class Salary(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)  # User tablosu ile ilişkilendirme
    salary = db.Column(db.Float, nullable=False)  # Maaş bilgisi
    valid_from = db.Column(db.Date, nullable=False)  # Maaşın başlangıç tarihi
    monthly_hours = db.Column(db.Integer, nullable=False, default=225)  # Aylık çalışma saati, varsayılan 225 saat

    user = db.relationship("User", backref=db.backref("salaries", lazy=True))  # User tablosu ile ilişki

    def __repr__(self):
        return f"<Salary {self.user_id} - {self.salary} - {self.valid_from}>"


# Mesai çarpanı için
from datetime import datetime

class OvertimeMultiplier(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    day = db.Column(db.String(20), nullable=False)  # Pazartesi, Salı, Çarşamba vb.
    start_time = db.Column(db.String(5), nullable=False)  # 18:00 gibi HH:MM formatında
    end_time = db.Column(db.String(5), nullable=False)  # 07:30 gibi HH:MM formatında
    multiplier = db.Column(db.Float, nullable=False)  # Fazla mesai çarpanı (1.5, 2.0 gibi)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)  # Otomatik ekleme zamanı

# Mesai için özel gün çarpanı için
from datetime import datetime
class SpecialDay(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    date = db.Column(db.Date, nullable=False)  # Özel gün tarihi
    name = db.Column(db.String(100), nullable=False)  # Özel gün adı
    multiplier = db.Column(db.Float, nullable=False)  # Fazla mesai çarpanı






class IzinTalebi(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    user = db.relationship('User', backref=db.backref('izin_talepleri', lazy=True))
    reason = db.Column(db.String(200), nullable=False)
    reason_text = db.Column(db.Text, nullable=True)
    request_date = db.Column(db.DateTime, default=datetime.now(ZoneInfo("Europe/Istanbul")))
    start_date = db.Column(db.Date, nullable=False)
    start_time = db.Column(db.String(50), nullable=False)
    end_date = db.Column(db.Date, nullable=False)
    end_time = db.Column(db.String(50), nullable=False)
    status = db.Column(db.String(50), default='Bekliyor')

    # 🔥 **Yeni Alanlar (İmzalar İçin)**
    bolum_yoneticisi = db.Column(db.String(200), nullable=True)
    bolum_muduru = db.Column(db.String(200), nullable=True)
    ik_muduru = db.Column(db.String(200), nullable=True)




class CalismaSaatleri(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    baslangic_tarihi = db.Column(db.Date, nullable=False)
    bitis_tarihi = db.Column(db.Date, nullable=False)
    giris_saati = db.Column(db.Time, nullable=False)
    cikis_saati = db.Column(db.Time, nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    # 🔥 Buradaki `backref` adını değiştiriyoruz
    user = db.relationship('User', backref=db.backref('vardiyalar', lazy=True))  # "calisma_saatleri" yerine "vardiyalar" oldu





class ModulAyarları(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    role = db.Column(db.String(20), unique=True, nullable=False)
    izin_modulu = db.Column(db.Boolean, default=True)  # İzin modülü varsayılan açık
    giris_cikis_modulu = db.Column(db.Boolean, default=True)  # Giriş-çıkış modülü varsayılan açık 
    bordro_modulu = db.Column(db.Boolean, default=False)  # Bordro modülü varsayılan kapalı  
    vardiya_modulu = db.Column(db.Boolean, default=False)  # Vardiya modülü (Yeni eklendi, varsayılan kapalı)




class Bilgilendirme(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(200), nullable=False)  # Mesaj başlığı
    message = db.Column(db.Text, nullable=False)  # Mesaj içeriği
    image_path = db.Column(db.String(255), nullable=True)  # Görsel yolu (isteğe bağlı)
    departments = db.Column(db.String(255), nullable=False)  # Görebilecek bölümler (virgülle ayrılmış string)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)  # Mesajın eklenme zamanı

    def __repr__(self):
        return f"<Bilgilendirme {self.title}>"



class UserReadMessage(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    mesaj_id = db.Column(db.Integer, db.ForeignKey('bilgilendirme.id'), nullable=False)

    def __repr__(self):
        return f"<UserReadMessage user_id={self.user_id}, mesaj_id={self.mesaj_id}>"


class UserPhoto(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)  # 📌 User tablosuna bağlantı
    photo_path = db.Column(db.String(255), nullable=False)  # 📌 Fotoğrafın kayıtlı olduğu dosya yolu

    user = db.relationship('User', backref=db.backref('photos', lazy=True))  # 📌 User ile ilişkilendir


import unicodedata

with app.app_context():
    db.create_all()




# 📌 Unicode karakterleri normalize eden fonksiyon
def normalize_text(text):
    if text:
        return unicodedata.normalize('NFKD', text).encode('ASCII', 'ignore').decode('utf-8').lower()
    return ""

# 📌 Giriş Sayfası (login)
@app.route("/", methods=["GET", "POST"])
def login():
    if request.method == "POST":
        first_name = normalize_text(request.form.get("first_name"))
        last_name = normalize_text(request.form.get("last_name"))
        password = request.form.get("password")

        # 📌 Kullanıcıları getir ve normalize ederek karşılaştır
        users = User.query.all()
        matched_user = None

        for user in users:
            if normalize_text(user.first_name) == first_name and normalize_text(user.last_name) == last_name and user.password == password:
                matched_user = user
                break  # Kullanıcıyı bulduk, döngüyü bitir

        # 📌 Kullanıcı bulunduysa giriş yap, yoksa hata sayfasına yönlendir
        if matched_user:
            session["user_id"] = matched_user.id
            session["role"] = matched_user.role

            # 📌 Departman bilgisi liste mi? Eğer öyleyse string'e çevir. 
            if isinstance(matched_user.department, list):
                session["department"] = ", ".join(matched_user.department)  # Listeyse string yap
            else:
                session["department"] = matched_user.department if matched_user.department else "Bilinmiyor"

            # 🛠 TERMINALDE KONTROL İÇİN EKLENDİ 
            print(f"✅ Giriş Başarılı: {matched_user.first_name} {matched_user.last_name}")
            print(f"🔹 Rol: {matched_user.role}, Departman: {session['department']}")

            # 📌 Kullanıcının rolüne göre yönlendirme yap
            if matched_user.role == "admin":
                return redirect(url_for("admin_home"))
            elif matched_user.role == "manager":
                return redirect(url_for("manager_home"))
            elif matched_user.role == "factory_manager":
                return redirect(url_for("factory_manager_home"))
            elif matched_user.role == "hr_manager":
                return redirect(url_for("hr_manager_home"))
            else:
                return redirect(url_for("personel_home"))
        else:
            return render_template("login_failed.html")  # 📌 Başarısız girişte hata sayfasına yönlendir 
    bilgiler = Bilgi.query.order_by(Bilgi.created_at.desc()).limit(6).all()
    return render_template("login.html", bilgiler=bilgiler)



# **Çıkış İşlemi** 
@app.route("/logout")
def logout():
    session.clear()
    return redirect(url_for("login"))













# 📌 Personel ekleme sayfası
# 🔒 Şifre Hashleme Fonksiyonu


import os
import json
from werkzeug.utils import secure_filename
from flask import Flask, render_template, request, redirect, url_for, flash, session
from datetime import datetime, timedelta
from sqlalchemy import func
from flask_sqlalchemy import SQLAlchemy  # 📌 SQLAlchemy'yi doğrudan import et



from PIL import Image  # 📌 Pillow kütüphanesini ekledik

# 📌 Fotoğraf Yükleme İçin Yapılandırmalar
UPLOAD_FOLDER = "static/uploads/"
ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif"}

app.config["MAX_CONTENT_LENGTH"] = 10 * 1024 * 1024  # Maksimum 10MB dosya boyutu
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER

# 📌 Eğer yükleme klasörü yoksa oluştur
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

def allowed_file(filename):
    """Geçerli uzantıları kontrol et."""
    return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS

def resize_image(image_path, max_size_kb=20):
    """📌 Fotoğrafı sıkıştırarak 20KB altına düşürür"""
    img = Image.open(image_path)

    # 📌 Kalite ve boyut ayarları
    quality = 85  # Başlangıç kalitesi
    while os.path.getsize(image_path) > max_size_kb * 1024 and quality > 10:
        img.save(image_path, format="JPEG", quality=quality, optimize=True)
        quality -= 5  # Kaliteyi azaltarak boyutu küçült

    print(f"✅ Fotoğraf sıkıştırıldı: {os.path.getsize(image_path) / 1024:.2f} KB")

@app.route("/add_person", methods=["GET", "POST"])
def add_person():
    if "user_id" not in session:
        return "Yetkisiz erişim!", 403

    role = session.get("role")
    back_url = url_for(f"{role}_home") if role in ["admin", "manager", "factory_manager", "hr_manager"] else url_for("index")

    bolumler = Department.query.all()

    if request.method == "POST":
        first_name = request.form.get("first_name")
        last_name = request.form.get("last_name")
        password = request.form.get("password")
        department = request.form.get("department")
        phone_number = request.form.get("phone_number")
        

        print("📌 Kullanıcı oluşturuluyor...")

        # ✅ Çalışma Günleri Alınıyor
        calisma_gunleri = request.form.getlist("calisma_gunleri[]")

        # ✅ Çalışma Saatleri JSON Formatına Dönüştürülüyor
        calisma_saatleri = {}
        for gun in ["Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi", "Pazar"]:
            giris_saati = request.form.get(f"giris_saati_{gun}")
            cikis_saati = request.form.get(f"cikis_saati_{gun}")

            if gun in calisma_gunleri:
                calisma_saatleri[gun] = {
                    "giris": giris_saati if giris_saati else "08:00",
                    "cikis": cikis_saati if cikis_saati else "18:00"
                }

        is_shift_worker = request.form.get("is_shift_worker") == "on"

        # ✅ Yeni Kullanıcı Oluşturuluyor
        new_user = User(
            first_name=first_name,
            last_name=last_name,
            password=password,  # 🔒 Hashlenmiş şifreyi kaydediyoruz!
            department=department,
            phone_number=phone_number,
            role="personel",
            calisma_gunleri=",".join(calisma_gunleri),
            calisma_saatleri=json.dumps(calisma_saatleri),
            is_shift_worker=is_shift_worker,
        )

        db.session.add(new_user)
        db.session.commit()

        print(f"✅ Kullanıcı eklendi: {new_user.id}")

        # 📌 **Fotoğraf Yükleme İşlemi**  
        if "profile_photo" in request.files:
            file = request.files["profile_photo"]

            if file.filename == "":
                print("❌ HATA: Dosya seçilmedi!")
            elif file and allowed_file(file.filename):
                filename = secure_filename(file.filename)
                photo_filename = f"user_{new_user.id}_{filename}"
                file_path = os.path.join(app.config["UPLOAD_FOLDER"], photo_filename)
                file.save(file_path)

                # 📌 Fotoğrafı sıkıştırarak 20KB altına düşür
                resize_image(file_path)

                # 📌 Kullanıcının fotoğrafını UserPhoto tablosuna kaydet
                user_photo = UserPhoto(user_id=new_user.id, photo_path=photo_filename)  # ✅ DÜZELTİLDİ
                db.session.add(user_photo)
                db.session.commit()

                print(f"✅ Fotoğraf kaydedildi: {photo_filename}")
            else:
                print("❌ HATA: Geçersiz dosya formatı!")

        flash("Yeni personel başarıyla eklendi!", "success")
        return redirect(url_for("personel_listesi"))

    return render_template("add_person.html", bolumler=bolumler, back_url=back_url)


@app.route("/personel_listesi")
def personel_listesi():
    if "user_id" not in session:
        return redirect(url_for("login"))

    role = session.get("role")

    # Kullanıcının rolüne göre geri döneceği URL belirleniyor
    role = session.get("role")
    back_url = url_for(f"{role}_home") if role in ["admin", "manager", "factory_manager", "hr_manager"] else url_for("index")
    if role == "admin":
        back_url = url_for("admin_home")
    elif role == "manager":
        back_url = url_for("manager_home")
    elif role == "factory_manager":
        back_url = url_for("factory_manager_home")
    elif role == "hr_manager":
        back_url = url_for("hr_manager_home")

    # 📌 **Personel Listeleme Sorgusu**
    users = db.session.query(
        User.id, 
        User.first_name, 
        User.last_name, 
        User.department, 
        User.phone_number, 
        UserPhoto.photo_path  # 🔵 **Fotoğraf bilgisi de çekiliyor**
    ).join(UserPhoto, User.id == UserPhoto.user_id, isouter=True)  # **Eğer fotoğrafı yoksa boş geç**
    
    users = users.filter(User.active == 1).all()

    # 📌 **Varsayılan Fotoğraf Ataması**
    user_list = []
    for user in users:
        foto_path = f"static/uploads/{user.photo_path}" if user.photo_path else "static/uploads/person.png"
        user_data = {
            "id": user.id,
            "first_name": user.first_name,
            "last_name": user.last_name,
            "department": user.department,
            "phone_number": user.phone_number,
            "foto_path": foto_path
        }
        user_list.append(user_data)

    return render_template("personel_listesi.html", users=user_list, back_url=back_url)






# 📌 Yönetici ekleme sayfası
@app.route("/add_manager", methods=["GET", "POST"])
def add_manager():
    if "user_id" not in session or session.get("role") != "admin":
        return "Yetkisiz erişim!", 403

    bolumler = Department.query.all()  # 📌 Artık bölümleri Department tablosundan çekiyoruz

    if request.method == "POST":
        first_name = request.form.get("first_name")
        last_name = request.form.get("last_name")
        password = request.form.get("password")
        phone_number = request.form.get("phone_number")  # 📌 Telefon numarası eklendi
        departments = request.form.getlist("department")  # Checkbox'tan gelen veriler

        if not departments:  # Eğer hiç bölüm seçilmezse hata verelim
            return "Lütfen en az bir bölüm seçin.", 400

        department_str = ",".join(departments)  # Seçilen bölümleri string olarak kaydedelim

        # Yeni bir yönetici ekleyelim
        new_manager = User(
            first_name=first_name,
            last_name=last_name,
            password=password,
            phone_number=phone_number,  # 📌 Telefon numarasını kaydediyoruz
            department=department_str,  # 📌 Seçilen bölümleri kaydediyoruz
            role="manager"
        )
        db.session.add(new_manager)
        db.session.commit()

        return redirect(url_for("admin_home"))  # Yönetici eklendikten sonra admin paneline yönlendir

    return render_template("add_manager.html", bolumler=bolumler)





# **FABRİKA MÜDÜRÜ EKLEME**

@app.route("/add_factory_manager", methods=["GET", "POST"])
def add_factory_manager():
    if "user_id" not in session or session.get("role") != "admin":
        return "Yetkisiz erişim!", 403  # Sadece admin ekleyebilir

    bolumler = Department.query.all()  # 📌 Artık bölümleri Department tablosundan çekiyoruz

    if request.method == "POST":
        first_name = request.form.get("first_name")
        last_name = request.form.get("last_name")
        password = request.form.get("password")
        phone_number = request.form.get("phone_number")  # 📌 Telefon numarası eklendi
        departments = request.form.getlist("department")  # Checkbox'tan gelen verileri liste olarak al

        if not departments:
            return "Lütfen en az bir bölüm seçin.", 400

        department_str = ",".join(departments)  # Seçilen bölümleri string olarak kaydedelim

        # Bölüm müdürünü ekleyelim
        new_factory_manager = User(
            first_name=first_name,
            last_name=last_name,
            password=password,
            phone_number=phone_number,  # 📌 Telefon numarası kaydedildi
            department=department_str,  # 📌 Seçilen bölümleri kaydediyoruz
            role="factory_manager"
        )
        db.session.add(new_factory_manager)
        db.session.commit()

        return redirect(url_for("admin_home"))  # Admin paneline geri dön

    return render_template("add_factory_manager.html", bolumler=bolumler)






# **İK MÜDÜRÜ EKLEME **

@app.route("/add_hr_manager", methods=["GET", "POST"])
def add_hr_manager():
    if "user_id" not in session or session.get("role") != "admin":
        return "Yetkisiz erişim!", 403  # Sadece admin ekleyebilir

    if request.method == "POST":
        first_name = request.form.get("first_name")
        last_name = request.form.get("last_name")
        password = request.form.get("password")
        phone_number = request.form.get("phone_number")  # 📌 Telefon numarası alındı
        email = request.form.get("email")  # 📌 E-posta alındı

        # **Boş değer kontrolü**
        if not first_name or not last_name or not password or not phone_number or not email:
            return "Lütfen tüm alanları doldurun!", 400

        # **Telefon numarasının formatını kontrol et**
        if not phone_number.startswith("+90") or len(phone_number) != 13:
            return "Telefon numarası '+90XXXXXXXXXX' formatında olmalıdır!", 400

        # **Yeni İK Müdürünü ekleyelim**
        new_hr_manager = User(
            first_name=first_name,
            last_name=last_name,
            password=password,
            phone_number=phone_number,  # 📌 Telefon numarası kaydedildi
            email=email,  # 📌 E-posta kaydedildi
            role="hr_manager"
        )
        db.session.add(new_hr_manager)
        db.session.commit()

        print(f"✅ Yeni İK Müdürü Eklendi: {first_name} {last_name}, Telefon: {phone_number}, Email: {email}")

        return redirect(url_for("admin_home"))  # Admin paneline geri dön

    return render_template("add_hr_manager.html")






@app.route("/personel_izinleri")
def personel_izinleri():
    if "user_id" not in session:
        return redirect(url_for("login"))

    user_id = session["user_id"]
    role = session.get("role")

    # Kullanıcının izin taleplerini çek
    talepler = IzinTalebi.query.filter_by(user_id=user_id).join(User).add_columns(
        IzinTalebi.id,
        IzinTalebi.start_date,
        IzinTalebi.start_time,
        IzinTalebi.end_date,
        IzinTalebi.end_time,
        IzinTalebi.reason,
        IzinTalebi.status,
        User.first_name,
        User.last_name,
        User.department,
        IzinTalebi.reason_text
    ).all()

    # Kullanıcının rolüne göre geri dönüş linki belirle
    role_back_urls = {
        "admin": "admin_home",
        "factory_manager": "factory_manager_home",
        "hr_manager": "hr_manager_home",
        "manager": "manager_home",
        "personel": "personel_home"
    }

    back_url = url_for(role_back_urls.get(role, "personel_home"))  # Varsayılan: personel_home

    # **Tarih ve saat formatlarını düzeltme**
    formatted_talepler = [
        {
            "id": talep.id,
            "start_date": talep.start_date.strftime("%d.%m.%Y") if talep.start_date else "",
            "start_time": talep.start_time[:5] if talep.start_time else "",
            "end_date": talep.end_date.strftime("%d.%m.%Y") if talep.end_date else "",
            "end_time": talep.end_time[:5] if talep.end_time else "",
            "reason": talep.reason,
            "status": talep.status,
            "first_name": talep.first_name,
            "last_name": talep.last_name,
            "department": talep.department.split(",")[0] if talep.department else "",  # İlk bölümü al
            "reason_text": talep.reason_text or "Belirtilmemiş"
        }
        for talep in talepler
    ]

    return render_template("personel_izinleri.html", talepler=formatted_talepler, back_url=back_url)








# **Bölüm Müdürü Home**  
@app.route("/factory_manager/home")
def factory_manager_home():
    if "user_id" not in session or session.get("role") != "factory_manager":
        return redirect(url_for("login"))

    # 📌 Kullanıcının rolüne göre modül ayarlarını çek
    ayarlar = ModulAyarları.query.filter_by(role="factory_manager").first()

    return render_template(
        "factory_manager_home.html",
        izin_modulu=ayarlar.izin_modulu if ayarlar else False,
        giris_cikis_modulu=ayarlar.giris_cikis_modulu if ayarlar else False,
        bordro_modulu=ayarlar.bordro_modulu if ayarlar else False
    )


# **İK Home** 

@app.route("/hr_manager/home")
def hr_manager_home():
    if "user_id" not in session or session.get("role") != "hr_manager":
        return redirect(url_for("login"))

    # 📌 Modül ayarlarını veritabanından çek
    ayarlar = ModulAyarları.query.filter_by(role="hr_manager").first()

    # 📌 Eğer ayarlar yoksa, varsayılan olarak tüm modülleri açık kabul et
    if not ayarlar:
        izin_modulu = True
        giris_cikis_modulu = True
        bordro_modulu = False  # Bordro varsayılan olarak kapalı
    else:
        izin_modulu = ayarlar.izin_modulu
        giris_cikis_modulu = ayarlar.giris_cikis_modulu
        bordro_modulu = ayarlar.bordro_modulu

    return render_template(
        "hr_manager_home.html",
        izin_modulu=izin_modulu,
        giris_cikis_modulu=giris_cikis_modulu,
        bordro_modulu=bordro_modulu,
    )





# **Personel Home**  
@app.route("/personel_home")
def personel_home():
    if "user_id" not in session:
        return redirect(url_for("login"))

    # Kullanıcının rolünü bul
    user_role = session.get("role")

    # Kullanıcının rolüne göre modül ayarlarını getir
    moduller = ModulAyarları.query.filter_by(role=user_role).first()

    # Kullanıcının departmanlarını al
    user_departments = set(session.get("departments", "").split(","))

    # Kullanıcının departmanları ile kesişen ve okunmamış mesajları say
    okunmamis_sayi = Bilgilendirme.query.filter(
        or_(*[Bilgilendirme.departments.like(f"%{dept}%") for dept in user_departments])
    ).count()

    return render_template(
        "personel_home.html",
        izin_modulu=moduller.izin_modulu if moduller else False,
        giris_cikis_modulu=moduller.giris_cikis_modulu if moduller else False,
        bordro_modulu=moduller.bordro_modulu if moduller else False,
        okunmamis_sayi=okunmamis_sayi  # ✅ Okunmamış mesaj sayısını HTML'e gönder
    )



# **Manager Home (Yönetici Paneli)**
@app.route("/manager/home")
def manager_home():
    if "user_id" not in session or session.get("role") != "manager":
        return redirect(url_for("login"))

    # 📌 Mevcut yöneticinin modül ayarlarını veritabanından al
    ayar = ModulAyarları.query.filter_by(role="manager").first()

    # 📌 Ayarları HTML'e gönderiyoruz
    return render_template(
        "manager_home.html",
        izin_modulu=ayar.izin_modulu if ayar else False,
        giris_cikis_modulu=ayar.giris_cikis_modulu if ayar else False,
        vardiya_modulu=ayar.vardiya_modulu if ayar else False,
        bordro_modulu=ayar.bordro_modulu if ayar else False
    )



# **Admin Home**
@app.route("/admin/home")
def admin_home():
    if "user_id" not in session or session.get("role") != "admin":
        return redirect(url_for("login"))

    # 📌 Admin için modül ayarlarını getir
    ayar = ModulAyarları.query.filter_by(role="admin").first()
    
    # 📌 Eğer admin için modül ayarları yoksa, varsayılan açık yap
    if not ayar:
        ayar = ModulAyarları(role="admin", izin_modulu=True, giris_cikis_modulu=True, bordro_modulu=True)
        db.session.add(ayar)
        db.session.commit()

    return render_template(
        "admin_home.html",
        izin_modulu=ayar.izin_modulu,
        giris_cikis_modulu=ayar.giris_cikis_modulu,
        bordro_modulu=ayar.bordro_modulu
    )



@app.route("/admin/izin_talepleri")
def izin_talepleri():
    if "user_id" not in session or session.get("role") != "admin":
        return redirect(url_for("login"))

    # 📌 Bekleyen izin taleplerini çek (Tamamlanan izinler hariç)
    talepler = db.session.query(
        IzinTalebi.id, IzinTalebi.start_date, IzinTalebi.start_time,
        IzinTalebi.end_date, IzinTalebi.end_time, IzinTalebi.reason,
        IzinTalebi.status, User.first_name, User.last_name, User.department,
        IzinTalebi.reason_text, UserPhoto.photo_path
    ).join(User, User.id == IzinTalebi.user_id)\
    .outerjoin(UserPhoto, User.id == UserPhoto.user_id)\
    .filter(~IzinTalebi.status.in_(["İzin Verildi", "Reddedildi"]))\
    .all()

    # 📌 Fotoğraf yolları düzeltiliyor (admin olmadan)
    formatted_talepler = []
    for talep in talepler:
        foto_path = f"/static/uploads/{talep.photo_path}" if talep.photo_path else "/static/uploads/person.png"  # 🔵 **Doğru dizin!**

        formatted_talepler.append({
            "id": talep.id,
            "start_date": talep.start_date.strftime('%d.%m.%Y') if talep.start_date else "",
            "start_time": talep.start_time[:5] if talep.start_time and len(talep.start_time) >= 5 else "",  
            "end_date": talep.end_date.strftime('%d.%m.%Y') if talep.end_date else "",
            "end_time": talep.end_time[:5] if talep.end_time and len(talep.end_time) >= 5 else "",  
            "reason": talep.reason,
            "status": talep.status,
            "first_name": talep.first_name,
            "last_name": talep.last_name,
            "department": talep.department,
            "reason_text": talep.reason_text,
            "foto_path": foto_path  # 📌 Kullanılacak fotoğraf yolu (Doğru Dizin!)
        })

    return render_template("izin_talepleri_goster.html", talepler=formatted_talepler)




# **Yönetici İzin Taleplerini Görüntüleme**
@app.route("/manager/izin_talepleri")
def manager_izin_talepleri():
    if "user_id" not in session or session.get("role") != "manager":
        return redirect(url_for("login"))

    user = db.session.get(User, session["user_id"])  # ✅ Doğru Kullanım

    if not user:
        return "Kullanıcı bulunamadı!", 404

    yetkili_bolumler = user.department.split(",")

    talepler = db.session.query(
        IzinTalebi.id, 
        IzinTalebi.start_date, 
        IzinTalebi.start_time,
        IzinTalebi.end_date, 
        IzinTalebi.end_time, 
        IzinTalebi.reason,
        IzinTalebi.status, 
        User.first_name, 
        User.last_name, 
        User.department,
        IzinTalebi.reason_text,
        UserPhoto.photo_path  # 📌 Fotoğraf Bilgisi Ekleniyor!
    ).join(User, User.id == IzinTalebi.user_id)\
    .outerjoin(UserPhoto, User.id == UserPhoto.user_id)\
    .filter(
        User.department.in_(yetkili_bolumler),
        IzinTalebi.status.in_(["Bekliyor", "Yönetici Onayladı"])
    ).all()

    # **📌 Tarih ve saat formatlarını düzeltelim** 
    formatted_talepler = []
    for talep in talepler:
        foto_path = f"/static/uploads/{talep.photo_path}" if talep.photo_path else "/static/uploads/person.png"  # 📌 Doğru Fotoğraf Yolu!

        formatted_talepler.append({
            "id": talep.id,
            "start_date": talep.start_date.strftime("%d.%m.%Y") if talep.start_date else "",
            "start_time": talep.start_time,
            "end_date": talep.end_date.strftime("%d.%m.%Y") if talep.end_date else "",
            "end_time": talep.end_time,
            "reason": talep.reason,
            "status": talep.status,
            "first_name": talep.first_name,
            "last_name": talep.last_name,
            "department": talep.department.split(",")[0],  # 🔥 İlk bölümü al ve sadece onu göster
            "reason_text": talep.reason_text or "Belirtilmemiş",
            "foto_path": foto_path  # 📌 Güncellenmiş Fotoğraf Yolu!
        })

    return render_template("izin_talepleri_goster.html", talepler=formatted_talepler)




def format_tarih(tarih_str, to_db=False):
    """
    Tarih formatlarını düzenler.
    - `to_db=True` olduğunda `GG.AA.YYYY` → `YYYY-MM-DD` formatına çevirir (DB için).
    - `to_db=False` olduğunda `YYYY-MM-DD` → `GG.AA.YYYY` formatına çevirir (Ekran için).
    """
    if tarih_str:
        try:
            if to_db:
                return datetime.strptime(tarih_str, "%d.%m.%Y").strftime("%Y-%m-%d")
            else:
                return datetime.strptime(tarih_str, "%Y-%m-%d").strftime("%d.%m.%Y")
        except ValueError:
            return tarih_str  # Hata olursa orijinal formatta bırak
    return ""









from datetime import datetime

# **Personelin İzin Talep Etmesi**
@app.route("/talep_izin", methods=["GET", "POST"])
def talep_izin():
    if "user_id" not in session:
        return redirect(url_for("login"))

    if request.method == "POST":
        start_date = request.form.get("start_date")
        start_time = request.form.get("start_time")
        end_date = request.form.get("end_date")
        end_time = request.form.get("end_time")
        reason = request.form.get("reason")
        reason_text = request.form.get("reason_text")

        user_id = session.get("user_id")
        izin_sahibi = db.session.get(User, user_id)

        if not izin_sahibi:
            return "Kullanıcı bulunamadı!", 404

        print(f"🛠 İzin talep eden: {izin_sahibi.first_name} {izin_sahibi.last_name} ({izin_sahibi.role})")

        # **Tarih formatını düzeltme**
        def format_tarih(tarih):
            if not tarih:
                return None
            try:
                return datetime.strptime(tarih, "%Y-%m-%d").date()
            except ValueError:
                print(f"⚠️ HATA: Tarih formatı hatalı! ({tarih})")
                return None  

        # **Tarihleri datetime.date nesnesine çeviriyoruz**
        start_date = format_tarih(start_date)
        end_date = format_tarih(end_date)

        print(f"✅ İşlenen Başlangıç Tarihi: {start_date}")
        print(f"✅ İşlenen Bitiş Tarihi: {end_date}")

        # **Bölüm eşleşmesini normalize eden fonksiyon**
        def normalize_bolum(bolum):
            if not bolum:
                return set()
            return set(b.strip().replace(" ", "").replace("-", "") for b in bolum.split(","))

        izin_sahibi_bolumleri = normalize_bolum(izin_sahibi.department)

        print(f"🔍 İzin Sahibi Bölümleri: {izin_sahibi_bolumleri}")

        # **Onay Merciini Belirleme ve Statüyü Ayarlama**  
        onay_mercii = None  
        status = "Bekliyor"

        # **Manager için Bölüm Müdürü Bulma**
        if izin_sahibi.role == "manager":
            bolum_muduru = None
            bolum_mudurleri = User.query.filter_by(role="factory_manager").all()

            for mudur in bolum_mudurleri:
                mudur_bolumleri = normalize_bolum(mudur.department)
                ortak_bolumler = izin_sahibi_bolumleri.intersection(mudur_bolumleri)

                print(f"🟠 Müdür Kontrol: {mudur.first_name} {mudur.last_name} | Müdür Bölümleri: {mudur_bolumleri} | "
                      f"Personel Bölümleri: {izin_sahibi_bolumleri} | Ortak Bölümler: {ortak_bolumler}")

                if ortak_bolumler:
                    bolum_muduru = mudur
                    break  # İlk eşleşeni al

            if bolum_muduru:
                onay_mercii = bolum_muduru
                status = "Bölüm Müdürü Onayı Bekliyor"
            else:
                ik_muduru = User.query.filter_by(role="hr_manager").first()
                if ik_muduru:
                    onay_mercii = ik_muduru
                    status = "İnsan Kaynakları Müdürü Onayı Bekliyor"
                else:
                    status = "İzin Verildi"

        # **Factory Manager için İK Müdürü Bulma**
        elif izin_sahibi.role == "factory_manager":
            ik_muduru = User.query.filter_by(role="hr_manager").first()
            if ik_muduru:
                onay_mercii = ik_muduru
                status = "İnsan Kaynakları Müdürü Onayı Bekliyor"
            else:
                status = "İzin Verildi"

        # **İK Müdürü için otomatik onay**
        elif izin_sahibi.role == "hr_manager":
            status = "İzin Verildi"

        # **Diğer personeller için yöneticiyi bulma**
        else:
            bolum_yoneticisi = None
            bolum_yoneticileri = User.query.filter_by(role="manager").all()

            for yonetici in bolum_yoneticileri:
                yonetici_bolumleri = normalize_bolum(yonetici.department)
                ortak_bolumler = izin_sahibi_bolumleri.intersection(yonetici_bolumleri)

                print(f"🔍 Yönetici Kontrol: {yonetici.first_name} {yonetici.last_name} | "
                      f"Yönetici Bölümleri: {yonetici_bolumleri} | Ortak Bölümler: {ortak_bolumler}")

                if ortak_bolumler:
                    bolum_yoneticisi = yonetici
                    break  # İlk eşleşeni al

            if bolum_yoneticisi:
                onay_mercii = bolum_yoneticisi
                status = "Bekliyor"
            else:
                print("⚠️ Yönetici bulunamadı, fabrika müdürüne bakılıyor...")

                # **Eğer yöneticisi yoksa, fabrika müdürüne bak**
                bolum_muduru = None
                bolum_mudurleri = User.query.filter_by(role="factory_manager").all()

                for mudur in bolum_mudurleri:
                    mudur_bolumleri = normalize_bolum(mudur.department)
                    ortak_bolumler = izin_sahibi_bolumleri.intersection(mudur_bolumleri)

                    print(f"🔍 Bölüm Müdürü Kontrol: {mudur.first_name} {mudur.last_name} | Ortak Bölümler: {ortak_bolumler}")

                    if ortak_bolumler:
                        bolum_muduru = mudur
                        break  

                if bolum_muduru:
                    onay_mercii = bolum_muduru
                    status = "Bölüm Müdürü Onayı Bekliyor"
                else:
                    print("⚠️ Bölüm müdürü de bulunamadı, İK müdürüne bakılıyor...")

                    # **Eğer fabrika müdürü de yoksa, İK Müdürüne bak**
                    ik_muduru = User.query.filter_by(role="hr_manager").first()
                    if ik_muduru:
                        onay_mercii = ik_muduru
                        status = "İnsan Kaynakları Müdürü Onayı Bekliyor"
                    else:
                        print("🚨 İK Müdürü de bulunamadı, izin otomatik onaylandı!")
                        status = "İzin Verildi"

        # **Yeni İzin Talebini Kaydetme**
        yeni_talep = IzinTalebi(
            user_id=user_id,
            reason=reason,
            reason_text=reason_text,
            start_date=start_date,  # 🔥 BURASI ARTIK DATETIME.DATE FORMATINDA
            start_time=start_time,
            end_date=end_date,  # 🔥 BURASI DA DATETIME.DATE FORMATINDA
            end_time=end_time,
            status=status  
        )
        db.session.add(yeni_talep)
        db.session.commit()

        print(f"📢 {izin_sahibi.first_name} {izin_sahibi.last_name} izin talep etti! ✅ Kaydedildi. Statü: {status}")

        # **Onay Merciine Mesaj Gönderme**
        if onay_mercii:
            print(f"📩 Onay merciine mesaj gönderiliyor: {onay_mercii.first_name} ({onay_mercii.role})")

            # **Yeni whatsapp kod**
            send_whatsapp_message(onay_mercii.phone_number[1:], f"Merhaba {onay_mercii.first_name}, {izin_sahibi.first_name} {izin_sahibi.last_name} adlı personel izin talebinde bulundu.\nhttps://izindefteri.com/")         
            

        # **Kullanıcı Rolüne Göre Ana Sayfasına Yönlendirme**
        if izin_sahibi.role == "manager":
            return redirect(url_for("manager_home"))
        elif izin_sahibi.role == "factory_manager":
            return redirect(url_for("factory_manager_home"))
        elif izin_sahibi.role == "hr_manager":
            return redirect(url_for("hr_manager_home"))
        else:
            return redirect(url_for("personel_home"))

    return render_template("talep_izin.html")








from sqlalchemy import or_

@app.route("/factory_manager/izin_talepleri")
def factory_manager_izin_talepleri():
    if "user_id" not in session or session.get("role") != "factory_manager":
        return redirect(url_for("login"))

    user = db.session.get(User, session["user_id"])
    if not user:
        return "Kullanıcı bulunamadı!", 404

    yetkili_bolumler = user.department.split(",")

    print(f"🛠 Bölüm Müdürü: {user.first_name} {user.last_name}, Yetkili Bölümler: {yetkili_bolumler}")

    # ✅ **Bölüm bazlı filtreleme: Bölüm Müdürünün yetkili olduğu bölümlerle eşleşen izinleri listele**
    talepler = db.session.query(
        IzinTalebi.id,
        IzinTalebi.start_date,
        IzinTalebi.start_time,
        IzinTalebi.end_date,
        IzinTalebi.end_time,
        IzinTalebi.reason,
        IzinTalebi.status,
        User.first_name,
        User.last_name,
        User.department,
        IzinTalebi.reason_text,
        UserPhoto.photo_path  # 📌 Fotoğraf Bilgisi Ekleniyor!
    ).join(User, User.id == IzinTalebi.user_id)\
    .outerjoin(UserPhoto, User.id == UserPhoto.user_id)\
    .filter(
        IzinTalebi.status == "Bölüm Müdürü Onayı Bekliyor",
        or_(*[User.department.like(f"%{bolum}%") for bolum in yetkili_bolumler])
    ).all()

    # 📌 **Tarih ve saat formatlarını düzenle**
    formatted_talepler = []
    for talep in talepler:
        foto_path = f"/static/uploads/{talep.photo_path}" if talep.photo_path else "/static/uploads/person.png"  # 📌 Fotoğraf Yolunu Doğru Ayarla!

        formatted_talepler.append({
            "id": talep.id,
            "start_date": talep.start_date.strftime("%d.%m.%Y") if talep.start_date else "",
            "start_time": talep.start_time,
            "end_date": talep.end_date.strftime("%d.%m.%Y") if talep.end_date else "",
            "end_time": talep.end_time,
            "reason": talep.reason,
            "status": talep.status,
            "first_name": talep.first_name,
            "last_name": talep.last_name,
            "department": talep.department.split(",")[0],  # 🔥 İlk bölümü al ve sadece onu göster
            "reason_text": talep.reason_text or "Belirtilmemiş",
            "foto_path": foto_path  # 📌 Güncellenmiş Fotoğraf Yolu!
        })

    # **Eğer hiç talep yoksa, terminalde uyarı verelim**
    if not formatted_talepler:
        print("⚠️ Bölüm Müdürüne düşen hiçbir izin talebi yok!")

    return render_template("izin_talepleri_goster.html", talepler=formatted_talepler)








from flask import jsonify

# **Yetkilendirme Kontrol Fonksiyonu**
def yetki_kontrol():
    """ Kullanıcının İnsan Kaynakları veya Planlama bölümünde olup olmadığını kontrol eder. """
    user_id = session.get("user_id")
    if not user_id:
        return False

    user = db.session.get(User, user_id)
    if not user:
        return False

    yetkili_bolumler = ["İnsan Kaynakları", "Planlama"]
    
    # Kullanıcı admin ise tam yetkili olsun
    if user.role == "admin":
        return True

    # Kullanıcının yetkili bölümlerden birine sahip olup olmadığını kontrol et
    return any(dep.strip() in yetkili_bolumler for dep in user.department.split(","))


# **🗑️ İzin Silme Fonksiyonu**
@app.route("/izin_sil/<int:talep_id>", methods=["DELETE"])
def izin_sil(talep_id):
    if not yetki_kontrol():
        return jsonify({"success": False, "error": "Yetkisiz erişim!"}), 403

    talep = db.session.get(IzinTalebi, talep_id)
    
    if not talep:
        return jsonify({"success": False, "error": "İzin talebi bulunamadı!"}), 404

    db.session.delete(talep)
    db.session.commit()

    return jsonify({"success": True, "message": "İzin talebi başarıyla silindi!"})


# **✏️ İzin Düzenleme Sayfası** 
@app.route("/izin_duzenle/<int:talep_id>", methods=["GET"])
def izin_duzenle(talep_id):
    if not yetki_kontrol():
        return "Bu izin talebini düzenleme yetkiniz yok!", 403

    talep = db.session.get(IzinTalebi, talep_id)
    if not talep:
        return "İzin talebi bulunamadı!", 404

    return render_template("izin_duzenle.html", talep=talep)


from datetime import datetime
from flask import request, redirect, url_for, flash

@app.route("/izin_guncelle/<int:talep_id>", methods=["POST"])
def izin_guncelle(talep_id):
    if not yetki_kontrol():
        return "Bu izin talebini düzenleme yetkiniz yok!", 403

    talep = db.session.get(IzinTalebi, talep_id)
    if not talep:
        return "İzin talebi bulunamadı!", 404

    start_date_str = request.form.get("start_date")
    end_date_str = request.form.get("end_date")
    start_time = request.form.get("start_time")
    end_time = request.form.get("end_time")
    reason = request.form.get("reason")
    reason_text = request.form.get("reason_text")

    # Tarihleri `datetime.date` formatına çevir
    def parse_date(date_str):
        return datetime.strptime(date_str, "%Y-%m-%d").date() if date_str else None

    talep.start_date = parse_date(start_date_str)
    talep.end_date = parse_date(end_date_str)
    talep.start_time = start_time
    talep.end_time = end_time
    talep.reason = reason
    talep.reason_text = reason_text
    talep.status = "İzin Verildi"

    db.session.commit()

    flash("İzin talebi başarıyla güncellendi!", "success")
    
    # Filtre parametrelerini koruyarak yönlendirme yap
    return redirect(url_for("izin_raporlari", **request.args))











@app.route("/hr_manager/izin_talepleri")
def hr_manager_izin_talepleri():
    if "user_id" not in session or session.get("role") != "hr_manager":
        return redirect(url_for("login"))

    # ✅ **Sadece "İnsan Kaynakları Müdürü Onayı Bekliyor" statüsündeki izinleri al**
    talepler = db.session.query(
        IzinTalebi.id,
        IzinTalebi.start_date,
        IzinTalebi.start_time,
        IzinTalebi.end_date,
        IzinTalebi.end_time,
        IzinTalebi.reason,
        IzinTalebi.status,
        User.first_name,
        User.last_name,
        User.department,
        IzinTalebi.reason_text,
        UserPhoto.photo_path  # 📌 Fotoğraf Bilgisi Ekleniyor!
    ).join(User, User.id == IzinTalebi.user_id)\
    .outerjoin(UserPhoto, User.id == UserPhoto.user_id)\
    .filter(IzinTalebi.status == "İnsan Kaynakları Müdürü Onayı Bekliyor")\
    .all()

    # 📌 **Tarih ve saat formatlarını düzenle**
    formatted_talepler = []
    for talep in talepler:
        foto_path = f"/static/uploads/{talep.photo_path}" if talep.photo_path else "/static/uploads/person.png"  # 📌 Fotoğraf Yolunu Doğru Ayarla!

        formatted_talepler.append({
            "id": talep.id,
            "start_date": talep.start_date.strftime("%d.%m.%Y") if talep.start_date else "",
            "start_time": talep.start_time,
            "end_date": talep.end_date.strftime("%d.%m.%Y") if talep.end_date else "",
            "end_time": talep.end_time,
            "reason": talep.reason,
            "status": talep.status,
            "first_name": talep.first_name,
            "last_name": talep.last_name,
            "department": talep.department.split(",")[0],  # 🔥 İlk bölümü al ve sadece onu göster
            "reason_text": talep.reason_text or "Belirtilmemiş",
            "foto_path": foto_path  # 📌 Güncellenmiş Fotoğraf Yolu!
        })

    return render_template("izin_talepleri_goster.html", talepler=formatted_talepler)



# **Personel izin talebini iptal etme talebi**

@app.route("/izin_iptal", methods=["POST"])
def izin_iptal():
    if "user_id" not in session:
        return redirect(url_for("login"))

    talep_id = request.form.get("talep_id")
    izin_talebi = IzinTalebi.query.get(talep_id)

    if not izin_talebi:
        return "İzin talebi bulunamadı!", 404

    # Sadece "Bekliyor" durumundaki izinler iptal edilebilir
    if izin_talebi.status == "Bekliyor":
        db.session.delete(izin_talebi)
        db.session.commit()
        return redirect(url_for("personel_izinleri"))

    return "Bu izin talebi iptal edilemez!", 403





# **İzin Onaylama Süreci**

from twilio.rest import Client



# Twilio hesap bilgileri

from twilio.rest import Client

# Twilio hesap bilgileri

ACCOUNT_SID = "ACcf644212580de8814867a0e3fd9b5607"
AUTH_TOKEN = "283fbb7a78fa071ac4026525afc6b147"
TWILIO_WHATSAPP_NUMARASI = "whatsapp:+15153750115"

# Twilio tarafından onaylanan mesaj şablonları  
TEMPLATE_IZIN_TALEBI = "HX42d224aec5c65ed7c3a41c564c383a1d"
TEMPLATE_IZIN_TALEBI_ONAYLANDI = "HX6ad1fd61cc79de6f40a4b5afb44037aa"

def whatsapp_mesaj_gonder(kime, template_sid, variables):
    """Belirtilen numaraya Twilio şablon mesajı gönderir."""
    if not kime:
        print("❌ Hata: Geçersiz telefon numarası!")
        return False

    try:
        client = Client(ACCOUNT_SID, AUTH_TOKEN)
        
        message = client.messages.create(
            from_=TWILIO_WHATSAPP_NUMARASI,
            to=f"whatsapp:{kime}",
            content_sid=template_sid,  # Şablon kullanımı için ekledik
            content_variables=variables  # Değişkenleri buraya ekledik
        )

        print(f"✅ WhatsApp mesajı başarıyla gönderildi! Mesaj SID: {message.sid}")
        return True

    except Exception as e:
        print(f"❌ WhatsApp mesajı gönderilemedi! Hata: {str(e)}")
        return False


import json

@app.route("/izin_onayla", methods=["POST"])
def izin_onayla():
    if "user_id" not in session:
        return redirect(url_for("login"))

    talep_id = request.form.get("talep_id")
    izin_talebi = db.session.get(IzinTalebi, talep_id)

    if not izin_talebi:
        return "İzin talebi bulunamadı!", 404

    user = db.session.get(User, session["user_id"])  # Onaylayan kişi
    izin_sahibi = db.session.get(User, izin_talebi.user_id)  # İzni isteyen kişi

    if user.role not in ["manager", "factory_manager", "hr_manager"]:
        return "Yetkisiz erişim!", 403

    bolum_yoneticisi = User.query.filter(
        User.department.like(f"%{izin_sahibi.department}%"), User.role == "manager"
    ).first()
    
    bolum_muduru = User.query.filter(
        User.department.like(f"%{izin_sahibi.department}%"), User.role == "factory_manager"
    ).first()
    
    ik_muduru = User.query.filter_by(role="hr_manager").first()

    print(f"🛠 Onaylayan kişi: {user.first_name} {user.last_name} ({user.role})")

    # 🔥 **İmza Alanları (Önceki değerleri koruyarak)**
    imzalar = {
        "personel": f"{izin_sahibi.first_name} {izin_sahibi.last_name}",
        "bolum_yoneticisi": izin_talebi.bolum_yoneticisi if izin_talebi.bolum_yoneticisi else "",
        "bolum_muduru": izin_talebi.bolum_muduru if izin_talebi.bolum_muduru else "",
        "ik_muduru": izin_talebi.ik_muduru if izin_talebi.ik_muduru else "",
    }

    mesaj_gonderilecekler = []
    personel_mesaji = None  # 🔥 Personel için mesajı buraya ekleyeceğiz

    if user.role == "manager":
        izin_talebi.bolum_yoneticisi = f"{user.first_name} {user.last_name}"
        print(f"✅ Bölüm Yöneticisi Onayladı: {izin_talebi.bolum_yoneticisi}")

        if bolum_muduru:
            izin_talebi.status = "Bölüm Müdürü Onayı Bekliyor"
            mesaj_gonderilecekler.append((bolum_muduru.phone_number, TEMPLATE_IZIN_TALEBI, bolum_muduru.first_name))
            personel_mesaji = f'{{"1":"{izin_sahibi.first_name}", "2":"{user.first_name} {user.last_name}", "3":"Bölüm Müdürü"}}'
        else:
            izin_talebi.status = "İnsan Kaynakları Müdürü Onayı Bekliyor"
            if ik_muduru:
                mesaj_gonderilecekler.append((ik_muduru.phone_number, TEMPLATE_IZIN_TALEBI, ik_muduru.first_name))
                personel_mesaji = f'{{"1":"{izin_sahibi.first_name}", "2":"{user.first_name} {user.last_name}", "3":"İK Müdürü"}}'

    elif user.role == "factory_manager":
        izin_talebi.bolum_muduru = f"{user.first_name} {user.last_name}"
        print(f"✅ Bölüm Müdürü Onayladı: {izin_talebi.bolum_muduru}")
        izin_talebi.status = "İnsan Kaynakları Müdürü Onayı Bekliyor"

        if ik_muduru:
            mesaj_gonderilecekler.append((ik_muduru.phone_number, TEMPLATE_IZIN_TALEBI, ik_muduru.first_name))
            personel_mesaji = f'{{"1":"{izin_sahibi.first_name}", "2":"{user.first_name} {user.last_name}", "3":"İK Müdürü"}}'

    elif user.role == "hr_manager":
        izin_talebi.ik_muduru = f"{user.first_name} {user.last_name}"
        print(f"✅ İK Müdürü Onayladı: {izin_talebi.ik_muduru}")
        izin_talebi.status = "İzin Verildi"

        pdf_dosya_yolu = izin_belgesi_olustur(izin_talebi, izin_sahibi, {
            "personel": f"{izin_talebi.user.first_name} {izin_talebi.user.last_name}",
            "bolum_yoneticisi": izin_talebi.bolum_yoneticisi,
            "bolum_muduru": izin_talebi.bolum_muduru,
            "ik_muduru": izin_talebi.ik_muduru,
        })

        if ik_muduru and ik_muduru.email and pdf_dosya_yolu:
            konu = "Tamamlanan İzin Talebi Formu"
            icerik = f"""
            <p><b>{izin_sahibi.first_name} {izin_sahibi.last_name}</b> adlı personelin izin talebi tamamlandı.</p>
            <p><b>İzin Tarihi:</b> {izin_talebi.start_date} - {izin_talebi.end_date}</p>
            <p><b>İzin Sebebi:</b> {izin_talebi.reason}</p>
            <p>Bu e-posta sistem tarafından otomatik gönderilmiştir.</p>
            """

            eposta_sonuc = eposta_gonder(ik_muduru.email, konu, icerik, pdf_dosya_yolu)
            print(f"📧 İK Müdürüne e-posta gönderildi (PDF ekli): {ik_muduru.email}, Sonuç: {eposta_sonuc}")

        # 🔥 **Personeli bilgilendirme mesajı - Süreç tamamlandı formatında**
        personel_mesaji = f'{{"1":"{izin_sahibi.first_name}", "2":"{user.first_name} {user.last_name}"}}'

    db.session.commit()

    # **WhatsApp Mesajlarını Gönder**
    for numara, template, isim in mesaj_gonderilecekler:
        if numara:
            send_whatsapp_message(numara[1:], f"Merhaba {isim}, {izin_sahibi.first_name} {izin_sahibi.last_name} adlı personel izin talebinde bulundu.\nhttps://izindefteri.com/")
            #whatsapp_mesaj_gonder(numara, template, f'{{"1":"{isim}", "2":"{izin_sahibi.first_name} {izin_sahibi.last_name}"}}')

    # **🔥 Personel Bilgilendirme Mesajını Gönderelim**
    if personel_mesaji:
        if izin_talebi.status == "İzin Verildi":
            send_whatsapp_message(izin_sahibi.phone_number[1:], f"Merhaba {izin_sahibi.first_name}, izin talebin {user.first_name} {user.last_name} tarafından onaylandı. Süreç Tamamlandı.\nhttps://izindefteri.com/")

            #whatsapp_mesaj_gonder(izin_sahibi.phone_number, "HXe280d67881d8aef134645d7941094302", personel_mesaji)
        else:
            j = json.loads(personel_mesaji)
            send_whatsapp_message(
                izin_sahibi.phone_number[1:],  # veya f"90{...}" ekle tercihe göre
                f"Merhaba {j['1']}, izin talebin {j['2']} tarafından onaylandı. Şimdi {j['3']} onayına gönderildi.\nhttps://izindefteri.com/"
            )
            #whatsapp_mesaj_gonder(izin_sahibi.phone_number, "HX6ad1fd61cc79de6f40a4b5afb44037aa", personel_mesaji)

    if user.role == "manager":
        return redirect(url_for("manager_izin_talepleri"))
    elif user.role == "factory_manager":
        return redirect(url_for("factory_manager_izin_talepleri"))
    elif user.role == "hr_manager":
        return redirect(url_for("hr_manager_izin_talepleri"))

    return redirect(url_for("izin_talepleri"))


















# ** izin reddet

@app.route("/izin_reddet", methods=["POST"])
def izin_reddet():
    if "user_id" not in session:
        return redirect(url_for("login"))

    talep_id = request.form.get("talep_id")
    izin_talebi = db.session.get(IzinTalebi, talep_id)

    if not izin_talebi:
        return "İzin talebi bulunamadı!", 404

    user = db.session.get(User, session["user_id"])  # Reddeden kişi 
    izin_sahibi = db.session.get(User, izin_talebi.user_id)  # İzni isteyen kişi

    # Yetkilendirme kontrolü
    if user.role not in ["manager", "factory_manager", "hr_manager"]:
        return "Yetkisiz erişim!", 403

    # **İzin Talebi Reddedildi**
    izin_talebi.status = "Reddedildi"

    # **Reddeden Kişinin Rolü**
    role_map = {
        "manager": "Yönetici",
        "factory_manager": "Bölüm Müdürü",
        "hr_manager": "İK Müdürü"
    }
    reddeden_rol = role_map.get(user.role, "Bilinmeyen Yetkili")

    # ✅ **Personeli bilgilendir (Onaylı Twilio şablonunu kullanarak)**  
    send_whatsapp_message(
        izin_sahibi.phone_number[1:], 
        f"Formunuz {reddeden_rol} tarafından reddedildi.\nhttps://izindefteri.com/"
    )


    db.session.commit()

    # **Reddeden yöneticiyi ilgili sayfasına yönlendir**
    if user.role == "manager":
        return redirect(url_for("manager_izin_talepleri"))
    elif user.role == "factory_manager":
        return redirect(url_for("factory_manager_izin_talepleri"))
    elif user.role == "hr_manager":
        return redirect(url_for("hr_manager_izin_talepleri"))

    return redirect(url_for("izin_talepleri"))










# ** twilio whatsapp api **


from twilio.rest import Client







# Mail

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication  # ✅ EKSİK MODÜL EKLENDİ
from email.mime.text import MIMEText

# Gmail SMTP Ayarları
SMTP_SERVER = "smtp.gmail.com"
SMTP_PORT = 587
GMAIL_USER = "personelbilgimerkezi@gmail.com"  # Kendi Gmail adresin    
GMAIL_PASSWORD = "xxvj mjlt ggom hrhv"  # Google'dan aldığın uygulama şifresi

def eposta_gonder(alici, konu, icerik, dosya_yolu=None):
    try:
        msg = MIMEMultipart()
        msg["From"] = GMAIL_USER
        msg["To"] = alici
        msg["Subject"] = konu
        msg.attach(MIMEText(icerik, "html"))

        # **Eğer PDF dosyası varsa, ekleyelim**
        if dosya_yolu:
            with open(dosya_yolu, "rb") as dosya:
                part = MIMEApplication(dosya.read(), Name=os.path.basename(dosya_yolu))
            part["Content-Disposition"] = f'attachment; filename="{os.path.basename(dosya_yolu)}"'
            msg.attach(part)

        # **SMTP Sunucusuna Bağlan ve Gönder**
        server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
        server.starttls()
        server.login(GMAIL_USER, GMAIL_PASSWORD)
        server.sendmail(GMAIL_USER, alici, msg.as_string())
        server.quit()

        print(f"📧 E-posta başarıyla gönderildi: {alici}")
        return True
    except Exception as e:
        print(f"❌ E-posta gönderme hatası: {str(e)}")
        return False






# **PDF İÇİN**  

from reportlab.lib.pagesizes import A3
from reportlab.pdfgen import canvas
import os




# **PDF İÇİN**
import os  # Dosya işlemleri için ekleyelim
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics
from reportlab.lib.pagesizes import A3
from reportlab.pdfgen import canvas

# Türkçe karakter desteği için font ekleyelim       
#font_yolu = os.path.join("static", "DejaVuSans.ttf")
#pdfmetrics.registerFont(TTFont('DejaVuSans', font_yolu))



import os

# Mutlak yol oluşturma 
base_dir = os.path.dirname(os.path.abspath(__file__))
font_yolu = os.path.join(base_dir, "static", "DejaVuSans.ttf")

# Fontu kaydetme 
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics

pdfmetrics.registerFont(TTFont('DejaVuSans', font_yolu))






def format_tarih(tarih):
    """Tarihi 'YYYY-MM-DD' formatından 'DD.MM.YYYY' formatına çevirir."""
    if isinstance(tarih, datetime):  # Eğer tarih nesnesiyse
        return tarih.strftime("%d.%m.%Y")
    try:
        return datetime.strptime(str(tarih), "%Y-%m-%d").strftime("%d.%m.%Y")
    except ValueError:
        return str(tarih)  # Hata olursa orijinal formatı koru





def izin_belgesi_olustur(izin_talebi, izin_sahibi, imzalar): 
    dosya_adi = f"izin_belgesi_{izin_sahibi.first_name}_{izin_sahibi.last_name}.pdf"
    dosya_yolu = os.path.join("static", dosya_adi)

    c = canvas.Canvas(dosya_yolu, pagesize=A3)
    c.setFont("DejaVuSans", 14)  

    # **Başlık**   
    c.drawString(340, 1100, "PERSONEL İZİN BELGESİ")  

    # **İzin Talep Eden Personel Bilgileri**
    c.drawString(60, 1050, f"Ad Soyad: {izin_sahibi.first_name} {izin_sahibi.last_name}")

    # **📌 Bildirim Tarihini (İzin Talep Edildiği Zaman) Doğru Al**
    if hasattr(izin_talebi, "request_date"):
        bildirim_tarihi = izin_talebi.request_date.strftime("%d.%m.%Y - %H:%M")  # 📅 Format: Gün.Ay.Yıl - Saat:Dakika
    else:
        bildirim_tarihi = "Bilinmiyor"

    c.drawString(60, 1020, f"Bildirim Tarihi: {bildirim_tarihi}")  # 🔥 Artık Gerçek Bildirim Tarihi Yazıyor!
    c.drawString(60, 990, f"İznin Başlama Tarihi: {format_tarih(izin_talebi.start_date)} - {izin_talebi.start_time}")
    c.drawString(60, 960, f"İznin Bitiş Tarihi: {format_tarih(izin_talebi.end_date)} - {izin_talebi.end_time}")


    mazeret = f"{izin_talebi.reason} - {izin_talebi.reason_text}" if izin_talebi.reason_text else izin_talebi.reason
    c.drawString(60, 930, mazeret)

    # **Alt Kısım (İmza Alanları)**
    c.drawString(50, 800, "Personel:")
    c.drawString(250, 800, "Bölüm Sorumlusu:")
    c.drawString(450, 800, "Bölüm Müdürü:")
    c.drawString(640, 800, "İnsan Kaynakları Müdürü:")

    # **🔥 NULL (None) Olan İmzaları BOŞ bırak**
    imzalar = {key: (value if value else "") for key, value in imzalar.items()}

    # **İmzalar (Boş olanları yazdırmaz, dolu olanların altına 'Dijital ortamda onaylanmıştır.' ekler)**
    def yazdir_imza(c, x, y, imza):
        if imza:
            c.setFont("DejaVuSans", 14)  # 🔥 Ana imza büyük
            c.drawString(x, y, imza)

            c.setFont("DejaVuSans", 11)  # 🔥 Dijital onay yazısı küçük olacak
            c.drawString(x, y - 15, "Dijital ortamda onaylanmıştır.")

    # **İmzaları ekleyelim**
    yazdir_imza(c, 50, 780, imzalar.get("personel", ""))
    yazdir_imza(c, 250, 780, imzalar.get("bolum_yoneticisi", ""))
    yazdir_imza(c, 450, 780, imzalar.get("bolum_muduru", ""))
    yazdir_imza(c, 640, 780, imzalar.get("ik_muduru", ""))

    c.save()
    return dosya_yolu








# Bölümler için yeni bir tablo oluşturuyoruz
class Department(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), unique=True, nullable=False)  # Bölüm adı

with app.app_context():
    db.create_all()  # Yeni tabloyu oluştur


# 📌 Bölüm ekleme sayfası (Admin Panelinde)
@app.route("/admin/bolumler", methods=["GET", "POST"])
def bolumler():
    if "user_id" not in session or session.get("role") != "admin":
        return "Yetkisiz erişim!", 403

    if request.method == "POST":
        bolum_adi = request.form.get("bolum_adi").strip()
        if bolum_adi:
            # Bölüm zaten var mı kontrol et
            mevcut_bolum = Department.query.filter_by(name=bolum_adi).first()
            if not mevcut_bolum:
                yeni_bolum = Department(name=bolum_adi)
                db.session.add(yeni_bolum)
                db.session.commit()

    # Tüm bölümleri getir
    bolumler = Department.query.all()
    return render_template("admin_bolumler.html", bolumler=bolumler)

# 📌 Bölüm silme işlemi
@app.route("/admin/bolum_sil/<int:bolum_id>", methods=["POST"])
def bolum_sil(bolum_id):
    if "user_id" not in session or session.get("role") != "admin":
        return "Yetkisiz erişim!", 403

    bolum = Department.query.get(bolum_id)
    if bolum:
        db.session.delete(bolum)
        db.session.commit()

    return redirect(url_for("bolumler"))




# 📌 Bölüm düzenleme işlemi
@app.route("/admin/bolum_duzenle/<int:bolum_id>", methods=["POST"])
def bolum_duzenle(bolum_id):
    if "user_id" not in session or session.get("role") != "admin":
        return "Yetkisiz erişim!", 403

    bolum = Department.query.get(bolum_id)
    if bolum:
        yeni_ad = request.form.get("bolum_adi").strip()
        if yeni_ad:
            # Eğer yeni isim farklı ve veri tabanında yoksa güncelle
            mevcut_bolum = Department.query.filter_by(name=yeni_ad).first()
            if not mevcut_bolum:
                bolum.name = yeni_ad
                db.session.commit()

    return redirect(url_for("bolumler"))






# **Personel Silme**
@app.route("/delete_personel/<int:user_id>", methods=["POST"])
def delete_personel(user_id):
    if "user_id" not in session or session.get("role") not in ["admin", "manager", "factory_manager", "hr_manager"]:
        return "Yetkisiz erişim!", 403  # Sadece yetkili kişiler silebilir

    user = User.query.get(user_id)
    if not user:
        return "Personel bulunamadı!", 404

    # 🔥 Eğer geçmişte izin talebi yoksa komple sil
    izin_var_mi = IzinTalebi.query.filter_by(user_id=user.id).first()

    if izin_var_mi:
        user.active = 0  # 🔥 Pasif yap, yöneticinin listesinde görünmesin
    else:
        db.session.delete(user)  # 🔥 Geçmişi yoksa tamamen sil

    db.session.commit()

    return redirect(url_for("personel_listesi"))  # 🔄 İşlem sonrası listeye dön








import os
import json
from werkzeug.utils import secure_filename
from flask import Flask, render_template, request, redirect, url_for, flash, session
from datetime import datetime, timedelta
from sqlalchemy import func
from flask_sqlalchemy import SQLAlchemy  # 📌 SQLAlchemy'yi doğrudan import et



from PIL import Image  # 📌 Pillow kütüphanesini ekledik

# 📌 Fotoğraf Yükleme İçin Yapılandırmalar
UPLOAD_FOLDER = "static/uploads/"
ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif"}

app.config["MAX_CONTENT_LENGTH"] = 10 * 1024 * 1024  # Maksimum 10MB dosya boyutu
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER

# 📌 Eğer yükleme klasörü yoksa oluştur
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

def allowed_file(filename):
    """Geçerli uzantıları kontrol et."""
    return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS

def resize_image(image_path, max_size_kb=20):
    """📌 Fotoğrafı sıkıştırarak 20KB altına düşürür"""
    img = Image.open(image_path)

    # 📌 Kalite ve boyut ayarları
    quality = 85  # Başlangıç kalitesi
    while os.path.getsize(image_path) > max_size_kb * 1024 and quality > 10:
        img.save(image_path, format="JPEG", quality=quality, optimize=True)
        quality -= 5  # Kaliteyi azaltarak boyutu küçült

    print(f"✅ Fotoğraf sıkıştırıldı: {os.path.getsize(image_path) / 1024:.2f} KB")


@app.route("/edit_person/<int:user_id>", methods=["GET", "POST"])
def edit_person(user_id):
    if "user_id" not in session:
        return "Yetkisiz erişim!", 403

    role = session.get("role")
    back_url = url_for(f"{role}_home") if role in ["admin", "manager", "factory_manager", "hr_manager"] else url_for("index")

    user = User.query.get_or_404(user_id)
    bolumler = Department.query.all()
    mevcut_bolumler = user.department.split(",") if user.department else []

    # 📌 Mevcut Kullanıcının Fotoğrafı
    user_photo = UserPhoto.query.filter_by(user_id=user.id).first()
    mevcut_foto_adı = user_photo.photo_path if user_photo else None  # ✅ Fotoğraf adı
    mevcut_foto_url = url_for('static', filename=f"uploads/profile_pictures/{mevcut_foto_adı}") if mevcut_foto_adı else None  # ✅ URL oluştur

    if request.method == "POST":
        user.first_name = request.form.get("first_name")
        user.last_name = request.form.get("last_name")
        user.password = request.form.get("password")
        user.phone_number = request.form.get("phone_number")

        if user.role in ["manager", "factory_manager", "hr_manager"]:
            secilen_bolumler = request.form.getlist("departments[]")
            user.department = ",".join(secilen_bolumler) if secilen_bolumler else None  # 🔵 Boş olmaması için kontrol
        else:
            user.department = request.form.get("department") if request.form.get("department") else None  # 🔵 Tek seçimli bölüm kaydedilmiyordu, düzeltildi

        calisma_gunleri = request.form.getlist("calisma_gunleri[]")
        calisma_saatleri = {}
        for gun in ["Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi", "Pazar"]:
            giris_saati = request.form.get(f"giris_saati_{gun}")
            cikis_saati = request.form.get(f"cikis_saati_{gun}")

            if gun in calisma_gunleri and giris_saati and cikis_saati:
                calisma_saatleri[gun] = {"giris": giris_saati, "cikis": cikis_saati}

        user.calisma_gunleri = ",".join(calisma_gunleri)
        user.calisma_saatleri = json.dumps(calisma_saatleri)
        user.is_shift_worker = request.form.get("is_shift_worker") == "on"

        # 📌 Fotoğraf Güncelleme
        if "profile_photo" in request.files:
            file = request.files["profile_photo"]
            if file.filename and file.filename != "":
                filename = secure_filename(file.filename)
                new_photo_filename = f"user_{user.id}_{filename}"
                new_photo_path = os.path.join(app.config["UPLOAD_FOLDER"], new_photo_filename)

                file.save(new_photo_path)

                # 📌 Eski fotoğrafı sil
                if user_photo and user_photo.photo_path:
                    eski_foto_path = os.path.join(app.config["UPLOAD_FOLDER"], user_photo.photo_path)
                    if os.path.exists(eski_foto_path):
                        os.remove(eski_foto_path)

                # 📌 Yeni fotoğrafı kaydet  ------------------
                if user_photo:
                    user_photo.photo_path = new_photo_filename
                else:
                    user_photo = UserPhoto(user_id=user.id, photo_path=new_photo_filename)
                    db.session.add(user_photo)

                mevcut_foto_adı = new_photo_filename  # ✅ Yeni adı güncelle
                mevcut_foto_url = url_for('static', filename=f"uploads/profile_pictures/{mevcut_foto_adı}")  # ✅ Yeni fotoğraf URL'sini güncelle

        db.session.commit()
        flash("Personel bilgileri güncellendi!", "success")
        return redirect(url_for("personel_listesi"))

    return render_template(
        "add_person.html",
        user=user,
        bolumler=bolumler,
        back_url=back_url,
        edit_mode=True,
        mevcut_bolumler=mevcut_bolumler,
        mevcut_foto_adı=mevcut_foto_adı,  # ✅ Fotoğraf adını gönder
        mevcut_foto_url=mevcut_foto_url,  # ✅ Fotoğraf URL'sini gönder
        is_shift_worker=user.is_shift_worker
    )






import locale
from collections import defaultdict, Counter
from flask import render_template, request, session
from datetime import datetime, timedelta
from sqlalchemy import or_

@app.route("/izin_raporlari", methods=["GET"])
def izin_raporlari():
    if "user_id" not in session:
        return "Yetkisiz erişim!", 403

    user_role = session.get("role")
    user_id = session.get("user_id")

    # 📌 Tarih dönüşüm fonksiyonu
    def format_tarih(tarih):
        if not tarih:
            return None
        try:
            if "-" in tarih:
                return datetime.strptime(tarih, "%Y-%m-%d").date()
            elif "." in tarih:
                return datetime.strptime(tarih, "%d.%m.%Y").date()
        except ValueError:
            print(f"⚠️ HATA: Tarih formatı hatalı! ({tarih})")
            return None
        return None

    # 📌 Saat bazlı izin süresi hesaplayan fonksiyon
    def hesapla_izin_saati(start_str, end_str):
        mesai_baslangic = timedelta(hours=8)
        mesai_bitis = timedelta(hours=18)
        try:
            start = datetime.strptime(start_str, "%d.%m.%Y %H:%M")
            end = datetime.strptime(end_str, "%d.%m.%Y %H:%M")
        except ValueError:
            return 0

        toplam_saat = 0
        current = start

        while current.date() <= end.date():
            if current.weekday() < 5:  # Hafta içi
                gun_baslangic = datetime.combine(current.date(), datetime.min.time()) + mesai_baslangic
                gun_bitis = datetime.combine(current.date(), datetime.min.time()) + mesai_bitis
                actual_start = max(current, gun_baslangic)
                actual_end = min(end, gun_bitis)
                if actual_start < actual_end:
                    fark = actual_end - actual_start
                    toplam_saat += fark.total_seconds() / 3600
            current += timedelta(days=1)

        return toplam_saat

    # 📌 Tarih filtrelerini al
    start_date_raw = request.args.get("start_date")
    end_date_raw = request.args.get("end_date")
    start_date = format_tarih(start_date_raw) if start_date_raw else None
    end_date = format_tarih(end_date_raw) if end_date_raw else None

    print(f"📅 Gelen filtreleme tarihleri: {start_date} - {end_date}")

    # 📌 SQLAlchemy sorgusu
    query = IzinTalebi.query.join(User)

    if user_role in ["admin", "factory_manager", "hr_manager"]:
        pass
    elif user_role == "manager":
        user = User.query.get(user_id)
        if user and user.department:
            if "İnsan Kaynakları" in user.department:
                pass
            else:
                user_departments = [dep.strip() for dep in user.department.split(",")]
                query = query.filter(
                    or_(*[User.department.ilike(f"%{dep}%") for dep in user_departments]),
                    User.role == "personel"
                )
        else:
            return "Yetkisiz erişim!", 403
    else:
        return "Yetkisiz erişim!", 403

    if start_date and end_date:
        query = query.filter(IzinTalebi.start_date >= start_date, IzinTalebi.end_date <= end_date)
    elif start_date:
        query = query.filter(IzinTalebi.start_date >= start_date)
    elif end_date:
        query = query.filter(IzinTalebi.end_date <= end_date)
    else:
        talepler = []
        return render_template("izin_raporlari.html", talepler=talepler)

    talepler = query.add_columns(
        IzinTalebi.id,
        IzinTalebi.start_date,
        IzinTalebi.start_time,
        IzinTalebi.end_date,
        IzinTalebi.end_time,
        IzinTalebi.reason,
        IzinTalebi.status,
        User.first_name,
        User.last_name,
        User.department,
    ).all()

    print(f"📊 Sonuçlar: {len(talepler)} kayıt bulundu.")

    formatted_talepler = [
        {
            "id": talep.id,
            "start_date": talep.start_date.strftime('%d.%m.%Y') if talep.start_date else "",
            "start_time": talep.start_time if isinstance(talep.start_time, str) else talep.start_time.strftime('%H:%M') if talep.start_time else "-",
            "end_date": talep.end_date.strftime('%d.%m.%Y') if talep.end_date else "",
            "end_time": talep.end_time if isinstance(talep.end_time, str) else talep.end_time.strftime('%H:%M') if talep.end_time else "-",
            "reason": talep.reason,
            "status": talep.status,
            "first_name": talep.first_name,
            "last_name": talep.last_name,
            "department": talep.department
        }
        for talep in talepler
    ]

    # 📌 En çok izin talep edenleri say
    ad_soyad_listesi = [
        (f"{t['first_name']} {t['last_name']}", t['department'].split(",")[0].strip() if t['department'] else "-")
        for t in formatted_talepler
    ]
    izin_sayimi = Counter(ad_soyad_listesi)
    ilk_10 = [(adsoyad, dept, count) for (adsoyad, dept), count in izin_sayimi.most_common(10)]

    # 📌 Saat bazlı izin sürelerini hesapla
    saat_sayac = defaultdict(float)
    for t in formatted_talepler:
        adsoyad = f"{t['first_name']} {t['last_name']}"
        department = t['department'].split(",")[0].strip() if t['department'] else "-"
        start = f"{t['start_date']} {t['start_time']}"
        end = f"{t['end_date']} {t['end_time']}"
        try:
            izin_suresi = hesapla_izin_saati(start, end)
            saat_sayac[(adsoyad, department)] += izin_suresi
        except:
            continue

    ilk_10_saat = sorted(saat_sayac.items(), key=lambda x: x[1], reverse=True)[:10]
    ilk_10_saat = [(ad, bolum, round(saat, 1)) for (ad, bolum), saat in ilk_10_saat]

    izin_detaylari = defaultdict(list)

    for t in formatted_talepler:
        adsoyad = f"{t['first_name']} {t['last_name']}"
        department = t['department'].split(",")[0].strip() if t['department'] else "-"
        key = (adsoyad, department)
        izin_detaylari[key].append(t)


    gun_sayaci = Counter()

    for t in formatted_talepler:
        if t["start_date"]:
            gun_sayaci[t["start_date"]] += 1

    # 📌 En çok talep edilen 10 günü sırala
    en_cok_gunler = gun_sayaci.most_common(10)

    izin_detaylari_by_day = defaultdict(list)

    for t in formatted_talepler:
        if t["start_date"]:
            izin_detaylari_by_day[t["start_date"]].append(t)


        # Türkçe gün adları için ayarla
    # 📌 Türkçe gün adları için ayarla (geçici olarak)
    try:
        onceki_locale = locale.setlocale(locale.LC_TIME)  # mevcut ayarı al
        locale.setlocale(locale.LC_TIME, "tr_TR.UTF-8")
    except locale.Error:
        print("⚠️ Uyarı: 'tr_TR.UTF-8' sistemde mevcut değil. Gün adları İngilizce olabilir.")

    izin_gunleri = Counter()

    for t in formatted_talepler:
        if t["start_date"]:
            try:
                dt = datetime.strptime(t["start_date"], "%d.%m.%Y")
                gun_adi = dt.strftime("%A")  # Pazartesi, Salı vs.
                izin_gunleri[gun_adi] += 1
            except:
                continue

    en_cok_gun_adlari = izin_gunleri.most_common()

    # 📌 Locale ayarını geri al
    if 'onceki_locale' in locals():
        locale.setlocale(locale.LC_TIME, onceki_locale)



    return render_template(
        "izin_raporlari.html",
        talepler=formatted_talepler,
        ilk_10=ilk_10,
        ilk_10_saat=ilk_10_saat,
        izin_detaylari=izin_detaylari,
        en_cok_gunler=en_cok_gunler,
        en_cok_gun_adlari=en_cok_gun_adlari,
        izin_detaylari_by_day=izin_detaylari_by_day  # ⬅️ EKLENDİ
    )








class Konumlar(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)  # Konum adı
    lat = db.Column(db.Float, nullable=False)  # Enlem
    lon = db.Column(db.Float, nullable=False)  # Boylam
    max_mesafe_km = db.Column(db.Float, nullable=False, default=0.1)  # Mesafe limiti (KM)

with app.app_context():
    db.create_all()  # Yeni tabloyu oluştur



@app.route("/admin/ayarlar", methods=["GET", "POST"])
def sistem_ayarlar():
    if "user_id" not in session or session.get("role") != "admin":
        return "Yetkisiz erişim!", 403

    if request.method == "POST":
        name = request.form.get("name")
        lat = float(request.form.get("lat"))
        lon = float(request.form.get("lon"))
        max_mesafe_km = float(request.form.get("max_mesafe_km"))

        yeni_konum = Konumlar(name=name, lat=lat, lon=lon, max_mesafe_km=max_mesafe_km)
        db.session.add(yeni_konum)
        db.session.commit()
        flash("✅ Yeni konum başarıyla eklendi!", "success")

    konumlar = Konumlar.query.all()  # Tüm konumları çek

    return render_template("admin_ayarlar.html", konumlar=konumlar)




@app.route("/admin/konum_duzenle/<int:konum_id>", methods=["GET", "POST"])
def konum_duzenle(konum_id):
    if "user_id" not in session or session.get("role") != "admin":
        return "Yetkisiz erişim!", 403

    konum = Konumlar.query.get_or_404(konum_id)  # Konumu getir

    if request.method == "POST":
        konum.name = request.form.get("name")
        konum.lat = float(request.form.get("lat"))
        konum.lon = float(request.form.get("lon"))
        konum.max_mesafe_km = float(request.form.get("max_mesafe_km"))

        db.session.commit()
        flash("✅ Konum başarıyla güncellendi!", "success")
        return redirect(url_for("sistem_ayarlar"))

    return render_template("konum_duzenle.html", konum=konum)


@app.route("/admin/konum_sil/<int:konum_id>", methods=["GET"])
def konum_sil(konum_id):
    if "user_id" not in session or session.get("role") != "admin":
        return "Yetkisiz erişim!", 403

    konum = Konumlar.query.get_or_404(konum_id)
    db.session.delete(konum)
    db.session.commit()
    flash("🗑️ Konum başarıyla silindi!", "danger")

    return redirect(url_for("sistem_ayarlar"))









# 📌 İki koordinat arasındaki mesafeyi hesaplayan fonksiyon (Haversine Formülü)
def haversine(lat1, lon1, lat2, lon2):
    R = 6371  # Dünya'nın yarıçapı (KM)
    dlat = radians(lat2 - lat1)
    dlon = radians(lon2 - lon1)
    a = sin(dlat/2)**2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon/2)**2
    c = 2 * atan2(sqrt(a), sqrt(1 - a))
    return R * c  # KM cinsinden mesafe


class PersonelHareketleri(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    user = db.relationship('User', backref=db.backref('hareketler', lazy=True))
    giris_tarihi = db.Column(db.DateTime, nullable=True)
    cikis_tarihi = db.Column(db.DateTime, nullable=True)
    konum_lat = db.Column(db.Float, nullable=False)  # Enlem
    konum_lng = db.Column(db.Float, nullable=False)  # Boylam


with app.app_context():
    db.create_all()







@app.route("/konum_kontrol", methods=["POST"])
def konum_kontrol():
    data = request.json
    lat, lon = float(data["latitude"]), float(data["longitude"])

    # 📌 Tüm kayıtlı konumları çek
    konumlar = Konumlar.query.all()

    if not konumlar:
        return jsonify({"mesaj": "⚠️ Tanımlı çalışma alanı bulunamadı!", "status": "ERROR", "success": False})

    # 📌 Tüm konumlar içinde kontrol yap
    for konum in konumlar:
        mesafe = haversine(lat, lon, konum.lat, konum.lon)

        if mesafe <= konum.max_mesafe_km:
            return jsonify({
                "mesaj": f"✅ {konum.name} alanındasınız!",
                "status": "OK",
                "success": True,
                "konum_adı": konum.name
            })

    return jsonify({
        "mesaj": f"⚠️ Çalışma alanı dışındasınız! ({mesafe*1000:.0f} metre uzaktasınız)",
        "status": "OUT",
        "success": False
    })




@app.route("/konum", methods=["GET"])
def konum_sayfasi():
    return render_template("konum_kontrol.html")


@app.route("/giris_cikis")
def giris_cikis():
    if "user_id" not in session or session.get("role") not in ["personel", "manager", "factory_manager", "hr_manager"]:
        return "Yetkisiz erişim!", 403

    role = session.get("role")

    # Kullanıcının rolüne göre geri dönüş URL'si
    back_url_map = {
        "personel": url_for("personel_home"),
        "manager": url_for("manager_home"),
        "factory_manager": url_for("factory_manager_home"),
        "hr_manager": url_for("hr_manager_home")
    }

    back_url = back_url_map.get(role, url_for("personel_home"))  # Varsayılan olarak personel home

    return render_template("giris_cikis.html", back_url=back_url)



import os
import time

# İstanbul saat dilimini zorunlu yap 
os.environ['TZ'] = 'Europe/Istanbul'
time.tzset()  # Saat dilimini hemen güncelle


@app.route("/giris_yap", methods=["POST"])
def giris_yap():
    if "user_id" not in session:
        return jsonify({"success": False, "message": "Yetkisiz erişim!"}), 403

    data = request.json
    latitude = data.get("latitude")
    longitude = data.get("longitude")

    sonuc = konum_kontrol_test(latitude, longitude)

    if sonuc.get("success"):
        yeni_giris = PersonelHareketleri(
            user_id=session["user_id"], 
            giris_tarihi=datetime.now(), 
            konum_lat=latitude, 
            konum_lng=longitude
        )
        db.session.add(yeni_giris)
        db.session.commit()
        return jsonify({"success": True, "message": f"✅ {sonuc.get('konum_adı')} konumunda giriş işlemi başarılı!"})
    else:
        return jsonify({"success": False, "message": sonuc.get("mesaj")})




@app.route("/cikis_yap", methods=["POST"])
def cikis_yap():
    if "user_id" not in session:
        return jsonify({"success": False, "message": "Yetkisiz erişim!"}), 403

    data = request.json
    latitude = data.get("latitude")
    longitude = data.get("longitude")

    sonuc = konum_kontrol_test(latitude, longitude)

    if sonuc.get("success"):
        son_giris = PersonelHareketleri.query.filter_by(
            user_id=session["user_id"], cikis_tarihi=None
        ).order_by(PersonelHareketleri.giris_tarihi.desc()).first()

        if son_giris:
            son_giris.cikis_tarihi = datetime.now()
            db.session.commit()
            return jsonify({"success": True, "message": f"🚪 {sonuc.get('konum_adı')} konumunda çıkış işlemi başarılı!"})
        else:
            return jsonify({"success": False, "message": "❌ Çıkış yapacak bir giriş kaydı bulunamadı!"})
    else:
        return jsonify({"success": False, "message": sonuc.get("mesaj")})



def konum_kontrol_test(lat, lon):
    """Personelin konumunu kontrol eden fonksiyon"""
    konumlar = Konumlar.query.all()  # Tüm konumları çek

    if not konumlar:
        return {"mesaj": "⚠️ Henüz tanımlı bir çalışma alanı yok!", "status": "ERROR", "success": False}

    en_yakin_mesafe = float("inf")
    en_yakin_konum = None

    for konum in konumlar:
        mesafe = haversine(float(lat), float(lon), konum.lat, konum.lon)

        # Eğer herhangi bir konum içindeyse başarılı döndür
        if mesafe <= konum.max_mesafe_km:
            return {
                "mesaj": f"✅ {konum.name} alanındasınız!",
                "status": "OK",
                "success": True,
                "konum_adı": konum.name
            }

        # En yakın konumu sakla (bilgilendirme için)
        if mesafe < en_yakin_mesafe:
            en_yakin_mesafe = mesafe
            en_yakin_konum = konum.name

    return {
        "mesaj": f"⚠️ Çalışma alanı dışındasınız! ({en_yakin_konum} konumuna {en_yakin_mesafe*1000:.0f} metre uzaktasınız)",
        "status": "OUT",
        "success": False
    }





@app.route("/son_giris_kontrol")
def son_giris_kontrol():
    if "user_id" not in session:
        return jsonify({"success": False, "message": "Yetkisiz erişim!"}), 403

    son_giris = PersonelHareketleri.query.filter_by(user_id=session["user_id"], cikis_tarihi=None).order_by(PersonelHareketleri.giris_tarihi.desc()).first()

    return jsonify({"giris_devam_ediyor": bool(son_giris)})



from datetime import datetime, timedelta

@app.route("/hareketler", methods=["GET"])
def hareketler():
    if "user_id" not in session:
        return redirect(url_for("login"))

    user_id = session["user_id"]

    # 📌 Varsayılan olarak son 7 günü gösterelim
    today = datetime.now().date()
    seven_days_ago = today - timedelta(days=7)

    # Kullanıcıdan gelen tarihleri al
    start_date = request.args.get("start_date", seven_days_ago.strftime("%Y-%m-%d"))
    end_date = request.args.get("end_date", today.strftime("%Y-%m-%d"))

    # **📌 Tarihleri datetime objesine çevir**
    start_datetime = datetime.strptime(start_date, "%Y-%m-%d")
    end_datetime = datetime.strptime(end_date, "%Y-%m-%d") + timedelta(days=1)  # **Bugünü de kapsasın!**

    # **📌 Sorgu (Bugün de dahil)**
    hareketler = PersonelHareketleri.query.filter(
        PersonelHareketleri.user_id == user_id,
        PersonelHareketleri.giris_tarihi >= start_datetime,
        PersonelHareketleri.giris_tarihi < end_datetime  # 🔥 "Küçük eşittir" yerine "küçüktür" kullanıyoruz
    ).order_by(PersonelHareketleri.giris_tarihi.desc()).all()

    # 📌 Tarihleri formatlayarak HTML'ye gönderelim
    formatted_hareketler = [
        {
            "giris_tarihi": hareket.giris_tarihi.strftime("%d.%m.%Y %H:%M") if hareket.giris_tarihi else "—",
            "cikis_tarihi": hareket.cikis_tarihi.strftime("%d.%m.%Y %H:%M") if hareket.cikis_tarihi else "⏳ Devam Ediyor",
            "durum": "✅ Tamamlandı" if hareket.cikis_tarihi else "⏳ Çalışıyor"
        }
        for hareket in hareketler
    ]

    return render_template("hareketler.html", hareketler=formatted_hareketler, start_date=start_date, end_date=end_date)









from flask import render_template, request, session
from datetime import datetime, timedelta, time
import json
from sqlalchemy.orm import joinedload
from sqlalchemy import or_

GUN_DONUSUMU = {
    "Monday": "Pazartesi",
    "Tuesday": "Salı",
    "Wednesday": "Çarşamba",
    "Thursday": "Perşembe",
    "Friday": "Cuma",
    "Saturday": "Cumartesi",
    "Sunday": "Pazar"
}

@app.route("/giris_cikis_raporlari", methods=["GET"])
def giris_cikis_raporlari():
    if "user_id" not in session or session.get("role") not in ["admin", "factory_manager", "hr_manager", "manager"]:
        return "Yetkisiz erişim!", 403

    user = User.query.get(session["user_id"])

    def format_tarih(tarih):
        if not tarih:
            return None
        try:
            return datetime.strptime(tarih, "%Y-%m-%d").date()
        except ValueError:
            return None

    today = datetime.now().date()
    start_date = format_tarih(request.args.get("start_date")) or today
    end_date = format_tarih(request.args.get("end_date")) or today

    print(f"📅 Filtreleme Tarih Aralığı: {start_date} - {end_date}")

    users = User.query.options(joinedload(User.hareketler)).all()
    if not users:
        return "Veritabanında kullanıcı bulunamadı.", 500

    GIRIS_EKSI_TOLERANS = 30  
    GIRIS_ARTI_TOLERANS = 15  
    CIKIS_ARTI_TOLERANS = 30  
    CIKIS_EKSI_TOLERANS = 0

    formatted_hareketler = []
    izin_detaylari = {}

    hareketler_tumu = PersonelHareketleri.query.filter(
        PersonelHareketleri.giris_tarihi >= datetime.combine(start_date, time.min),
        PersonelHareketleri.giris_tarihi <= datetime.combine(end_date, time.max)
    ).all()

    calismasi_gereken_user_ids = set()
    fazla_mesai_user_ids = set()
    eklenen_kullanicilar = set()
    izinli_kullanicilar = set()

    # formatted_hareketler listesine eklenen hareketlerin benzersiz olmasını sağlamak için bir set kullanıyoruz.
    eklenen_hareket_ids = set()

    for user in users:
        user_id = user.id
        user_name = f"{user.first_name} {user.last_name}"
        department = user.department

        calisma_gunleri = user.calisma_gunleri.split(",") if user.calisma_gunleri else []
        calisma_saatleri = json.loads(user.calisma_saatleri) if user.calisma_saatleri else {}

        # Kullanıcının belirtilen tarih aralığında en az bir giriş yapıp yapmadığını kontrol ediyoruz.
        kullanici_giris_yapti_mi = any(h.user_id == user_id for h in hareketler_tumu)

        for tarih in (start_date + timedelta(days=n) for n in range((end_date - start_date).days + 1)):
            gun_adi = GUN_DONUSUMU.get(tarih.strftime("%A"), "")

            vardiya = CalismaSaatleri.query.filter(
                CalismaSaatleri.user_id == user_id,
                CalismaSaatleri.baslangic_tarihi <= tarih,
                CalismaSaatleri.bitis_tarihi >= tarih
            ).first()

            if vardiya:
                giris_saati = vardiya.giris_saati
                cikis_saati = vardiya.cikis_saati
            else:
                if gun_adi not in calisma_gunleri:
                    continue
                giris_saati = calisma_saatleri.get(gun_adi, {}).get("giris", None)
                cikis_saati = calisma_saatleri.get(gun_adi, {}).get("cikis", None)

            if isinstance(giris_saati, str):
                giris_saati = datetime.strptime(giris_saati, "%H:%M").time()
            if isinstance(cikis_saati, str):
                cikis_saati = datetime.strptime(cikis_saati, "%H:%M").time()

            planlanmis_giris = datetime.combine(tarih, giris_saati)
            planlanmis_cikis = datetime.combine(tarih, cikis_saati)

            izin_var = IzinTalebi.query.filter(
                IzinTalebi.user_id == user_id,
                IzinTalebi.status == "İzin Verildi",
                IzinTalebi.start_date <= tarih,
                IzinTalebi.end_date >= tarih
            ).first()

            # Kullanıcının giriş çıkış hareketlerini gün bazında gruplayarak alıyoruz
            hareketler = [h for h in hareketler_tumu if h.user_id == user_id and h.giris_tarihi.date() == tarih]


            if izin_var:
                izin_baslangic = izin_var.start_date.strftime("%d.%m.%Y") + " " + izin_var.start_time
                izin_bitis = izin_var.end_date.strftime("%d.%m.%Y") + " " + izin_var.end_time
                izin_detaylari[user_id] = {"start": izin_baslangic, "end": izin_bitis}

                izinli_kullanicilar.add(user_id)

                if hareketler:
                    for hareket in hareketler:
                        giris_tarihi = hareket.giris_tarihi
                        cikis_tarihi = hareket.cikis_tarihi

                        formatted_hareketler.append({
                            "id": hareket.id,
                            "user_id": user.id,
                            "first_name": user.first_name,
                            "last_name": user.last_name,
                            "department": department,
                            "giris_tarihi": giris_tarihi.strftime('%d.%m.%Y %H:%M') if giris_tarihi else "—",
                            "cikis_tarihi": cikis_tarihi.strftime('%d.%m.%Y %H:%M') if cikis_tarihi else "—",
                            "status": f"""<button class='izin-button btn btn-primary' data-bs-toggle='modal' data-bs-target='#izinModal' 
                                         data-start='{izin_baslangic}' data-end='{izin_bitis}'>🔵 İzinli</button>"""
                        })
                        eklenen_hareket_ids.add(hareket.id)
                else:
                    formatted_hareketler.append({
                        "id": None,
                        "user_id": user.id,
                        "first_name": user.first_name,
                        "last_name": user.last_name,
                        "department": department,
                        "giris_tarihi": "—",
                        "cikis_tarihi": "—",
                        "status": f"""<button class='izin-button btn btn-primary' data-bs-toggle='modal' data-bs-target='#izinModal' 
                                     data-start='{izin_baslangic}' data-end='{izin_bitis}'>🔵 İzinli</button>"""
                    })
                continue

            calismasi_gereken_user_ids.add(user_id)

            if not hareketler:
                # Kullanıcı belirtilen tarih aralığında hiç giriş yapmamışsa, sadece bir kez "Hiç Giriş Yapmadı" satırı ekleyeceğiz.
                if not kullanici_giris_yapti_mi:
                    formatted_hareketler.append({
                        "id": None,
                        "user_id": user.id,
                        "first_name": user.first_name,
                        "last_name": user.last_name,
                        "department": department,
                        "giris_tarihi": "—",
                        "cikis_tarihi": "—",
                        "status": "🔴 Hiç Giriş Yapmadı"
                    })
                continue

            for hareket in hareketler:
                giris_tarihi = hareket.giris_tarihi
                cikis_tarihi = hareket.cikis_tarihi

                giris_farki = (giris_tarihi - planlanmis_giris).total_seconds() / 60

                if cikis_tarihi:
                    cikis_farki = (cikis_tarihi - planlanmis_cikis).total_seconds() / 60

                    if giris_farki > GIRIS_ARTI_TOLERANS:
                        giris_durumu = "gec"
                    elif giris_farki < -GIRIS_EKSI_TOLERANS:
                        giris_durumu = "erken"
                    else:
                        giris_durumu = "uygun"

                    if cikis_farki > CIKIS_ARTI_TOLERANS:
                        cikis_durumu = "gec"
                    elif cikis_farki < -CIKIS_EKSI_TOLERANS:
                        cikis_durumu = "erken"
                    else:
                        cikis_durumu = "uygun"

                    if giris_durumu == "uygun" and cikis_durumu == "uygun":
                        status = "🟢 Kurallara Uygun"
                    elif giris_durumu == "gec" and cikis_durumu == "uygun":
                        status = "🟠 Geç Giriş"
                    elif giris_durumu == "erken" and cikis_durumu == "uygun":
                        status = "🟠 Erken Giriş"
                    elif giris_durumu == "uygun" and cikis_durumu == "gec":
                        status = "🟠 Geç Çıkış"
                    elif giris_durumu == "uygun" and cikis_durumu == "erken":
                        status = "🟠 Erken Çıkış"
                    else:
                        status = "🔴 Düzensiz Giriş Çıkış"

                else:
                    # Sadece giriş varsa
                    if giris_farki > GIRIS_ARTI_TOLERANS:
                        status = "🟠 Geç Giriş"
                    elif giris_farki < -GIRIS_EKSI_TOLERANS:
                        status = "🟠 Erken Giriş"
                    else:
                        status = "🟢 Kurallara Uygun"

                formatted_hareketler.append({
                    "id": hareket.id,
                    "user_id": user.id,
                    "first_name": user.first_name,
                    "last_name": user.last_name,
                    "department": department,
                    "giris_tarihi": giris_tarihi.strftime('%d.%m.%Y %H:%M'),
                    "cikis_tarihi": cikis_tarihi.strftime('%d.%m.%Y %H:%M') if cikis_tarihi else "—",
                    "status": status if user_id not in izinli_kullanicilar else "🔵 İzinli"
                })

                eklenen_hareket_ids.add(hareket.id)

    for hareket in hareketler_tumu:
        user_id = hareket.user_id
        user = hareket.user
        giris_tarihi = hareket.giris_tarihi
        cikis_tarihi = hareket.cikis_tarihi

        if user_id in calismasi_gereken_user_ids or user_id in izinli_kullanicilar:
            continue

        formatted_hareketler.append({
            "id": hareket.id,
            "user_id": user_id,
            "first_name": user.first_name,
            "last_name": user.last_name,
            "department": user.department,
            "giris_tarihi": giris_tarihi.strftime('%d.%m.%Y %H:%M') if giris_tarihi else "—",
            "cikis_tarihi": cikis_tarihi.strftime('%d.%m.%Y %H:%M') if cikis_tarihi else "—",
            "status": "🟡 Fazla Mesai"
        })

    return render_template("giris_cikis_raporlari.html", hareketler=formatted_hareketler, start_date=start_date.strftime('%Y-%m-%d'), end_date=end_date.strftime('%Y-%m-%d'))





from flask import jsonify

@app.route("/update_giris_cikis", methods=["POST"])
def update_giris_cikis():
    data = request.json
    hareket_id = data.get("record_id")
    field = data.get("field")
    new_value = data.get("new_value")
    user_id = data.get("user_id")

    if not user_id:
        return jsonify({"error": "Kullanıcı kimliği bulunamadı!"}), 400

    if hareket_id == "null" or not hareket_id:
        # **Yeni kayıt oluştur**
        yeni_hareket = PersonelHareketleri(
            user_id=user_id,
            giris_tarihi=None,
            cikis_tarihi=None,
            konum_lat=0,  # **NULL hatası almamak için "0" olarak ekliyoruz**
            konum_lng=0
        )
        db.session.add(yeni_hareket)
        db.session.commit()
        hareket_id = yeni_hareket.id  # Yeni oluşturulan kaydın ID'sini al

    hareket = PersonelHareketleri.query.get(hareket_id)
    if not hareket:
        return jsonify({"error": "Kayıt bulunamadı!"}), 404

    if field == "giris_tarihi":
        hareket.giris_tarihi = datetime.strptime(new_value, "%d.%m.%Y %H:%M")
    elif field == "cikis_tarihi":
        hareket.cikis_tarihi = datetime.strptime(new_value, "%d.%m.%Y %H:%M")
    else:
        return jsonify({"error": "Geçersiz alan!"}), 400

    db.session.commit()
    return jsonify({"success": True, "message": "Veri başarıyla güncellendi!"})



from flask import request, jsonify

@app.route("/delete_giris_cikis", methods=["POST"])
def delete_giris_cikis():
    data = request.json
    hareket_id = data.get("record_id")  # ID'yi aldık
    field = data.get("field")  # Hangi alanı sildiğimizi belirledik
    user_id = data.get("user_id")  # Kullanıcı ID'yi aldık

    if not hareket_id or not user_id:
        return jsonify({"error": "Hareket ID veya Kullanıcı ID bulunamadı!"}), 400

    # **Veritabanından hareketi al**
    hareket = PersonelHareketleri.query.filter_by(id=hareket_id, user_id=user_id).first()

    if not hareket:
        return jsonify({"error": "Kayıt bulunamadı!"}), 404

    # **Hangi alanın silindiğini belirleyelim**
    if field == "giris_tarihi":
        hareket.giris_tarihi = None
    elif field == "cikis_tarihi":
        hareket.cikis_tarihi = None
    else:
        return jsonify({"error": "Geçersiz alan!"}), 400

    # **Eğer hem giriş hem çıkış boşsa, kaydı tamamen silelim**
    if not hareket.giris_tarihi and not hareket.cikis_tarihi:
        db.session.delete(hareket)

    db.session.commit()

    return jsonify({"success": True, "message": "Veri başarıyla silindi!"})



@app.route("/debug_user_id", methods=["POST"])
def debug_user_id():
    data = request.json
    user_id = data.get("user_id")
    print(f"📌 Kullanıcı Tıklama Algılandı: User ID = {user_id}")
    return jsonify({"success": True, "message": "User ID terminale yazdırıldı."})

















@app.route("/calisma_saatleri", methods=["GET"])
def calisma_saatleri():
    if "user_id" not in session or session.get("role") not in ["manager", "factory_manager"]:
        return "Yetkisiz erişim!", 403

    user = db.session.get(User, session["user_id"])
    if not user:
        return "Kullanıcı bulunamadı!", 404

    # 📌 Yöneticinin bağlı olduğu bölümleri al
    bolumler = user.department.split(",")

    # 📌 Bu bölümlerde çalışan personelleri çek
    personeller = User.query.filter(User.department.in_(bolumler), User.role == "personel").all()

    return render_template("calisma_saatleri.html", personeller=personeller)





from flask import request, redirect, url_for, flash
from datetime import datetime

@app.route("/calisma_saatleri_kaydet", methods=["POST"])
def calisma_saatleri_kaydet():
    if "user_id" not in session or session.get("role") not in ["manager", "factory_manager"]:
        return "Yetkisiz erişim!", 403

    user = db.session.get(User, session["user_id"])  # ✅ Doğru Kullanım
    
    if not user:
        return "Kullanıcı bulunamadı!", 404

    bolumler = user.department.split(",")  # Yönetici birden fazla bölüme bakabiliyor
    personeller = User.query.filter(User.department.in_(bolumler)).all()

    kaydedilen_personel_sayisi = 0  # ✅ Kaç kayıt yapıldığını takip edelim

    for personel in personeller:
        start_date = request.form.get(f"start_date_{personel.id}")
        end_date = request.form.get(f"end_date_{personel.id}")
        giris_saati = request.form.get(f"giris_saati_{personel.id}")
        cikis_saati = request.form.get(f"cikis_saati_{personel.id}")

        # **Eğer tarih ve saatlerden biri bile boşsa, kullanıcıya uyarı ver!**
        if not start_date or not end_date or not giris_saati or not cikis_saati:
            flash(f"{personel.first_name} {personel.last_name} için tüm alanları doldurun!", "danger")
            return redirect(url_for("calisma_saatleri"))  # Geri dön ve mesajı göster

        # **Tarih ve saatleri uygun formata çevir**
        start_date = datetime.strptime(start_date, "%Y-%m-%d").date()
        end_date = datetime.strptime(end_date, "%Y-%m-%d").date()
        giris_saati = datetime.strptime(giris_saati, "%H:%M").time()
        cikis_saati = datetime.strptime(cikis_saati, "%H:%M").time()

        # **Eğer bu personelin aynı tarih aralığında kaydı varsa, yeni kayıt ekleme!**
        mevcut_kayit = CalismaSaatleri.query.filter(
            CalismaSaatleri.user_id == personel.id,
            CalismaSaatleri.baslangic_tarihi == start_date,
            CalismaSaatleri.bitis_tarihi == end_date
        ).first()

        if mevcut_kayit:
            flash(f"{personel.first_name} {personel.last_name} için {start_date} - {end_date} tarihleri zaten kayıtlı!", "warning")
            continue  # Aynı kaydı tekrar ekleme

        # **Yeni Çalışma Saatini Ekle**
        yeni_calisma_saati = CalismaSaatleri(
            user_id=personel.id,
            baslangic_tarihi=start_date,  # ✅ Doğru format
            bitis_tarihi=end_date,        # ✅ Doğru format
            giris_saati=giris_saati,      # ✅ Doğru format
            cikis_saati=cikis_saati       # ✅ Doğru format
        )
        db.session.add(yeni_calisma_saati)
        kaydedilen_personel_sayisi += 1  # ✅ Kayıt başarılıysa sayaç artır

    db.session.commit()

    if kaydedilen_personel_sayisi > 0:
        flash(f"{kaydedilen_personel_sayisi} personelin çalışma saatleri başarıyla kaydedildi!", "success")
    else:
        flash("Yeni bir kayıt eklenmedi. Tüm personel için çalışma saatleri zaten kayıtlı!", "info")

    return redirect(url_for("calisma_saatleri"))



@app.route("/vardiya_goruntule", methods=["GET"])
def vardiya_goruntule():
    if "user_id" not in session or session.get("role") not in ["manager", "factory_manager"]:
        return "Yetkisiz erişim!", 403

    user = db.session.get(User, session["user_id"])  # ✅ Doğru Kullanım
    if not user:
        return "Kullanıcı bulunamadı!", 404

    # 📌 Yönetici kendi bölümündeki personelleri görsün
    bolumler = user.department.split(",")
    personeller = User.query.filter(User.department.in_(bolumler), User.role == "personel").all()
    personel_ids = [p.id for p in personeller]

    # 📌 Debug için verileri yazdır
    print("📌 Yöneticinin Bölümleri:", bolumler)
    print("📌 Personel ID'leri:", personel_ids)

    # 📌 Tarih filtreleme
    start_date = request.args.get("start_date")
    end_date = request.args.get("end_date")

    query = CalismaSaatleri.query.join(User).filter(CalismaSaatleri.user_id.in_(personel_ids))

    if start_date:
        query = query.filter(CalismaSaatleri.baslangic_tarihi >= start_date)
    if end_date:
        query = query.filter(CalismaSaatleri.bitis_tarihi <= end_date)

    vardiyalar = query.add_columns(
        User.first_name,
        User.last_name,
        CalismaSaatleri.baslangic_tarihi,
        CalismaSaatleri.bitis_tarihi,
        CalismaSaatleri.giris_saati,
        CalismaSaatleri.cikis_saati,
        CalismaSaatleri.id  # 📌 Silme ve düzenleme için ID gerekiyor
    ).all()
    print("📌 Vardiyalar Gönderiliyor:", vardiyalar)
    return render_template("vardiya_goruntule.html", vardiyalar=vardiyalar, start_date=start_date, end_date=end_date)





# **burasu vardiya görüntüle sayfasının ana sayfasında düzenle butonu görünsün diye
from flask import request, redirect, url_for, flash
from datetime import datetime

@app.route("/vardiya_duzenle/<int:vardiya_id>", methods=["POST"])
def vardiya_duzenle(vardiya_id):
    if "user_id" not in session or session.get("role") not in ["manager", "factory_manager"]:
        return "Yetkisiz erişim!", 403

    vardiya = db.session.get(CalismaSaatleri, vardiya_id)

    if not vardiya:
        flash("Vardiya bulunamadı!", "danger")
        return redirect(url_for("vardiya_goruntule"))

    start_date = request.form.get("start_date")
    end_date = request.form.get("end_date")
    giris_saati = request.form.get("giris_saati")
    cikis_saati = request.form.get("cikis_saati")

    # **Eğer herhangi bir alan boşsa, güncellemeyi yapma ve kullanıcıyı uyar!**
    if not start_date or not end_date or not giris_saati or not cikis_saati:
        flash("Tüm alanları doldurmanız gerekmektedir!", "danger")
        return redirect(url_for("vardiya_duzenle_form", vardiya_id=vardiya_id))  # Kullanıcı düzenleme sayfasına geri dönsün!

    # **Tarih ve saatleri uygun formata çevir**
    start_date = datetime.strptime(start_date, "%Y-%m-%d").date()
    end_date = datetime.strptime(end_date, "%Y-%m-%d").date()
    giris_saati = datetime.strptime(giris_saati, "%H:%M").time()
    cikis_saati = datetime.strptime(cikis_saati, "%H:%M").time()

    # **Eğer hiçbir değişiklik yoksa uyarı ver**
    if (
        vardiya.baslangic_tarihi == start_date and
        vardiya.bitis_tarihi == end_date and
        vardiya.giris_saati == giris_saati and
        vardiya.cikis_saati == cikis_saati
    ):
        flash("Hiçbir değişiklik yapılmadı!", "info")
        return redirect(url_for("vardiya_goruntule"))  # Kullanıcıyı vardiya görüntüleme sayfasına yönlendir

    # **Değişiklikleri kaydet**
    vardiya.baslangic_tarihi = start_date
    vardiya.bitis_tarihi = end_date
    vardiya.giris_saati = giris_saati
    vardiya.cikis_saati = cikis_saati

    db.session.commit()
    
    flash("Vardiya başarıyla güncellendi!", "success")
    return redirect(url_for("vardiya_goruntule"))  # Güncelleme sonrası kullanıcıyı burada tut!





# **Burasu vardiya görüntüleme sayfasından düzenleye basınca çgittiği sayfa için
from flask import render_template

@app.route("/vardiya_duzenle/<int:vardiya_id>", methods=["GET"])
def vardiya_duzenle_form(vardiya_id):
    if "user_id" not in session or session.get("role") not in ["manager", "factory_manager"]:
        return "Yetkisiz erişim!", 403

    vardiya = db.session.get(CalismaSaatleri, vardiya_id)  # SQLAlchemy 2.0 uyumlu

    if not vardiya:
        flash("Vardiya bulunamadı!", "danger")
        return redirect(url_for("vardiya_goruntule"))

    return render_template("vardiya_duzenle.html", vardiya=vardiya)




@app.route("/vardiya_sil/<int:vardiya_id>", methods=["POST"])
def vardiya_sil(vardiya_id):
    if "user_id" not in session or session.get("role") not in ["manager", "factory_manager"]:
        return "Yetkisiz erişim!", 403

    vardiya = CalismaSaatleri.query.get(vardiya_id)
    if not vardiya:
        flash("Silmek istediğiniz vardiya bulunamadı!", "danger")
        return redirect(url_for("vardiya_goruntule"))

    db.session.delete(vardiya)
    db.session.commit()

    flash("Vardiya başarıyla silindi!", "success")
    return redirect(url_for("vardiya_goruntule"))







# **GÖRÜŞ VE ÖNERİ MODELİ**

from datetime import datetime
from zoneinfo import ZoneInfo
from flask_sqlalchemy import SQLAlchemy


class GorusOneri(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
    message = db.Column(db.Text, nullable=False)
    created_at = db.Column(db.DateTime, default=lambda: datetime.now(ZoneInfo("Europe/Istanbul")))
    okundu = db.Column(db.Boolean, default=False)  # 🔥 Yeni eklenen alan (Görüntüleme durumu)

    user = db.relationship("User", backref=db.backref("gorus_oneri", lazy=True))  # ✅ **Senin verdiğin gibi!**










# Görüş ve Öneri Gönderme  
from flask import Flask, flash, redirect, render_template, request, session, url_for


@app.route("/gorus_oneri_gonder", methods=["GET", "POST"])
def gorus_onerisi_gonder():
    if "user_id" not in session:
        return redirect(url_for("login"))

    user = db.session.get(User, session["user_id"])
    if not user:
        return redirect(url_for("login"))

    # Kullanıcının rolüne göre ana sayfa rotasını belirle
    home_routes = {
        "personel": "personel_home",
        "manager": "manager_home",
        "factory_manager": "factory_manager_home",
        "hr_manager": "hr_manager_home"
    }
    home_route = home_routes.get(user.role, "personel_home")

    if request.method == "POST":
        message = request.form.get("message")
        if message:
            yeni_oneri = GorusOneri(user_id=user.id, message=message)
            db.session.add(yeni_oneri)
            db.session.commit()
            flash("Görüş ve öneriniz başarıyla gönderildi!", "success")

    # Kullanıcının geçmiş görüş ve önerilerini getir
    gorus_onerileri = GorusOneri.query.filter_by(user_id=user.id).order_by(GorusOneri.created_at.desc()).all()

    return render_template("gorus_oneri_gonder.html", gorus_onerileri=gorus_onerileri, home_route=home_route)






# Görüş ve Öneri Listesi (Admin ve HR Manager için)
@app.route("/gorus_onerileri")
def gorus_onerileri():
    if "user_id" not in session or session.get("role") not in ["admin", "hr_manager"]:
        return "Yetkisiz erişim!", 403

    # ✅ Görüş ve önerileri en son eklenen en üstte olacak şekilde sıralıyoruz
    gorus_onerileri = GorusOneri.query.join(User).add_columns(
        GorusOneri.id,
        GorusOneri.message,
        GorusOneri.created_at,
        GorusOneri.okundu,  # Okundu durumu
        User.first_name,
        User.last_name
    ).order_by(GorusOneri.created_at.desc()).all()  # 🔥 DESC ile ters sıralama

    # ✅ **Sadece HR Manager okuduğunda okundu olarak işaretle**
    if session.get("role") == "hr_manager":
        GorusOneri.query.filter_by(okundu=False).update({"okundu": True})
        db.session.commit()

    return render_template("gorus_onerileri.html", gorus_onerileri=gorus_onerileri)








@app.route("/okunmamis_oneri_sayisi")
def okunmamis_oneri_sayisi():
    if "user_id" not in session or session.get("role") not in ["admin", "hr_manager"]:
        return jsonify({"count": 0})

    # ✅ Sadece `okundu=False` olan mesajları say
    okunmamis_sayisi = GorusOneri.query.filter_by(okundu=False).count()

    return jsonify({"count": okunmamis_sayisi})








from sqlalchemy import or_

@app.route("/bekleyen_izin_sayisi")
def bekleyen_izin_sayisi():
    if "user_id" not in session:
        return jsonify({"count": 0})

    user = db.session.get(User, session["user_id"])
    if not user:
        return jsonify({"count": 0})

    print(f"🛠 Kullanıcı: {user.first_name} {user.last_name} ({user.role})")

    if user.role == "admin":
        # 🔥 Admin için tüm bekleyen izinleri getir
        count = IzinTalebi.query.filter(
            or_(
                IzinTalebi.status == "Bekliyor",
                IzinTalebi.status == "Bölüm Müdürü Onayı Bekliyor",
                IzinTalebi.status == "İnsan Kaynakları Müdürü Onayı Bekliyor"
            )
        ).count()
        print(f"📢 Admin için bekleyen toplam izin sayısı: {count}")

    elif user.role == "manager":
        yetkili_bolumler = user.department.split(",")
        count = IzinTalebi.query.join(User).filter(
            or_(*[User.department.like(f"%{bolum.strip()}%") for bolum in yetkili_bolumler]),
            IzinTalebi.status == "Bekliyor"
        ).count()
        print(f"📢 Manager için bekleyen izin sayısı: {count}")

    elif user.role == "factory_manager":
        yetkili_bolumler = user.department.split(",")
        count = IzinTalebi.query.join(User).filter(
            or_(*[User.department.like(f"%{bolum.strip()}%") for bolum in yetkili_bolumler]),
            IzinTalebi.status == "Bölüm Müdürü Onayı Bekliyor"
        ).count()
        print(f"📢 Factory Manager için bekleyen izin sayısı: {count}")

    elif user.role == "hr_manager":
        count = IzinTalebi.query.filter(
            IzinTalebi.status == "İnsan Kaynakları Müdürü Onayı Bekliyor"
        ).count()
        print(f"📢 HR Manager için bekleyen izin sayısı: {count}")

    else:
        count = 0
        print("❌ Yetkili rol bulunamadı, bekleyen izin sayısı: 0")

    print("📌 API Yanıtı:", {"count": count})  # 🔥 Flask loglarına düşsün

    return jsonify({"count": count})



# Maaş ekleme sayfası


from datetime import datetime

@app.route("/salary", methods=["GET", "POST"])
def manage_salary():
    if "user_id" not in session or session.get("role") not in ["admin", "hr_manager"]:
        return "Yetkisiz erişim!", 403

    users = User.query.all()
    salaries = Salary.query.all()

    if request.method == "POST":
        action = request.form.get("action")  # İşlem türünü al (add, edit, delete)
        salary_id = request.form.get("salary_id")

        if action == "add":  # ➕ Yeni Maaş Ekleme
            user_id = request.form.get("user_id")
            salary = request.form.get("salary")
            valid_from_str = request.form.get("valid_from")
            monthly_hours = request.form.get("monthly_hours")

            if not user_id or not salary or not valid_from_str or not monthly_hours:
                flash("Tüm alanları doldurmanız gerekiyor!", "danger")
                return redirect(url_for("manage_salary"))

            try:
                valid_from = datetime.strptime(valid_from_str, "%Y-%m-%d").date()
            except ValueError:
                flash("Geçersiz tarih formatı! (Yıl-Ay-Gün)", "danger")
                return redirect(url_for("manage_salary"))

            new_salary = Salary(
                user_id=user_id,
                salary=float(salary),
                valid_from=valid_from,
                monthly_hours=int(monthly_hours)
            )

            db.session.add(new_salary)
            db.session.commit()
            flash("Maaş bilgisi başarıyla eklendi!", "success")

        elif action == "edit":  # ✏️ Maaş Düzenleme
            salary = Salary.query.get(salary_id)
            if salary:
                salary.salary = float(request.form.get("salary"))
                salary.valid_from = datetime.strptime(request.form.get("valid_from"), "%Y-%m-%d").date()
                salary.monthly_hours = int(request.form.get("monthly_hours"))
                db.session.commit()
                flash("Maaş bilgisi başarıyla güncellendi!", "success")

        elif action == "delete":  # ❌ Maaş Silme
            salary = Salary.query.get(salary_id)
            if salary:
                db.session.delete(salary)
                db.session.commit()
                flash("Maaş kaydı silindi!", "warning")

        return redirect(url_for("manage_salary"))

    return render_template("salary.html", users=users, salaries=salaries)


# Maaş güncelleme kodu

@app.route("/salary_edit/<int:salary_id>", methods=["POST"])
def salary_edit(salary_id):
    if "user_id" not in session or session.get("role") not in ["admin", "hr_manager"]:
        return "Yetkisiz erişim!", 403

    salary = Salary.query.get_or_404(salary_id)  # Güncellenecek maaşı getir

    # Formdan gelen verileri al
    salary_amount = request.form.get("salary")
    valid_from = request.form.get("valid_from")
    monthly_hours = request.form.get("monthly_hours")

    if not salary_amount or not valid_from or not monthly_hours:
        flash("Tüm alanları doldurmanız gerekiyor!", "danger")
        return redirect(url_for("manage_salary"))

    try:
        salary.salary = float(salary_amount)
        salary.valid_from = datetime.strptime(valid_from, "%Y-%m-%d").date()  # String tarih formatını Date objesine çevir
        salary.monthly_hours = int(monthly_hours)

        db.session.commit()
        flash("Maaş bilgisi başarıyla güncellendi!", "success")
    except Exception as e:
        flash(f"Hata oluştu: {str(e)}", "danger")

    return redirect(url_for("manage_salary"))



# Maaş silme kodu

@app.route("/salary_delete/<int:salary_id>", methods=["POST"])
def salary_delete(salary_id):
    if "user_id" not in session or session.get("role") not in ["admin", "hr_manager"]:
        return "Yetkisiz erişim!", 403

    salary = Salary.query.get_or_404(salary_id)  # Silinecek maaş kaydını getir

    try:
        db.session.delete(salary)  # Veritabanından sil
        db.session.commit()
        flash("Maaş kaydı başarıyla silindi!", "success")
    except Exception as e:
        flash(f"Hata oluştu: {str(e)}", "danger")

    return redirect(url_for("manage_salary"))




# Mesai çarpanı belirleme sayfası




@app.route("/overtime", methods=["GET", "POST"])
def manage_overtime():
    if "user_id" not in session or session.get("role") not in ["admin", "hr_manager"]:
        return "Yetkisiz erişim!", 403

    turkish_to_english_days = {
        "Pazartesi": "Monday",
        "Salı": "Tuesday",
        "Çarşamba": "Wednesday",
        "Perşembe": "Thursday",
        "Cuma": "Friday",
        "Cumartesi": "Saturday",
        "Pazar": "Sunday"
    }

    english_to_turkish_days = {v: k for k, v in turkish_to_english_days.items()}  # İngilizce → Türkçe

    multipliers = OvertimeMultiplier.query.all()

    # ✅ Günleri Türkçeye çevirerek gönder
    for multiplier in multipliers:
        multiplier.display_day = english_to_turkish_days.get(multiplier.day, multiplier.day)

    if request.method == "POST":
        action = request.form.get("action")

        if action == "add":  # ✅ Yeni Çarpan Ekle
            turkish_day = request.form.get("day")  
            day = turkish_to_english_days.get(turkish_day, turkish_day)  # İngilizceye çevir

            start_time = request.form.get("start_time")
            end_time = request.form.get("end_time")
            multiplier_value = request.form.get("multiplier")

            if not day or not start_time or not end_time or not multiplier_value:
                flash("Tüm alanları doldurmanız gerekiyor!", "danger")
                return redirect(url_for("manage_overtime"))

            new_multiplier = OvertimeMultiplier(
                day=day,  
                start_time=start_time,
                end_time=end_time,
                multiplier=float(multiplier_value)
            )

            db.session.add(new_multiplier)
            db.session.commit()
            flash("Fazla mesai çarpanı başarıyla eklendi!", "success")

        elif action == "edit":  # ✏️ Çarpanı Güncelle
            multiplier_id = request.form.get("multiplier_id")
            multiplier = OvertimeMultiplier.query.get(multiplier_id)

            if multiplier:
                turkish_day = request.form.get("day")  # Formdan gelen Türkçe gün adı
                multiplier.day = turkish_to_english_days.get(turkish_day, turkish_day)  # İngilizceye çevir

                multiplier.start_time = request.form.get("start_time")
                multiplier.end_time = request.form.get("end_time")
                multiplier.multiplier = float(request.form.get("multiplier"))

                db.session.commit()
                flash("Çarpan bilgisi başarıyla güncellendi!", "success")

        elif action == "delete":  # ❌ Çarpanı Sil
            multiplier_id = request.form.get("multiplier_id")
            multiplier = OvertimeMultiplier.query.get(multiplier_id)

            if multiplier:
                db.session.delete(multiplier)
                db.session.commit()
                flash("Çarpan bilgisi silindi!", "warning")

        return redirect(url_for("manage_overtime"))

    return render_template("overtime.html", multipliers=multipliers, english_to_turkish_days=english_to_turkish_days)





 # Mesai için özel gün çarpanı ekleme

@app.route("/special_days", methods=["GET", "POST"])
def manage_special_days():
    if "user_id" not in session or session.get("role") not in ["admin", "hr_manager"]:
        return "Yetkisiz erişim!", 403

    # Tüm özel günleri getir
    special_days = SpecialDay.query.order_by(SpecialDay.date).all()

    if request.method == "POST":
        action = request.form.get("action")
        day_id = request.form.get("day_id")

        if action == "add":  # Yeni Özel Gün Ekle
            date_str = request.form.get("date")
            name = request.form.get("name")
            multiplier = request.form.get("multiplier")

            if not date_str or not name or not multiplier:
                flash("Tüm alanları doldurun!", "danger")
                return redirect(url_for("manage_special_days"))

            date = datetime.strptime(date_str, "%Y-%m-%d").date()
            new_day = SpecialDay(date=date, name=name, multiplier=float(multiplier))

            db.session.add(new_day)
            db.session.commit()
            flash("Özel gün başarıyla eklendi!", "success")

        elif action == "edit":  # Düzenleme
            special_day = SpecialDay.query.get(day_id)
            if special_day:
                special_day.date = datetime.strptime(request.form.get("date"), "%Y-%m-%d").date()
                special_day.name = request.form.get("name")
                special_day.multiplier = float(request.form.get("multiplier"))
                db.session.commit()
                flash("Özel gün güncellendi!", "success")

        elif action == "delete":  # Silme
            special_day = SpecialDay.query.get(day_id)
            if special_day:
                db.session.delete(special_day)
                db.session.commit()
                flash("Özel gün silindi!", "warning")

        return redirect(url_for("manage_special_days"))

    return render_template("special_days.html", special_days=special_days)







# Bordro maaaş hesaplama  

@app.route("/payroll", methods=["GET", "POST"])
def payroll():
    if "user_id" not in session or session.get("role") not in ["admin", "hr_manager"]:
        return "Yetkisiz erişim!", 403

    users = User.query.all()

    if request.method == "POST":
        start_date_str = request.form.get("start_date")
        end_date_str = request.form.get("end_date")
        user_id = request.form.get("user_id")

        if not start_date_str or not end_date_str:
            flash("Tarih aralığını seçmelisiniz!", "danger")
            return redirect(url_for("payroll"))

        start_date = datetime.strptime(start_date_str, "%Y-%m-%d").date()
        end_date = datetime.strptime(end_date_str, "%Y-%m-%d").date()

        payroll_results = []
        selected_users = users if user_id == "all" else [db.session.get(User, int(user_id))]

        for user in selected_users:
            salary = Salary.query.filter(
                Salary.user_id == user.id,
                Salary.valid_from <= start_date
            ).order_by(Salary.valid_from.desc()).first()

            if not salary:
                print(f"DEBUG: Kullanıcı maaşı bulunamadı: {user.first_name} {user.last_name}")
                payroll_results.append({
                    "user": user,
                    "status": "❌ Maaş bilgisi bulunamadı",
                    "net_salary": 0,
                    "worked_hours": 0,
                    "overtime_hours": 0,
                    "overtime_pay": 0,
                    "special_day_pay": 0,
                    "special_day_details": [],
                    "annual_leave_hours": 0
                })
                continue

            monthly_salary = salary.salary
            monthly_hours = salary.monthly_hours
            hourly_rate = monthly_salary / monthly_hours

            hareketler = PersonelHareketleri.query.filter(
                PersonelHareketleri.user_id == user.id,
                PersonelHareketleri.giris_tarihi >= start_date,
                PersonelHareketleri.giris_tarihi <= end_date
            ).all()

            overtime_multipliers = OvertimeMultiplier.query.all()
            special_days = SpecialDay.query.filter(
                SpecialDay.date >= start_date,
                SpecialDay.date <= end_date
            ).all()


            total_worked_hours = 0
            overtime_hours = 0
            overtime_pay = 0
            special_day_pay = 0
            special_day_hours = 0
            overtime_details = []
            special_day_details = []
            normal_details = []

            # Özel günlerde çalışan ve çalışmayan personelleri tespit etmek için
            special_days_worked = set()  # Çalışılan özel günler
            for hareket in hareketler:
                giris = hareket.giris_tarihi
                cikis = hareket.cikis_tarihi or datetime.combine(giris.date(), datetime.max.time())

                worked_hours = (cikis - giris).total_seconds() / 3600
                total_worked_hours += worked_hours

                print(f"\n📌 İşlenen Kullanıcı: {user.first_name} {user.last_name}")
                print(f"  ➝ Giriş Tarihi: {giris}, Çıkış Tarihi: {cikis}")
                print(f"  ➝ Çalışılan Saat: {worked_hours:.2f}")

                # Özel gün kontrolü
                is_special_day = False
                for special in special_days:
                    if special.date == giris.date():
                        special_amount = worked_hours * hourly_rate * special.multiplier
                        special_day_hours += worked_hours
                        special_day_pay += special_amount

                        special_day_details.append({
                            "date": giris.strftime("%d.%m.%Y"),
                            "hours": round(worked_hours, 2),
                            "multiplier": special.multiplier,
                            "amount": round(special_amount, 2)
                        })
                        is_special_day = True
                        special_days_worked.add(special.date)  # Çalışılan özel günü kaydet
                        break  # Özel gün bulundu, diğer kontrollere gerek yok

                if is_special_day:
                    continue  # Özel gün çalışması ise normal çalışmaya ekleme

                # Normal çalışma ve fazla mesai saatlerini hesapla
                normal_hours_day = worked_hours
                overtime_hours_day = 0

                for overtime in overtime_multipliers:
                    calisma_gunu = giris.strftime("%A")  # Gün ismi (İngilizce bekliyor)
                    mesai_gunu = overtime.day.strip()  # Veritabanından gelen gün ismi

                    if calisma_gunu.lower() == mesai_gunu.lower():
                        overtime_start = datetime.strptime(overtime.start_time, "%H:%M").time()
                        overtime_end = datetime.strptime(overtime.end_time, "%H:%M").time()

                        overtime_start_dt = datetime.combine(giris.date(), overtime_start)
                        overtime_end_dt = datetime.combine(giris.date(), overtime_end)

                        if cikis > overtime_start_dt and giris < overtime_end_dt:
                            overlap_start = max(giris, overtime_start_dt)
                            overlap_end = min(cikis, overtime_end_dt)
                            overtime_duration = (overlap_end - overlap_start).total_seconds() / 3600

                            if overtime_duration > 0.01:
                                overtime_hours_day += overtime_duration
                                overtime_amount = overtime_duration * hourly_rate * overtime.multiplier
                                overtime_pay += overtime_amount

                                overtime_details.append({
                                    "date": giris.strftime("%d.%m.%Y"),
                                    "hours": round(overtime_duration, 2),
                                    "multiplier": overtime.multiplier,
                                    "amount": round(overtime_amount, 2)
                                })

                # Normal çalışma saatleri
                normal_hours_day = worked_hours - overtime_hours_day
                if normal_hours_day > 0:
                    normal_details.append({
                        "date": giris.strftime("%d.%m.%Y"),
                        "hours": round(normal_hours_day, 2),
                        "amount": round(normal_hours_day * hourly_rate, 2)
                    })

                # Toplam fazla mesai saatlerini güncelle
                overtime_hours += overtime_hours_day

            # Özel günlerde çalışmayan personellere sabit bir günlük ödeme ekle
            for special in special_days:
                if special.date not in special_days_worked:
                    # Çalışılmayan özel gün için sabit bir günlük ödeme (örneğin 8 saatlik çalışma ücreti) 
                    fixed_payment = 8 * hourly_rate
                    special_day_pay += fixed_payment

                    special_day_details.append({
                        "date": special.date.strftime("%d.%m.%Y"),
                        "hours": 8,
                        "multiplier": 1.0,  # Çarpansız
                        "amount": round(fixed_payment, 2)
                    })

            izinler = IzinTalebi.query.filter(
                IzinTalebi.user_id == user.id,
                IzinTalebi.status == "İzin Verildi",
                IzinTalebi.start_date <= end_date,
                IzinTalebi.end_date >= start_date,
                IzinTalebi.reason == "Senelik"
            ).all()

            izin_saatleri = sum([
                ((izin.end_date - izin.start_date).days * 8) +
                ((datetime.strptime(izin.end_time, "%H:%M") - datetime.strptime(izin.start_time, "%H:%M")).seconds / 3600)
                for izin in izinler
            ])

            # Normal çalışma saatlerini topla
            normal_hours = sum([detail["hours"] for detail in normal_details])
            normal_pay = normal_hours * hourly_rate

            # Toplam maaş hesaplama
            total_salary = normal_pay + overtime_pay + special_day_pay + (izin_saatleri * hourly_rate)

            payroll_results.append({
                "user": user,
                "status": "✅ Hesaplama Tamamlandı",
                "net_salary": total_salary,
                "worked_hours": total_worked_hours,
                "normal_hours": normal_hours,
                "normal_pay": normal_pay,
                "normal_details": normal_details,
                "hourly_rate": hourly_rate,
                "overtime_hours": overtime_hours,
                "overtime_pay": overtime_pay,
                "overtime_details": overtime_details,
                "special_day_hours": special_day_hours,
                "special_day_pay": special_day_pay,
                "special_day_details": special_day_details,
                "annual_leave_hours": izin_saatleri,
                "annual_leave_pay": izin_saatleri * hourly_rate
            })

        return render_template("payroll.html", users=users, payroll_results=payroll_results)

    return render_template("payroll.html", users=users)





# Modül aç kapa kodu

# Modül Aç/Kapa Ayarları
@app.route("/admin/modul_ayarlar", methods=["GET", "POST"])
def modul_ayarlar():
    if "user_id" not in session or session.get("role") != "admin":
        return "Yetkisiz erişim!", 403

    if request.method == "POST":
        for role in ["personel", "manager", "factory_manager", "hr_manager", "admin"]:
            ayar = ModulAyarları.query.filter_by(role=role).first()
            if ayar:
                ayar.izin_modulu = request.form.get(f"izin_{role}") == "on"
                ayar.giris_cikis_modulu = request.form.get(f"giris_cikis_{role}") == "on"
                ayar.bordro_modulu = request.form.get(f"bordro_{role}") == "on"
                ayar.vardiya_modulu = request.form.get(f"vardiya_{role}") == "on"  # ✅ Yeni eklenen modül
        db.session.commit()
        flash("Modül ayarları güncellendi!", "success")
        return redirect(url_for("modul_ayarlar"))

    moduller = ModulAyarları.query.all()
    return render_template("modul_ayarlar.html", moduller=moduller)






import json
import random
from flask import session, flash, redirect, url_for, render_template, request
from twilio.rest import Client

# 📌 Twilio API Bilgileri  
TWILIO_ACCOUNT_SID = "ACcf644212580de8814867a0e3fd9b5607"
TWILIO_AUTH_TOKEN = "283fbb7a78fa071ac4026525afc6b147"
TWILIO_WHATSAPP_NUMBER = "whatsapp:+15153750115"
TWILIO_TEMPLATE_ID = "HXaa1625948d41cd5b3db285352422bc18"

client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN)

@app.route("/forgot_password", methods=["GET", "POST"])
def forgot_password():
    if request.method == "POST":
        phone_number = request.form.get("phone_number").strip()

        # 📌 Telefon numarasını normalize et
        normalized_phone = phone_number.replace(" ", "").replace("-", "")  # Boşluk ve tireleri kaldır
        if not normalized_phone.startswith("+90"):
            normalized_phone = "+90" + normalized_phone[-10:]  # Eksikse +90 ekle ve son 10 haneyi al

        # 📌 Kullanıcıyı Veritabanında Bul
        user = User.query.filter_by(phone_number=normalized_phone).first()
        if not user:
            flash("Bu telefon numarasıyla kayıtlı bir kullanıcı bulunamadı!", "danger")
            return redirect(url_for("forgot_password"))

        # 📌 6 Haneli Doğrulama Kodu Oluştur
        reset_code = str(random.randint(100000, 999999))

        # 📌 Doğrulama Kodunu Kullanıcının Oturumuna Kaydet (Geçici)
        session["reset_code"] = reset_code
        session["reset_phone"] = normalized_phone  # Normalleştirilmiş numarayı kaydet

        # 📌 Twilio ile Şifre Sıfırlama Kodu Gönder (Onaylı Şablon Kullanılarak)
        try:
            send_whatsapp_message(
                normalized_phone[1:],  # +90'ın başındaki "+" işaretini atıyoruz
                f"Şifre sıfırlama kodunuz: {reset_code}\nKodun süresi 10 dakikadır.\nhttps://izindefteri.com/"
            )

            flash("Şifre sıfırlama kodu WhatsApp üzerinden gönderildi!", "success")
            return redirect(url_for("verify_reset_code"))

        except Exception as e:
            flash(f"Mesaj gönderilirken hata oluştu: {str(e)}", "danger")
            return redirect(url_for("forgot_password"))

    return render_template("forgot_password.html")




@app.route("/verify_reset_code", methods=["GET", "POST"])
def verify_reset_code():
    if request.method == "POST":
        user_code = request.form.get("reset_code")

        # 📌 Oturumdaki Kodu Kontrol Et
        if "reset_code" in session and session["reset_code"] == user_code:
            flash("Doğrulama başarılı! Yeni şifrenizi belirleyebilirsiniz.", "success")
            return redirect(url_for("reset_password"))
        else:
            flash("Geçersiz kod! Lütfen tekrar deneyin.", "danger")

    return render_template("verify_reset_code.html")



@app.route("/reset_password", methods=["GET", "POST"])
def reset_password():
    if request.method == "POST":
        new_password = request.form.get("new_password")

        # 📌 Kullanıcıyı Telefon Numarasına Göre Bul
        phone_number = session.get("reset_phone")
        user = User.query.filter_by(phone_number=phone_number).first()
        
        if user:
            user.password = new_password  # 📌 Yeni Şifreyi Kaydet (Şifreleme yok)
            db.session.commit()

            # 📌 Oturum Verilerini Temizle
            session.pop("reset_code", None)
            session.pop("reset_phone", None)

            flash("Şifreniz başarıyla sıfırlandı! Giriş yapabilirsiniz.", "success")
            return redirect(url_for("login"))
        else:
            flash("Bir hata oluştu! Lütfen tekrar deneyin.", "danger")

    return render_template("reset_password.html")



@app.route("/settings")
def settings():
    if "user_id" not in session:
        return redirect(url_for("login"))

    user = User.query.get(session["user_id"])
    return render_template("settings.html", phone_number=user.phone_number)



@app.route("/update_phone", methods=["POST"])
def update_phone():
    if "user_id" not in session:
        return redirect(url_for("login"))

    user = User.query.get(session["user_id"])
    new_phone = request.form.get("phone_number").strip()

    # 📌 Numaranın başına +90 ekleyerek normalize et
    normalized_phone = f"+90{new_phone}"

    # 📌 Telefon numarasını güncelle
    user.phone_number = normalized_phone
    db.session.commit()

    flash("✅ Telefon numaranız başarıyla güncellendi!", "success")
    return redirect(url_for("settings"))




@app.route("/update_password", methods=["POST"])
def update_password():
    if "user_id" not in session:
        return redirect(url_for("login"))

    user = User.query.get(session["user_id"])
    old_password = request.form.get("old_password")
    new_password = request.form.get("new_password")
    confirm_password = request.form.get("confirm_password")

    # 📌 Eski şifre doğrulaması
    if user.password != old_password:
        flash("❌ Mevcut şifreniz yanlış!", "danger")
        return redirect(url_for("settings"))

    # 📌 Yeni şifrelerin eşleştiğini kontrol et
    if new_password != confirm_password:
        flash("❌ Yeni şifreler uyuşmuyor! Lütfen tekrar deneyin.", "danger")
        return redirect(url_for("settings"))

    # 📌 Şifreyi güncelle
    user.password = new_password
    db.session.commit()

    flash("✅ Şifreniz başarıyla güncellendi!", "success")
    return redirect(url_for("settings"))




def allowed_file(filename):
    """Dosya uzantısını kontrol eder."""
    ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


from flask import flash
from werkzeug.utils import secure_filename
from PIL import Image  # 📌 Pillow ile görsel işleme
import os

UPLOAD_FOLDER = 'static/uploads'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
MAX_FILE_SIZE = 2 * 1024 * 1024  # 2MB
MAX_WIDTH = 800  # Maksimum genişlik (piksel)

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER


# **Görsel Dosya Kontrolleri**  
@app.route("/bilgilendirme_ekle", methods=["GET", "POST"])
def bilgilendirme_ekle():
    if "user_id" not in session:
        return "Yetkisiz erişim!", 403

    role = session.get("role")
    department = session.get("department")

    # 🔹 Admin ve İK Müdürü her zaman ekleme yapabilir
    if role not in ["admin", "hr_manager"]:
        # 🔹 Fabrika Müdürü veya Yönetici ise, sadece "İnsan Kaynakları" departmanında ise ekleme yapabilir
        if role in ["factory_manager", "manager"] and department and any(dep in department for dep in ["İnsan Kaynakları", "Planlama"]):
            pass  # Yetkilendirildi
        else:
            return "Yetkisiz erişim!", 403

    bolumler = Department.query.all()  # Tüm bölümleri çek

    if request.method == "POST":
        title = request.form.get("title")
        message = request.form.get("message")
        selected_departments = request.form.getlist("departments")

        if not title or not message or not selected_departments:
            flash("Başlık, mesaj ve en az bir bölüm seçmelisiniz!", "danger")
            return redirect(url_for("bilgilendirme_ekle"))

        departments_str = ",".join(map(str, selected_departments))

        # 📌 Görsel Yükleme İşlemi
        image_path = None
        if "image" in request.files:
            image = request.files["image"]
            if image.filename != "":
                if not allowed_file(image.filename):
                    flash("Sadece PNG, JPG, JPEG ve GIF formatları desteklenmektedir!", "danger")
                    return redirect(url_for("bilgilendirme_ekle"))

                filename = secure_filename(image.filename)
                filepath = os.path.join(app.config["UPLOAD_FOLDER"], filename)
                image.save(filepath)

                img = Image.open(filepath)
                if img.width > MAX_WIDTH:
                    ratio = MAX_WIDTH / img.width
                    new_height = int(img.height * ratio)
                    img = img.resize((MAX_WIDTH, new_height), Image.LANCZOS)
                    img.save(filepath, optimize=True, quality=85)

                image_path = f"static/uploads/{filename}"

        # 📌 Yeni Bilgilendirme Kaydı
        yeni_mesaj = Bilgilendirme(
            title=title,
            message=message,
            image_path=image_path,
            departments=departments_str
        )

        db.session.add(yeni_mesaj)
        db.session.commit()

        flash("Bilgilendirme mesajı başarıyla eklendi!", "success")
        return redirect(url_for("bilgilendirme_listesi"))

    return render_template("bilgilendirme_ekle.html", bolumler=bolumler)






from flask import jsonify, render_template, session
from sqlalchemy import or_

@app.route("/bilgilendirme_listesi")
def bilgilendirme_listesi():
    if "user_id" not in session:
        return "Yetkisiz erişim!", 403

    user_id = session["user_id"]
    user = User.query.get(user_id)  # Kullanıcıyı al

    if not user:
        return "Kullanıcı bulunamadı!", 404

    # Admin, HR Manager veya İnsan Kaynakları bölümüne sahip kullanıcılar tüm mesajları görsün
    tum_mesajlari_gorebilir = user.role in ["admin", "hr_manager"] or "İnsan Kaynakları" in user.department.split(",")

    if tum_mesajlari_gorebilir:
        filtreli_mesajlar = Bilgilendirme.query.order_by(Bilgilendirme.created_at.desc()).all()
    else:
        user_departments = user.department.split(",")
        department_ids = [
            str(dep.id) for dep in Department.query.filter(Department.name.in_(user_departments)).all()
        ]

        if not department_ids:
            return render_template("bilgilendirme_listesi.html", mesajlar=[])

        filtreli_mesajlar = Bilgilendirme.query.filter(
            or_(
                Bilgilendirme.departments == dep_id
                for dep_id in department_ids
            ) | or_(
                Bilgilendirme.departments.like(f"{dep_id},%")
                for dep_id in department_ids
            ) | or_(
                Bilgilendirme.departments.like(f"%,{dep_id},%")
                for dep_id in department_ids
            ) | or_(
                Bilgilendirme.departments.like(f"%,{dep_id}")
                for dep_id in department_ids
            )
        ).order_by(Bilgilendirme.created_at.desc()).all()

    # Kullanıcının okuduğu mesajları al
    okunan_mesajlar = {mesaj.mesaj_id for mesaj in UserReadMessage.query.filter_by(user_id=user_id).all()}

    return render_template("bilgilendirme_listesi.html", mesajlar=filtreli_mesajlar, okunan_mesajlar=okunan_mesajlar)


@app.route("/okunmamis_mesaj_sayisi", methods=["GET"])
def okunmamis_mesaj_sayisi():
    if "user_id" not in session:
        return jsonify({"success": False, "error": "Yetkisiz erişim!"}), 403

    user_id = session["user_id"]
    user = User.query.get(user_id)

    if not user:
        return jsonify({"success": False, "error": "Kullanıcı bulunamadı!"}), 404

    # Kullanıcı admin, HR Manager veya İnsan Kaynakları bölümü ise tüm mesajları görebilsin
    tum_mesajlari_gorebilir = user.role in ["admin", "hr_manager"] or "İnsan Kaynakları" in user.department.split(",")

    if tum_mesajlari_gorebilir:
        okunmamis_mesajlar = Bilgilendirme.query.filter(
            ~Bilgilendirme.id.in_(
                db.session.query(UserReadMessage.mesaj_id).filter_by(user_id=user_id)
            )
        ).all()
    else:
        user_departments = user.department.split(",")
        department_ids = [
            str(dep.id) for dep in Department.query.filter(Department.name.in_(user_departments)).all()
        ]

        if not department_ids:
            return jsonify({"success": True, "okunmamis_sayi": 0})  # Eğer bölümü yoksa 0 döndür

        okunmamis_mesajlar = Bilgilendirme.query.filter(
            or_(
                Bilgilendirme.departments.ilike(f"{dep_id}") for dep_id in department_ids
            ) | or_(
                Bilgilendirme.departments.ilike(f"{dep_id},%") for dep_id in department_ids
            ) | or_(
                Bilgilendirme.departments.ilike(f"%,{dep_id},%") for dep_id in department_ids
            ) | or_(
                Bilgilendirme.departments.ilike(f"%,{dep_id}") for dep_id in department_ids
            )
        ).filter(~Bilgilendirme.id.in_(
            db.session.query(UserReadMessage.mesaj_id).filter_by(user_id=user_id)
        )).all()

    okunmamis_sayi = len(okunmamis_mesajlar)

    print(f"Kullanıcının Bölümleri: {user.department.split(',')}")
    if not tum_mesajlari_gorebilir:
        print(f"Kullanıcının Bölüm ID'leri: {department_ids}")
    print(f"Kullanıcının Okuduğu Mesajlar: {[mesaj.mesaj_id for mesaj in db.session.query(UserReadMessage.mesaj_id).filter_by(user_id=user_id).all()]}")
    print(f"Gerçek Okunmamış Mesaj ID'leri: {[mesaj.id for mesaj in okunmamis_mesajlar]}")
    print(f"✅ Backend dönen okunmamış mesaj sayısı: {okunmamis_sayi}")

    return jsonify({"success": True, "okunmamis_sayi": okunmamis_sayi})


@app.route("/okundu_isaretle/<int:mesaj_id>", methods=["POST"])
def okundu_isaretle(mesaj_id):
    if "user_id" not in session:
        return jsonify({"success": False, "error": "Yetkisiz erişim!"}), 403

    user_id = session["user_id"]
    user = User.query.get(user_id)

    if not user:
        return jsonify({"success": False, "error": "Kullanıcı bulunamadı!"}), 404

    # Eğer zaten okunmuşsa tekrar eklememek için kontrol et
    okunmus_mesaj = UserReadMessage.query.filter_by(user_id=user_id, mesaj_id=mesaj_id).first()

    if not okunmus_mesaj:
        yeni_kayit = UserReadMessage(user_id=user_id, mesaj_id=mesaj_id)
        db.session.add(yeni_kayit)
        db.session.commit()

    return jsonify({"success": True})



@app.route("/bilgilendirme_sil/<int:mesaj_id>", methods=["DELETE"])
def bilgilendirme_sil(mesaj_id):
    if "user_id" not in session:
        return jsonify({"success": False, "error": "Yetkisiz erişim!"}), 403

    role = session.get("role")
    department = session.get("department", "")

    # 🔹 Admin ve İK Müdürü her zaman silebilir
    if role in ["admin", "hr_manager"]:
        pass
    # 🔹 Fabrika Müdürü veya Yönetici ise, sadece "İnsan Kaynakları" veya "Planlama" departmanında ise silebilir
    elif role in ["factory_manager", "manager"] and any(dep in department for dep in ["İnsan Kaynakları", "Planlama"]):
        pass
    else:
        return jsonify({"success": False, "error": "Yetkisiz erişim!"}), 403

    mesaj = Bilgilendirme.query.get(mesaj_id)

    if not mesaj:
        return jsonify({"success": False, "error": "Mesaj bulunamadı!"}), 404

    # Eğer mesajın bir görseli varsa dosyayı da silelim
    if mesaj.image_path:
        image_path = os.path.join(app.root_path, mesaj.image_path)
        if os.path.exists(image_path):
            os.remove(image_path)

    # Mesajı veritabanından sil
    db.session.delete(mesaj)
    db.session.commit()

    return jsonify({"success": True, "message": "Mesaj başarıyla silindi!"})




@app.route("/uretim")
def uretim():
    if "user_id" not in session:
        return "Yetkisiz erişim!", 403

    role = session.get("role")
    department = session.get("department", "")

    # 🔹 Yetkili roller ve bölümler
    authorized_roles = ["admin", "factory_manager", "manager", "personel"]
    authorized_departments = ["Planlama", "Enjeksiyon"]

    # 🔹 Yetki kontrolü
    if role in authorized_roles and any(dep in department for dep in authorized_departments):
        return render_template("uretim.html")

    return "Erişim yetkiniz yok.", 403





import os

BASE_DIR = os.path.abspath(os.path.dirname(__file__))  # Proje klasörünün tam yolunu al
DATABASE_PATH = os.path.join(BASE_DIR, "instance", "izin_takip.db")

app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{DATABASE_PATH}"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

# Makineler Tablosu
class Makine(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    makine_turu = db.Column(db.String(50), nullable=False)  # Enjeksiyon, Kaynak, Dikiş vb.
    makine_adi = db.Column(db.String(100), nullable=False)
    marka = db.Column(db.String(50), nullable=True)
    model = db.Column(db.String(50), nullable=True)
    ozellik = db.Column(db.Text, nullable=True)

# Veritabanı oluşturma komutu (Sadece ilk çalıştırmada kullanın)
with app.app_context():
    db.create_all()






@app.route("/makine_ekle", methods=["GET", "POST"])
def makine_ekle():
    if "user_id" not in session:
        return redirect(url_for("login"))  # Giriş yapmayanları yönlendir

    user_department = session.get("department", "")

    # Sadece Planlama bölümündekiler makine ekleyebilir
    if "Planlama" not in user_department:
        return "Erişim yetkiniz yok.", 403

    if request.method == "POST":
        makine_turu = request.form.get("makine_turu")
        makine_adi = request.form.get("makine_adi")
        marka = request.form.get("marka")
        model = request.form.get("model")
        ozellik = request.form.get("ozellik")

        yeni_makine = Makine(
            makine_turu=makine_turu,
            makine_adi=makine_adi,
            marka=marka,
            model=model,
            ozellik=ozellik
        )

        db.session.add(yeni_makine)
        db.session.commit()

        return redirect(url_for("makine_ekle"))  # Eklendikten sonra sayfayı yenile

    # Veritabanındaki makineleri çek
    makineler = Makine.query.all()
    return render_template("makine_ekle.html", makineler=makineler)





@app.route("/makine_sil/<int:makine_id>", methods=["GET"])
def makine_sil(makine_id):
    if "user_id" not in session:
        return redirect(url_for("login"))

    user_department = session.get("department", "")

    # Sadece Planlama bölümü makineleri silebilir
    if "Planlama" not in user_department:
        return "Erişim yetkiniz yok.", 403

    makine = Makine.query.get(makine_id)

    if not makine:
        return "Makine bulunamadı.", 404

    db.session.delete(makine)
    db.session.commit()

    return redirect(url_for("makine_ekle"))  # Silindikten sonra listeye geri dön





@app.route("/makine_duzenle/<int:makine_id>", methods=["GET", "POST"])
def makine_duzenle(makine_id):
    if "user_id" not in session:
        return redirect(url_for("login"))

    user_department = session.get("department", "")

    # Sadece Planlama bölümü makineleri düzenleyebilir
    if "Planlama" not in user_department:
        return "Erişim yetkiniz yok.", 403

    makine = Makine.query.get(makine_id)

    if not makine:
        return "Makine bulunamadı.", 404

    if request.method == "POST":
        makine.makine_turu = request.form.get("makine_turu")
        makine.makine_adi = request.form.get("makine_adi")
        makine.marka = request.form.get("marka")
        makine.model = request.form.get("model")
        makine.ozellik = request.form.get("ozellik")

        db.session.commit()
        return redirect(url_for("makine_ekle"))  # Güncellendikten sonra listeye geri dön

    return render_template("makine_duzenle.html", makine=makine)



class Urun(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    urun_adi = db.Column(db.String(100), nullable=False)
    ortalama_cevrim_suresi = db.Column(db.Float, nullable=True)    
    barkod = db.Column(db.String(20), unique=True, nullable=True) 
    qr_kod = db.Column(db.String(255), unique=True, nullable=True)  



# Veritabanı oluşturma komutu (Sadece ilk çalıştırmada kullanın)  
with app.app_context():
    db.create_all()




@app.route("/urun_ekle", methods=["GET", "POST"])
def urun_ekle():
    if "user_id" not in session:
        return redirect(url_for("login"))

    user_department = session.get("department", "")

    if "Planlama" not in user_department:
        return "Erişim yetkiniz yok.", 403

    if request.method == "POST":
        urun_adi = request.form.get("urun_adi")
        ortalama_cevrim_suresi = request.form.get("ortalama_cevrim_suresi")  # ✅ **Mevcut alan**
        barkod = request.form.get("barkod")  # 🔵 **Yeni barkod alanı**
        qr_kod = request.form.get("qr_kod")  # 🔵 **Yeni QR kod alanı**

        yeni_urun = Urun(
            urun_adi=urun_adi,
            ortalama_cevrim_suresi=float(ortalama_cevrim_suresi) if ortalama_cevrim_suresi else None,
            barkod=barkod,  # ✅ **Barkod ekleme**
            qr_kod=qr_kod   # ✅ **QR kod ekleme**
        )

        db.session.add(yeni_urun)
        db.session.commit()

        return redirect(url_for("urun_ekle"))

    urunler = Urun.query.all()
    return render_template("urun_ekle.html", urunler=urunler)



with app.app_context():
    db.create_all()

@app.route("/urun_duzenle/<int:urun_id>", methods=["GET", "POST"])
def urun_duzenle(urun_id):
    if "user_id" not in session:
        return redirect(url_for("login"))

    user_department = session.get("department", "")

    if "Planlama" not in user_department:
        return "Erişim yetkiniz yok.", 403

    urun = Urun.query.get_or_404(urun_id)

    if request.method == "POST":
        urun.urun_adi = request.form.get("urun_adi")
        urun.ortalama_cevrim_suresi = request.form.get("ortalama_cevrim_suresi")
        urun.ortalama_cevrim_suresi = float(urun.ortalama_cevrim_suresi) if urun.ortalama_cevrim_suresi else None
        urun.barkod = request.form.get("barkod")  # 🔵 **Yeni barkod alanı**
        urun.qr_kod = request.form.get("qr_kod")  # 🔵 **Yeni QR kod alanı**

        db.session.commit()
        return redirect(url_for("urun_ekle"))

    return render_template("urun_duzenle.html", urun=urun)



@app.route("/urun_sil/<int:urun_id>", methods=["GET"])
def urun_sil(urun_id):
    if "user_id" not in session:
        return redirect(url_for("login"))

    user_department = session.get("department", "")

    # Sadece Planlama bölümü ürünleri silebilir
    if "Planlama" not in user_department:
        return "Erişim yetkiniz yok.", 403

    urun = Urun.query.get_or_404(urun_id)  # Eğer ürün yoksa 404 döndür

    db.session.delete(urun)
    db.session.commit()

    return redirect(url_for("urun_ekle"))  # Silindikten sonra listeye geri dön




class Renk(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    renk_adi = db.Column(db.String(100), nullable=False)

# Veritabanı oluşturma komutu (Sadece ilk çalıştırmada kullanın)
with app.app_context():
    db.create_all()




@app.route("/renk_ekle", methods=["GET", "POST"])
def renk_ekle():
    if "user_id" not in session:
        return redirect(url_for("login"))  # Giriş yapmayanları yönlendir

    user_department = session.get("department", "")

    # Sadece Planlama bölümü renk ekleyebilir
    if "Planlama" not in user_department:
        return "Erişim yetkiniz yok.", 403

    if request.method == "POST":
        renk_adi = request.form.get("renk_adi")

        yeni_renk = Renk(renk_adi=renk_adi)

        db.session.add(yeni_renk)
        db.session.commit()

        return redirect(url_for("renk_ekle"))  # Eklendikten sonra sayfayı yenile

    # Veritabanındaki renkleri çek
    renkler = Renk.query.all()
    return render_template("renk_ekle.html", renkler=renkler)




@app.route("/renk_duzenle/<int:renk_id>", methods=["GET", "POST"])
def renk_duzenle(renk_id):
    if "user_id" not in session:
        return redirect(url_for("login"))

    user_department = session.get("department", "")

    # Sadece Planlama bölümü renkleri düzenleyebilir
    if "Planlama" not in user_department:
        return "Erişim yetkiniz yok.", 403

    renk = Renk.query.get_or_404(renk_id)  # Eğer renk yoksa 404 döndür

    if request.method == "POST":
        renk.renk_adi = request.form.get("renk_adi")
        db.session.commit()
        return redirect(url_for("renk_ekle"))  # Güncellendikten sonra listeye geri dön

    return render_template("renk_duzenle.html", renk=renk)



@app.route("/renk_sil/<int:renk_id>", methods=["GET"])
def renk_sil(renk_id):
    if "user_id" not in session:
        return redirect(url_for("login"))

    user_department = session.get("department", "")

    # Sadece Planlama bölümü renkleri silebilir
    if "Planlama" not in user_department:
        return "Erişim yetkiniz yok.", 403

    renk = Renk.query.get_or_404(renk_id)  # Eğer renk yoksa 404 döndür

    db.session.delete(renk)
    db.session.commit()

    return redirect(url_for("renk_ekle"))  # Silindikten sonra listeye geri dön




from datetime import datetime
from sqlalchemy.orm import relationship


class IsEmri(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    is_emri_no = db.Column(db.String(50), unique=True, nullable=False)  # 📌 İş Emri No Alanı Eklendi
    urun_id = db.Column(db.Integer, db.ForeignKey("urun.id"), nullable=False)
    renk_id = db.Column(db.Integer, db.ForeignKey("renk.id"), nullable=False)
    makine_id = db.Column(db.Integer, db.ForeignKey("makine.id"), nullable=False)
    miktar = db.Column(db.Integer, nullable=False)
    aciklama = db.Column(db.Text)
    durum = db.Column(db.String(20), default="Başlamadı")
    tarih_saat = db.Column(db.DateTime, default=datetime.utcnow)

    # **Zaman bilgileri**
    baslangic_zamani = db.Column(db.DateTime, nullable=True)  # Üretimin başladığı an
    tamamlanma_zamani = db.Column(db.DateTime, nullable=True)  # Üretimin bittiği an

    # **İlişkiler (ForeignKey ile bağlanan tablolar)**
    urun = db.relationship("Urun", backref="is_emirleri")
    renk = db.relationship("Renk", backref="is_emirleri")
    makine = db.relationship("Makine", backref="is_emirleri")

    # **Üretim kaliteleri**
    kalite_1 = db.Column(db.Integer, default=0)
    kalite_2 = db.Column(db.Integer, default=0)
    kalite_3 = db.Column(db.Integer, default=0)
    fire = db.Column(db.Integer, default=0)

    # **Çevrim süresi verileri**
    son_islem_tarihi = db.Column(db.DateTime, nullable=True)
    ortalama_cevrim_suresi = db.Column(db.Float, default=0)

    # **Personel bilgileri (İş emrinde çalışan personeller)**
    personel1_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True)
    personel2_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True)
    personel3_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True)
    vardiya_ustasi_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True)

    # **İlişkiler**
    personel1 = db.relationship("User", foreign_keys=[personel1_id])
    personel2 = db.relationship("User", foreign_keys=[personel2_id])
    personel3 = db.relationship("User", foreign_keys=[personel3_id])
    vardiya_ustasi = db.relationship("User", foreign_keys=[vardiya_ustasi_id])

    # **Bekleme Süresi için gerekli alanlar**
    toplam_bekleme_suresi = db.Column(db.Float, default=0)

# 📌 **Veritabanını Güncelle**
with app.app_context():
    db.create_all()







from datetime import datetime
from sqlalchemy.orm import relationship

class UretimSureleri(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    is_emri_id = db.Column(db.Integer, db.ForeignKey("is_emri.id"), nullable=False)
    baslangic_zamani = db.Column(db.DateTime, nullable=False)
    bitis_zamani = db.Column(db.DateTime, nullable=True)  # Bitmemişse None kalır
    durum = db.Column(db.String(20), nullable=False)  # "Bekleme", "Devam", "Tamamlandı" 
    durus_nedeni = db.Column(db.String(255), nullable=True)  # 📌 **Yeni alan eklendi**

    is_emri = db.relationship("IsEmri", backref="uretim_sureleri")


class DurusNedenleri(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    neden = db.Column(db.String(255), nullable=False, unique=True)  # 🔹 Neden açıklaması (ör: "Makine Arızası")

    def __repr__(self):
        return f"<DurusNedenleri {self.neden}>"





class UretimKayit(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    is_emri_id = db.Column(db.Integer, db.ForeignKey("is_emri.id"), nullable=False)
    
    # İş emrinde görevli personeller
    personel1_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True)
    personel2_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True)
    personel3_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True)
    vardiya_ustasi_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True)

    kalite_turu = db.Column(db.String(20), nullable=False)  # "kalite_1", "kalite_2", "kalite_3", "fire"
    zaman = db.Column(db.DateTime, default=datetime.utcnow)  # Basıldığı anın zamanı

    # İlişkiler
    is_emri = db.relationship("IsEmri", backref="uretim_kayitlari")
    personel1 = db.relationship("User", foreign_keys=[personel1_id])
    personel2 = db.relationship("User", foreign_keys=[personel2_id])
    personel3 = db.relationship("User", foreign_keys=[personel3_id])
    vardiya_ustasi = db.relationship("User", foreign_keys=[vardiya_ustasi_id])

# 📌 **Veritabanını güncelle**
with app.app_context():
    db.create_all()







@app.route("/is_emri_ekle", methods=["GET", "POST"])
def is_emri_ekle():
    if "user_id" not in session:
        return redirect(url_for("login"))  # Giriş yapmayanları yönlendir

    user_department = session.get("department", "")

    # Sadece Planlama bölümü iş emri ekleyebilir
    if "Planlama" not in user_department:
        return "Erişim yetkiniz yok.", 403

    if request.method == "POST":
        is_emri_no = request.form.get("is_emri_no")  # 📌 **İş Emri No formdan alındı**
        urun_id = request.form.get("urun_id")
        renk_id = request.form.get("renk_id")
        makine_id = request.form.get("makine_id")
        miktar = request.form.get("miktar")
        aciklama = request.form.get("aciklama")

        # 📌 **Eğer İş Emri No girilmemişse, otomatik oluştur**
        if not is_emri_no:
            son_emir = IsEmri.query.order_by(IsEmri.id.desc()).first()
            is_emri_no = f"EMR-{(son_emir.id + 1) if son_emir else 1}"

        yeni_is_emri = IsEmri(
            is_emri_no=is_emri_no,  # 📌 **Yeni Alan Eklendi**
            urun_id=urun_id,
            renk_id=renk_id,
            makine_id=makine_id,
            miktar=miktar,
            aciklama=aciklama
        )

        db.session.add(yeni_is_emri)
        db.session.commit()

        return redirect(url_for("is_emri_ekle"))  # Eklendikten sonra sayfayı yenile

    # Veritabanındaki ürünleri, renkleri ve makineleri çek
    urunler = Urun.query.all()
    renkler = Renk.query.all()
    makineler = Makine.query.all()

    # Varsayılan olarak sadece "Başlamadı", "Devam Ediyor" ve "Duruş" durumundakileri gösterelim
    is_emirleri = IsEmri.query.filter(IsEmri.durum.in_(["Başlamadı", "Devam Ediyor", "Duruş"])).all()

    return render_template("is_emri_ekle.html", urunler=urunler, renkler=renkler, makineler=makineler, is_emirleri=is_emirleri)




@app.route("/is_emri_duzenle/<int:is_emri_id>", methods=["GET", "POST"])
def is_emri_duzenle(is_emri_id):
    if "user_id" not in session:
        return redirect(url_for("login"))

    user_department = session.get("department", "")

    # Sadece Planlama bölümü iş emirlerini düzenleyebilir
    if "Planlama" not in user_department:
        return "Erişim yetkiniz yok.", 403

    is_emri = IsEmri.query.get_or_404(is_emri_id)  # Eğer iş emri yoksa 404 döndür

    if request.method == "POST":
        is_emri.is_emri_no = request.form.get("is_emri_no")  # 📌 **İş Emri No Güncellenebilir**
        is_emri.urun_id = request.form.get("urun_id")
        is_emri.renk_id = request.form.get("renk_id")
        is_emri.makine_id = request.form.get("makine_id")
        is_emri.miktar = request.form.get("miktar")
        is_emri.aciklama = request.form.get("aciklama")
        is_emri.durum = request.form.get("durum")

        db.session.commit()
        return redirect(url_for("is_emri_ekle"))  # Güncellendikten sonra listeye geri dön

    # Güncelleme için mevcut ürünleri, renkleri ve makineleri listeleyelim
    urunler = Urun.query.all()
    renkler = Renk.query.all()
    makineler = Makine.query.all()

    return render_template("is_emri_duzenle.html", is_emri=is_emri, urunler=urunler, renkler=renkler, makineler=makineler)





@app.route("/is_emri_sil/<int:is_emri_id>", methods=["GET"])
def is_emri_sil(is_emri_id):
    if "user_id" not in session:
        return redirect(url_for("login"))

    user_department = session.get("department", "")

    # Sadece Planlama bölümü iş emirlerini silebilir
    if "Planlama" not in user_department:
        return "Erişim yetkiniz yok.", 403

    is_emri = IsEmri.query.get_or_404(is_emri_id)  # Eğer iş emri yoksa 404 döndür

    db.session.delete(is_emri)
    db.session.commit()

    return redirect(url_for("is_emri_ekle"))  # Silindikten sonra listeye geri dön






@app.route("/is_emirleri")
def is_emirleri():
    if "user_id" not in session:
        return redirect(url_for("login"))  # Giriş yapmayanları yönlendir

    # ✅ Tüm iş emirlerini getir
    is_emirleri = IsEmri.query.all()

    return render_template("is_emirleri.html", is_emirleri=is_emirleri)





@app.route("/is_emri_goruntule/<int:is_emri_id>", methods=["GET", "POST"])
def is_emri_goruntule(is_emri_id):
    if "user_id" not in session:
        return redirect(url_for("login"))  

    is_emri = IsEmri.query.get_or_404(is_emri_id)
    makineler = Makine.query.all()
    personeller = User.query.filter(User.department == "Enjeksiyon").all()

    if request.method == "POST":
        print("📌 FORM GÖNDERİLDİ!")  # Butona basıldı mı?

        # 📌 **Ham Form Verilerini Terminale Yaz**
        print(f"📌 HAM FORM VERİLERİ: {request.form}")

        makine_id = request.form.get("makine_id")
        personel1_id = request.form.get("personel1")
        personel2_id = request.form.get("personel2")
        personel3_id = request.form.get("personel3")
        vardiya_ustasi_id = request.form.get("vardiya_ustasi")

        print(f"📌 FORM VERİLERİ -> P1: {personel1_id}, P2: {personel2_id}, P3: {personel3_id}, VU: {vardiya_ustasi_id}")

        # 📌 **Geçerli bir makine seçildi mi?**
        if not makine_id:
            flash("⚠️ Makine seçilmelidir!", "danger")
            return redirect(url_for("is_emri_goruntule", is_emri_id=is_emri.id))

        # 📌 **En az 1 personel atanmış mı?**
        if not any([personel1_id, personel2_id, personel3_id]):
            flash("⚠️ En az bir personel seçilmelidir!", "danger")
            return redirect(url_for("is_emri_goruntule", is_emri_id=is_emri.id))

        # 📌 **Seçilen personel ID'leri integer olarak kaydet (boş değerler None olacak)**
        is_emri.makine_id = int(makine_id)
        is_emri.personel1_id = int(personel1_id) if personel1_id else None
        is_emri.personel2_id = int(personel2_id) if personel2_id else None
        is_emri.personel3_id = int(personel3_id) if personel3_id else None
        is_emri.vardiya_ustasi_id = int(vardiya_ustasi_id) if vardiya_ustasi_id else None

        print(f"🔍 DB'YE KAYDEDİLİYOR -> P1: {is_emri.personel1_id}, P2: {is_emri.personel2_id}, P3: {is_emri.personel3_id}, VU: {is_emri.vardiya_ustasi_id}")

        db.session.commit()

        is_emri_check = IsEmri.query.get(is_emri.id)  
        print(f"✅ DB SONRASI KONTROL -> P1: {is_emri_check.personel1_id}, P2: {is_emri_check.personel2_id}, P3: {is_emri_check.personel3_id}, VU: {is_emri_check.vardiya_ustasi_id}")

        flash("✅ İş emri başarıyla başlatıldı.", "success")
        return redirect(url_for("uretim_takip", is_emri_id=is_emri.id))

    return render_template("is_emri_goruntule.html", is_emri=is_emri, makineler=makineler, personeller=personeller)



# İş emri butonlarının olduğu sayfa
from datetime import datetime, timedelta

@app.route("/is_emri_uretim/<int:is_emri_id>", methods=["POST"])
def is_emri_uretim(is_emri_id):
    if "user_id" not in session:
        return redirect(url_for("login"))

    is_emri = IsEmri.query.get_or_404(is_emri_id)

    # Gelen buton verisine göre kalite miktarını artır
    kalite_turu = request.form.get("kalite_turu")

    # Şu anki zamanı kaydet
    su_an = datetime.utcnow()

    # Çevrim süresi hesaplaması için önceki basım ile farkı alıyoruz
    if is_emri.son_islem_tarihi:
        gecen_sure = (su_an - is_emri.son_islem_tarihi).total_seconds()
    else:
        gecen_sure = None  # İlk işlem

    is_emri.son_islem_tarihi = su_an  # Yeni işlem zamanını kaydet

    # Kalite türüne göre verileri güncelle
    if kalite_turu == "1_kalite":
        is_emri.kalite_1 = (is_emri.kalite_1 or 0) + 1
        if is_emri.en_kisa_cevrim is None or (gecen_sure and gecen_sure < is_emri.en_kisa_cevrim):
            is_emri.en_kisa_cevrim = gecen_sure  # En kısa çevrim süresini güncelle
    elif kalite_turu == "2_kalite":
        is_emri.kalite_2 = (is_emri.kalite_2 or 0) + 1
    elif kalite_turu == "3_kalite":
        is_emri.kalite_3 = (is_emri.kalite_3 or 0) + 1
    elif kalite_turu == "fire":
        is_emri.fire = (is_emri.fire or 0) + 1

    # Toplam çevrim süresi ve ortalama hesaplaması
    if gecen_sure:
        is_emri.toplam_cevrim_suresi = (is_emri.toplam_cevrim_suresi or 0) + gecen_sure
        is_emri.islem_sayisi = (is_emri.islem_sayisi or 0) + 1
        is_emri.ortalama_cevrim_suresi = is_emri.toplam_cevrim_suresi / is_emri.islem_sayisi

    db.session.commit()

    return redirect(url_for("is_emri_goruntule", is_emri_id=is_emri.id))



from flask import request, jsonify

@app.route("/dogrula_sifre", methods=["POST"])
def dogrula_sifre():
    data = request.get_json()
    personel_id = data.get("personel_id")
    girilen_sifre = data.get("sifre")

    personel = User.query.get(personel_id)
    
    if not personel:
        return jsonify({"success": False, "error": "Personel bulunamadı!"}), 404



    # 📌 **Düz metin şifre karşılaştırması yapıyoruz**
    if personel.password.strip() != girilen_sifre.strip():

        return jsonify({"success": False, "error": "Hatalı şifre!"}), 403


    return jsonify({"success": True})






from datetime import datetime

@app.route("/uretim_guncelle/<int:is_emri_id>", methods=["POST"])
def uretim_guncelle(is_emri_id):
    if "user_id" not in session:
        return jsonify({"success": False, "error": "Yetkisiz erişim"}), 403

    is_emri = IsEmri.query.get_or_404(is_emri_id)
    data = request.get_json()
    kalite_turu = data.get("kalite_turu")
    now = datetime.utcnow()

    # 📌 **Son işlem zamanını güncelle**
    is_emri.son_islem_tarihi = now  # ✅ Güncellendi!

    # 📌 **Personeller boş olabilir, bu yüzden kontrol edelim**
    personel1_id = is_emri.personel1_id if is_emri.personel1_id else None
    personel2_id = is_emri.personel2_id if is_emri.personel2_id else None
    personel3_id = is_emri.personel3_id if is_emri.personel3_id else None
    vardiya_ustasi_id = is_emri.vardiya_ustasi_id if is_emri.vardiya_ustasi_id else None

    # 📌 **Üretim Kaydı Ekleyelim**
    yeni_kayit = UretimKayit(
        is_emri_id=is_emri.id,
        personel1_id=personel1_id,
        personel2_id=personel2_id,
        personel3_id=personel3_id,
        vardiya_ustasi_id=vardiya_ustasi_id,
        kalite_turu=kalite_turu,
        zaman=now
    )
    db.session.add(yeni_kayit)
    db.session.commit()  # ✅ Kayıt ID'si oluşması için burada commit!

    print(f"✅ Yeni Üretim Kaydı Eklendi -> ID: {yeni_kayit.id}")  # 📌 Terminalde ID'yi göster

    # 📌 **Kalite Türüne Göre Sayaç Güncelleme**
    if kalite_turu == "kalite_1":
        is_emri.kalite_1 += 1
    elif kalite_turu == "kalite_2":
        is_emri.kalite_2 += 1
    elif kalite_turu == "kalite_3":
        is_emri.kalite_3 += 1
    elif kalite_turu == "fire":
        is_emri.fire += 1
    else:
        return jsonify({"success": False, "error": "Geçersiz kalite türü"}), 400

    # 📌 **Toplam Üretilen Parça Hesapla**
    toplam_parca_sayisi = is_emri.kalite_1 + is_emri.kalite_2 + is_emri.kalite_3 + is_emri.fire

    # 📌 **Ortalama Çevrim Süresi Güncellemesi**
    baslangic_zamani = is_emri.baslangic_zamani
    son_islem_tarihi = now  # 📌 **Güncellenmiş son işlem tarihi**
    
    bekleme_kayitlari = UretimSureleri.query.filter_by(is_emri_id=is_emri.id, durum="Bekleme").all()
    toplam_bekleme_suresi = sum(
        (kayit.bitis_zamani - kayit.baslangic_zamani).total_seconds()
        for kayit in bekleme_kayitlari if kayit.bitis_zamani
    )

    if baslangic_zamani and toplam_parca_sayisi > 0:
        toplam_gecen_sure = (son_islem_tarihi - baslangic_zamani).total_seconds() - toplam_bekleme_suresi
        ortalama_cevrim_suresi = toplam_gecen_sure / toplam_parca_sayisi
    else:
        ortalama_cevrim_suresi = 0

    # 📌 **Formatlama Fonksiyonu**
    def format_sure(saniye):
        saat = int(saniye // 3600)
        dakika = int((saniye % 3600) // 60)
        saniye = int(saniye % 60)
        return f"{saat:02}:{dakika:02}:{saniye:02}"

    db.session.commit()  # ✅ **Son güncellemeleri kaydet!**

    return jsonify({
        "success": True,
        "kalite_1": is_emri.kalite_1,
        "kalite_2": is_emri.kalite_2,
        "kalite_3": is_emri.kalite_3,
        "fire": is_emri.fire,
        "ortalama_cevrim_suresi": format_sure(ortalama_cevrim_suresi),
        "uretim_kayit_id": yeni_kayit.id  # ✅ **Yeni eklenen kaydın ID'sini frontend'e yolluyoruz!**
    })






from datetime import datetime


@app.route("/uretim_durum_guncelle/<int:is_emri_id>", methods=["POST"])
def uretim_durum_guncelle(is_emri_id):
    if "user_id" not in session:
        return jsonify({"success": False, "error": "Yetkisiz erişim"}), 403

    is_emri = IsEmri.query.get_or_404(is_emri_id)
    data = request.get_json()
    yeni_durum = data.get("durum")
    durus_nedeni = data.get("durus_nedeni", None)  # ✅ **Duruş nedeni kontrolü**
    now = datetime.utcnow()

    # 📌 **Son işlem zamanını güncelle**
    is_emri.son_islem_tarihi = now  # ✅ Güncellendi!

    if yeni_durum == "Bekleme" or yeni_durum == "Beklemede":
        son_devam = UretimSureleri.query.filter_by(is_emri_id=is_emri.id, durum="Devam Ediyor").order_by(UretimSureleri.baslangic_zamani.desc()).first()
        if son_devam and not son_devam.bitis_zamani:
            son_devam.bitis_zamani = now  

        yeni_kayit = UretimSureleri(
            is_emri_id=is_emri.id, 
            baslangic_zamani=now, 
            durum="Bekleme", 
            durus_nedeni=durus_nedeni  # ✅ **Duruş nedeni ekleniyor**
        )
        db.session.add(yeni_kayit)

        is_emri.durum = "Bekleme"  # **📌 Güncelleme eklendi!**

    elif yeni_durum == "Devam Ediyor":
        # 📌 Eğer üretim ilk kez başlatılıyorsa, tabloyu kontrol et
        ilk_kayit_var_mi = UretimSureleri.query.filter_by(is_emri_id=is_emri.id).first()

        if not ilk_kayit_var_mi:
            # 📌 İlk kez "Başlat" butonuna basıldığında yeni kayıt oluştur
            yeni_kayit = UretimSureleri(
                is_emri_id=is_emri.id, 
                baslangic_zamani=now, 
                durum="Devam Ediyor"
            )
            db.session.add(yeni_kayit)
        else:
            son_bekleme = UretimSureleri.query.filter_by(is_emri_id=is_emri.id, durum="Bekleme").order_by(UretimSureleri.baslangic_zamani.desc()).first()
            if son_bekleme and not son_bekleme.bitis_zamani:
                son_bekleme.bitis_zamani = now  

            yeni_kayit = UretimSureleri(
                is_emri_id=is_emri.id, 
                baslangic_zamani=now, 
                durum="Devam Ediyor"
            )
            db.session.add(yeni_kayit)

        if not is_emri.baslangic_zamani:
            is_emri.baslangic_zamani = now

        is_emri.durum = "Devam Ediyor"

    elif yeni_durum == "Tamamlandı":
        son_devam = UretimSureleri.query.filter(
            UretimSureleri.is_emri_id == is_emri.id,
            UretimSureleri.durum == "Devam Ediyor",
            UretimSureleri.bitis_zamani == None
        ).order_by(UretimSureleri.baslangic_zamani.desc()).first()

        if son_devam:
            son_devam.bitis_zamani = now  
            son_devam.durum = "Tamamlandı"

        is_emri.tamamlanma_zamani = now
        is_emri.durum = "Tamamlandı"

        # 📌 **Ortalama Çevrim Süresini Hesapla ve Kaydet (Bekleme Süresi Çıkartıldı)**
        toplam_parca_sayisi = is_emri.kalite_1 + is_emri.kalite_2 + is_emri.kalite_3 + is_emri.fire

        if is_emri.baslangic_zamani and is_emri.tamamlanma_zamani and toplam_parca_sayisi > 0:
            toplam_gecen_sure = (is_emri.tamamlanma_zamani - is_emri.baslangic_zamani).total_seconds()

            # 📌 **Toplam bekleme süresini hesapla**
            toplam_bekleme_suresi = sum(
                (kayit.bitis_zamani - kayit.baslangic_zamani).total_seconds()
                for kayit in UretimSureleri.query.filter_by(is_emri_id=is_emri.id, durum="Bekleme").all()
                if kayit.bitis_zamani
            )

            # 📌 **Toplam geçen süreden bekleme süresini çıkararak ortalama çevrim süresini hesapla**
            net_uretim_suresi = toplam_gecen_sure - toplam_bekleme_suresi
            is_emri.ortalama_cevrim_suresi = net_uretim_suresi / toplam_parca_sayisi  # ✅ **DÜZELTİLDİ**
        else:
            is_emri.ortalama_cevrim_suresi = None  # Eğer hesaplanamazsa boş bırak


    db.session.commit()

     
    
    return jsonify({"success": True, "yeni_durum": is_emri.durum})





from datetime import datetime

@app.route("/uretim_takip/<int:is_emri_id>")
def uretim_takip(is_emri_id):
    if "user_id" not in session:
        return redirect(url_for("login"))

    is_emri = IsEmri.query.get_or_404(is_emri_id)

    # 📌 Başlangıç ve tamamlanma zamanlarını al
    baslangic_zamani = is_emri.baslangic_zamani if is_emri.baslangic_zamani else None
    tamamlanma_zamani = is_emri.tamamlanma_zamani if is_emri.tamamlanma_zamani else None
    son_islem_tarihi = is_emri.son_islem_tarihi if is_emri.son_islem_tarihi else None  # 📌 Eksik değişken eklendi!

    # 📌 Toplam bekleme süresini hesapla
    bekleme_kayitlari = UretimSureleri.query.filter_by(is_emri_id=is_emri.id, durum="Bekleme").all()

    # 📌 Bekleme süresi hesaplama
    toplam_bekleme_suresi = sum(
        (kayit.bitis_zamani - kayit.baslangic_zamani).total_seconds()
        for kayit in bekleme_kayitlari if kayit.bitis_zamani
    )

    # 📌 **Geçen süreyi hesapla** (Şu an - başlangıç - toplam bekleme süresi)
    def format_sure(saniye):
        saat = int(saniye // 3600)
        dakika = int((saniye % 3600) // 60)
        saniye = int(saniye % 60)
        return f"{saat:02}:{dakika:02}:{saniye:02}"

    gecen_sure_saniye = (datetime.utcnow() - baslangic_zamani).total_seconds() - toplam_bekleme_suresi if baslangic_zamani else 0
    gecen_sure_formatli = format_sure(gecen_sure_saniye)
    toplam_bekleme_suresi_formatli = format_sure(toplam_bekleme_suresi)

    # 📌 **Ortalama Çevrim Süresi Hesapla**
    toplam_parca_sayisi = is_emri.kalite_1 + is_emri.kalite_2 + is_emri.kalite_3 + is_emri.fire

    if baslangic_zamani and son_islem_tarihi and toplam_parca_sayisi > 0:
        toplam_gecen_sure = (son_islem_tarihi - baslangic_zamani).total_seconds() - toplam_bekleme_suresi
        ortalama_cevrim_suresi = toplam_gecen_sure / toplam_parca_sayisi
    else:
        ortalama_cevrim_suresi = 0

    ortalama_cevrim_suresi_formatli = format_sure(ortalama_cevrim_suresi)

    # 📌 En son üretim durumunu al
    son_kayit = UretimSureleri.query.filter_by(is_emri_id=is_emri.id)\
                                    .order_by(UretimSureleri.baslangic_zamani.desc()).first()

    # 📌 Eğer hiç üretim kaydı yoksa "Başlamadı" olarak varsay
    mevcut_durum = son_kayit.durum if son_kayit else "Başlamadı"

    # **Güncelleme yapmadan önce kontrol edelim**
    if is_emri.durum != mevcut_durum:
        is_emri.durum = mevcut_durum
        db.session.commit()  # **Veritabanına durumu kaydet!**

    durus_nedenleri = DurusNedenleri.query.all()
    return render_template(
        "uretim_takip.html",
        is_emri=is_emri,
        baslangic_zamani=baslangic_zamani,
        tamamlanma_zamani=tamamlanma_zamani,
        toplam_bekleme_suresi=toplam_bekleme_suresi_formatli,
        gecen_sure=gecen_sure_formatli,
        mevcut_durum=mevcut_durum,  # 📌 Şablona en son üretim durumunu ekledik
        ortalama_cevrim_suresi=ortalama_cevrim_suresi_formatli,  # 📌 Yeni eklenen veri!
        durus_nedenleri=durus_nedenleri  # 📌 EKLENDİ!
    )




# 📌 Bekleme Nedenlerini Listeleme ve Ekleme Sayfası
@app.route("/bekleme_nedenleri", methods=["GET", "POST"])
def bekleme_nedenleri():
    if "user_id" not in session:
        return redirect(url_for("login"))

    if request.method == "POST":
        neden = request.form.get("neden_adi")

       

        if neden and neden.strip():  # 📌 None veya boş değer kontrolü
            try:
                yeni_neden = DurusNedenleri(neden=neden.strip())
                db.session.add(yeni_neden)
                db.session.commit()
              
                flash("Bekleme nedeni eklendi.", "success")
            except Exception as e:
                db.session.rollback()  # 📌 Hata olursa işlemi geri al
               
                flash("Bir hata oluştu, lütfen tekrar deneyin.", "danger")

        else:
            flash("Lütfen bir bekleme nedeni girin!", "danger")

        return redirect(url_for("bekleme_nedenleri"))

    nedenler = DurusNedenleri.query.all()
 

    return render_template("bekleme_nedenleri.html", nedenler=nedenler)


# 📌 Bekleme Nedenini Düzenleme Route'u
@app.route("/bekleme_nedeni_duzenle/<int:neden_id>", methods=["GET", "POST"])
def bekleme_nedeni_duzenle(neden_id):
    if "user_id" not in session:
        return redirect(url_for("login"))

    neden = DurusNedenleri.query.get_or_404(neden_id)

    if request.method == "POST":
        yeni_neden = request.form.get("neden").strip()
        if yeni_neden:
            neden.neden = yeni_neden
            db.session.commit()
            flash("Bekleme nedeni güncellendi.", "success")
        else:
            flash("Lütfen bir bekleme nedeni girin!", "danger")

        return redirect(url_for("bekleme_nedenleri"))

    return render_template("bekleme_nedeni_duzenle.html", neden=neden)

# 📌 Bekleme Nedenini Silme Route'u
@app.route("/bekleme_nedeni_sil/<int:neden_id>", methods=["POST"])
def bekleme_nedeni_sil(neden_id):
    if "user_id" not in session:
        return redirect(url_for("login"))

    neden = DurusNedenleri.query.get_or_404(neden_id)
    db.session.delete(neden)
    db.session.commit()
    flash("Bekleme nedeni silindi.", "success")

    return redirect(url_for("bekleme_nedenleri"))




from sqlalchemy import func

@app.route("/is_emri_performans")
def is_emri_performans():
    # Devam eden iş emirlerini çek
    is_emirleri = IsEmri.query.filter(IsEmri.durum != "Tamamlandı").all()

    # Gönderilecek listeyi oluştur
    is_emri_listesi = []
    for is_emri in is_emirleri:
        # Kalite türlerini sayıyoruz
        kalite_sayilari = db.session.query(
            UretimKayit.kalite_turu, func.count(UretimKayit.kalite_turu)
        ).filter(UretimKayit.is_emri_id == is_emri.id).group_by(UretimKayit.kalite_turu).all()

        # Kalite türlerini bir sözlük olarak kaydedelim
        kalite_dagilimi = {
            "kalite_1": 0,
            "kalite_2": 0,
            "kalite_3": 0,
            "fire": 0
        }
        for kalite_turu, sayi in kalite_sayilari:
            kalite_dagilimi[kalite_turu] = sayi

        is_emri_listesi.append({
            "id": is_emri.id,
            "urun_adi": is_emri.urun.urun_adi if is_emri.urun else "Bilinmeyen Ürün",
            "miktar": is_emri.miktar,
            "aciklama": is_emri.aciklama if is_emri.aciklama else "Açıklama yok",
            "durum": is_emri.durum,
            "kalite_1": kalite_dagilimi["kalite_1"],
            "kalite_2": kalite_dagilimi["kalite_2"],
            "kalite_3": kalite_dagilimi["kalite_3"],
            "fire": kalite_dagilimi["fire"]
        })

    return render_template("is_emri_performans.html", is_emri_listesi=is_emri_listesi)






from sqlalchemy import func
from datetime import datetime

@app.route("/is_emri_performans_json")
def is_emri_performans_json():
    # Devam eden iş emirlerini çek
    is_emirleri = IsEmri.query.filter(IsEmri.durum != "Tamamlandı").all()

    # JSON için iş emirlerini hazırla
    is_emri_listesi = []
    for is_emri in is_emirleri:
        # 📌 Kalite türlerini sayıyoruz
        kalite_sayilari = db.session.query(
            UretimKayit.kalite_turu, func.count(UretimKayit.kalite_turu)
        ).filter(UretimKayit.is_emri_id == is_emri.id).group_by(UretimKayit.kalite_turu).all()

        # 📌 Kalite türlerini bir sözlük olarak kaydedelim
        kalite_dagilimi = {
            "kalite_1": 0,
            "kalite_2": 0,
            "kalite_3": 0,
            "fire": 0
        }
        for kalite_turu, sayi in kalite_sayilari:
            kalite_dagilimi[kalite_turu] = sayi

        # 📌 Başlangıç ve tamamlanma zamanlarını al
        baslangic_zamani = is_emri.baslangic_zamani
        son_islem_tarihi = is_emri.son_islem_tarihi

        # 📌 Bekleme sürelerini hesapla
        bekleme_kayitlari = UretimSureleri.query.filter_by(is_emri_id=is_emri.id, durum="Bekleme").all()
        toplam_bekleme_suresi = sum(
            (kayit.bitis_zamani - kayit.baslangic_zamani).total_seconds()
            for kayit in bekleme_kayitlari if kayit.bitis_zamani
        )

        # 📌 **Ortalama Çevrim Süresi Hesapla**
        toplam_parca_sayisi = (
            kalite_dagilimi["kalite_1"] +
            kalite_dagilimi["kalite_2"] +
            kalite_dagilimi["kalite_3"] +
            kalite_dagilimi["fire"]
        )

        if baslangic_zamani and son_islem_tarihi and toplam_parca_sayisi > 0:
            toplam_gecen_sure = (son_islem_tarihi - baslangic_zamani).total_seconds() - toplam_bekleme_suresi
            ortalama_cevrim_suresi = toplam_gecen_sure / toplam_parca_sayisi
        else:
            ortalama_cevrim_suresi = 0

        # 📌 Süreyi saat:dakika:saniye formatına çevir
        def format_sure(saniye):
            saat = int(saniye // 3600)
            dakika = int((saniye % 3600) // 60)
            saniye = int(saniye % 60)
            return f"{saat:02}:{dakika:02}:{saniye:02}"

        ortalama_cevrim_suresi_formatli = format_sure(ortalama_cevrim_suresi)

        # 📌 **Hedef Çevrim Süresi (Ürün tablosundan çekilecek)**
        hedef_cevrim_suresi = is_emri.urun.ortalama_cevrim_suresi if is_emri.urun and is_emri.urun.ortalama_cevrim_suresi else 0
        hedef_cevrim_suresi_formatli = format_sure(hedef_cevrim_suresi)

        is_emri_listesi.append({
            "id": is_emri.id,
            "urun_adi": is_emri.urun.urun_adi if is_emri.urun else "Bilinmeyen Ürün",
            "renk_adi": is_emri.renk.renk_adi if hasattr(is_emri, 'renk') and is_emri.renk else "Bilinmeyen Renk",  # ✅ Renk bilgisi eklendi
            "miktar": is_emri.miktar,
            "aciklama": is_emri.aciklama if is_emri.aciklama else "Açıklama yok",
            "makine_adi": is_emri.makine.makine_adi if hasattr(is_emri, 'makine') and is_emri.makine else "Bilinmeyen Makine",  # ✅ Makine bilgisi eklendi
            "durum": is_emri.durum,
            "kalite_1": kalite_dagilimi["kalite_1"],
            "kalite_2": kalite_dagilimi["kalite_2"],
            "kalite_3": kalite_dagilimi["kalite_3"],
            "fire": kalite_dagilimi["fire"],
            "ortalama_cevrim_suresi": ortalama_cevrim_suresi_formatli,
            "hedef_cevrim_suresi": hedef_cevrim_suresi_formatli,  # ✅ Yeni eklenen alan
            "barkod": is_emri.urun.barkod if hasattr(is_emri, 'urun') and is_emri.urun and is_emri.urun.barkod else None,  # 🟠 Barkod eklendi
            "qr_kod": is_emri.urun.qr_kod if hasattr(is_emri, 'urun') and is_emri.urun and is_emri.urun.qr_kod else None  # 🟠 QR Kod Linki eklendi
        })


    return jsonify(is_emri_listesi)



from flask import Flask, render_template, request, jsonify
from datetime import datetime, timedelta
from sqlalchemy import func

@app.route("/personel_performans", methods=["GET"])
def personel_performans():
    baslangic_tarihi = request.args.get("baslangic_tarihi")
    bitis_tarihi = request.args.get("bitis_tarihi")

    if not baslangic_tarihi or not bitis_tarihi:
        return render_template("personel_performans.html", personel_raporu=[], baslangic_tarihi="", bitis_tarihi="")

    baslangic_tarihi = datetime.strptime(baslangic_tarihi, "%Y-%m-%d")
    bitis_tarihi = datetime.strptime(bitis_tarihi, "%Y-%m-%d") + timedelta(days=1) - timedelta(seconds=1)

    personeller = User.query.filter(User.department == "Enjeksiyon").all()
    personel_raporu = []

    toplam_uretim = db.session.query(func.count(UretimKayit.id))\
        .filter(UretimKayit.zaman >= baslangic_tarihi, UretimKayit.zaman <= bitis_tarihi)\
        .scalar() or 0  

    if toplam_uretim == 0:
        return render_template("personel_performans.html", personel_raporu=[], baslangic_tarihi=baslangic_tarihi.strftime("%Y-%m-%d"), bitis_tarihi=bitis_tarihi.strftime("%Y-%m-%d"))

    for personel in personeller:
        uretim_kayitlari = UretimKayit.query\
            .filter(
                UretimKayit.zaman >= baslangic_tarihi,
                UretimKayit.zaman <= bitis_tarihi,
                (UretimKayit.personel1_id == personel.id) |
                (UretimKayit.personel2_id == personel.id) |
                (UretimKayit.personel3_id == personel.id)
            ).order_by(UretimKayit.is_emri_id, UretimKayit.zaman).all()

        is_emri_gruplari = []
        onceki_is_emri = None
        onceki_personel = None
        blok = []

        for kayit in uretim_kayitlari:
            if onceki_is_emri is None or kayit.is_emri_id != onceki_is_emri or onceki_personel != kayit.personel1_id:
                if blok:
                    is_emri_gruplari.append(blok)
                blok = []

            blok.append(kayit)
            onceki_is_emri = kayit.is_emri_id
            onceki_personel = kayit.personel1_id

        if blok:
            is_emri_gruplari.append(blok)

        toplam_cevrim_suresi = 0
        toplam_cevrim_sayisi = 0
        toplam_puan = 0
        detay_listesi = []

        for grup in is_emri_gruplari:
            is_emri_id = grup[0].is_emri_id
            is_emri = IsEmri.query.get(is_emri_id)

            hedef_cevrim_suresi = is_emri.urun.ortalama_cevrim_suresi if is_emri and is_emri.urun else 20

            uretim_sayisi = len(grup) if grup else 0
            baslangic_zamani = grup[0].zaman if grup else None
            bitis_zamani = grup[-1].zaman if grup else None
            gecen_sure = (bitis_zamani - baslangic_zamani).total_seconds() if baslangic_zamani and bitis_zamani else 0

            ortalama_cevrim_suresi = gecen_sure / uretim_sayisi if uretim_sayisi > 0 else 0
            cevrim_suresi_orani = round((hedef_cevrim_suresi / ortalama_cevrim_suresi) * 100, 2) if ortalama_cevrim_suresi > 0 else 0

            toplam_cevrim_suresi += gecen_sure
            toplam_cevrim_sayisi += uretim_sayisi

            detay_listesi.append({
                "is_emri_no": is_emri.is_emri_no if is_emri else "Bilinmiyor",
                "toplam_cevrim_suresi": round(gecen_sure, 2),
                "uretim_sayisi": uretim_sayisi,
                "hedef_cevrim_suresi": hedef_cevrim_suresi,
                "cevrim_suresi_orani": cevrim_suresi_orani
            })

        ortalama_cevrim_suresi_orani = round(sum(d["cevrim_suresi_orani"] for d in detay_listesi) / len(detay_listesi), 2) if detay_listesi else 0

        uretim_yuzdesi = (toplam_cevrim_sayisi / toplam_uretim) * 100 if toplam_cevrim_sayisi else 0

        toplam_puan = round(
            (uretim_yuzdesi * 0.3) +
            ((100 - min(abs(100 - ortalama_cevrim_suresi_orani), 100)) * 0.7), 2
        )
        # ✅ Fotoğraf yolu ekleniyor
        foto_kayit = UserPhoto.query.filter_by(user_id=personel.id).first()
        foto_path = f"static/uploads/{foto_kayit.photo_path}" if foto_kayit else "static/uploads/person.png"


        personel_raporu.append({
            "id": personel.id,
            "ad_soyad": f"{personel.first_name} {personel.last_name}",
            "uretim_sayisi": toplam_cevrim_sayisi or 0,  # ✅ Eğer None ise 0 ata
            "uretim_yuzdesi": round(uretim_yuzdesi, 2),
            "cevrim_suresi_orani": ortalama_cevrim_suresi_orani,
            "toplam_puan": toplam_puan,
            "detay_listesi": detay_listesi,
            "foto_path": foto_path  # ✅ Fotoğraf ekleniyor
        })

    personel_raporu.sort(key=lambda x: x["toplam_puan"], reverse=True)

    return render_template(
        "personel_performans.html",
        personel_raporu=personel_raporu,
        toplam_uretim=toplam_uretim,
        baslangic_tarihi=baslangic_tarihi.strftime("%Y-%m-%d"),
        bitis_tarihi=bitis_tarihi.strftime("%Y-%m-%d")
    )




@app.route('/kvkk')
def kvkk():
    return render_template('kvkk.html')

@app.route('/personelyonetimi')
def personelyonetimi():
    return render_template('personelyonetimi.html')

@app.route('/hakkimizda')
def hakkimizda():
    return render_template('hakkimizda.html')

@app.route('/izindefteri')
def izindefteri():
    return render_template('izindefteri.html')




from flask import Response

@app.route("/")
def home():
    return render_template("login.html")  # Ana sayfa olarak login.html kullanılıyor

@app.route("/sitemap.xml")
def sitemap():
    pages = []
    ten_days_ago = datetime.now().strftime("%Y-%m-%d")

    static_pages = ["izindefteri","login", "hakkimizda", "iletisim", "bilgi_listesi", "personelyonetimi"]
    for page in static_pages:
        pages.append({
            "loc": url_for(page, _external=True),
            "lastmod": ten_days_ago,
            "changefreq": "weekly",
            "priority": 0.8
        })

    # 🔵 Dinamik bilgi sayfaları için
    bilgiler = Bilgi.query.all()
    for bilgi in bilgiler:
        pages.append({
            "loc": url_for("bilgi_detay", bilgi_id=bilgi.id, _external=True),
            "lastmod": bilgi.created_at.strftime("%Y-%m-%d") if bilgi.created_at else ten_days_ago,
            "changefreq": "monthly",
            "priority": 0.6
        })

    sitemap_xml = render_template("sitemap.xml", pages=pages)
    return Response(sitemap_xml, mimetype="application/xml")








def send_email(name, phone, email, message):
    sender_email = "alptekinalpan@gmail.com"
    sender_password = "oobw qqwq kkns zoms"
    receiver_email = "alptekinalpan@gmail.com"

    subject = f"📩 Yeni İletişim Mesajı - {name}"
    body = f"Ad: {name}\nTelefon: {phone}\nE-posta: {email}\nMesaj:\n{message}"  # ✅ **Telefon numarası eklendi!**
    msg = MIMEMultipart()
    msg["From"] = sender_email
    msg["To"] = receiver_email
    msg["Subject"] = subject
    msg.attach(MIMEText(body, "plain"))

    try:
        server = smtplib.SMTP("smtp.gmail.com", 587)
        server.starttls()
        server.login(sender_email, sender_password)
        server.sendmail(sender_email, receiver_email, msg.as_string())
        server.quit()
        print("✅ E-posta başarıyla gönderildi!")
    except Exception as e:
        print("❌ E-posta gönderilirken hata oluştu:", str(e))

@app.route("/iletisim", methods=["GET", "POST"])
def iletisim():
    if request.method == "POST":
        name = request.form.get("name")
        phone = request.form.get("phone")  # 🔵 **Telefon numarası eklendi**
        email = request.form.get("email")
        message = request.form.get("message")

        if not name or not phone or not email or not message:
            flash("Lütfen tüm alanları doldurun!", "danger")
            return redirect(url_for("iletisim"))

        # 📌 E-posta gönderme işlemini çağır
        send_email(name, phone, email, message)  # ✅ **Telefon numarası da gönderiliyor!**

        flash("Mesajınız başarıyla gönderildi! En kısa sürede sizinle iletişime geçeceğiz.", "success")
        return redirect(url_for("iletisim"))

    return render_template("iletisim.html")  # 📌 Sayfayı yükle (GET isteği)


@app.route('/uudodszebc3f1cj6h8tydsvaicgcs1.html')
def meta_domain_verification():
    return send_from_directory(directory='.', path='uudodszebc3f1cj6h8tydsvaicgcs1.html')


class Bilgi(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(255), nullable=False)  # Başlık (SEO için önemli)
    content = db.Column(db.Text, nullable=False)       # Ana içerik
    image_path = db.Column(db.String(255), nullable=True)  # Görsel yolu (SEO için önemli)
    meta_description = db.Column(db.String(300), nullable=True)  # Meta açıklama (SEO için kritik)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)  # Oluşturulma zamanı

    def __repr__(self):
        return f"<Bilgi {self.title}>"



@app.route("/bilgi-ekle", methods=["GET", "POST"])
def bilgi_ekle():
    if request.method == "POST":
        title = request.form.get("title")
        content = request.form.get("content")
        meta_description = request.form.get("meta_description")
        image = request.files.get("image")

        image_path = None
        if image and image.filename:
            upload_folder = os.path.join("static", "uploads")
            os.makedirs(upload_folder, exist_ok=True)
            filename = datetime.utcnow().strftime("%Y%m%d%H%M%S_") + image.filename
            image_save_path = os.path.join(upload_folder, filename)
            image.save(image_save_path)
            image_path = image_save_path.replace("\\", "/")  # Windows uyumu

        yeni_bilgi = Bilgi(
            title=title,
            content=content,
            meta_description=meta_description,
            image_path=image_path
        )
        db.session.add(yeni_bilgi)
        db.session.commit()
        return redirect(url_for("bilgi_listesi"))  # Bilgi listesi sayfasına yönlendirme

    return render_template("bilgi_ekle.html")

@app.route("/bilgiler")
def bilgi_listesi():
    bilgiler = Bilgi.query.order_by(Bilgi.created_at.desc()).all()
    return render_template("bilgi_listesi.html", bilgiler=bilgiler)

@app.route("/bilgi/<int:bilgi_id>")
def bilgi_detay(bilgi_id):
    bilgi = Bilgi.query.get_or_404(bilgi_id)
    return render_template("bilgi_detay.html", bilgi=bilgi)

@app.template_filter('nl2br')
def nl2br(value):
    return value.replace("\n", "<br>")

@app.route('/fiyat')
def fiyat_sayfasi():
    return render_template('fiyat.html')


@app.route("/hizmetlerimiz")
def hizmetlerimiz():
    return render_template("hizmetlerimiz.html")




@app.route("/toplu_mesaj", methods=["GET"])
def toplu_mesaj():
    if "user_id" not in session:
        return redirect(url_for("login"))

    bolumler_raw = db.session.query(User.department).filter(User.department != None).distinct().all()
    
    bolum_set = set()
    for b in bolumler_raw:
        if b[0]:
            parcalar = [x.strip() for x in b[0].split(",") if x.strip()]
            print(f"🔍 Bölüm parçalara ayrıldı: {parcalar}")
            bolum_set.update(parcalar)

    bolumler = sorted(bolum_set)
    print(f"📋 HTML için gönderilen bölüm listesi: {bolumler}")

    return render_template("toplu_mesaj.html", bolumler=bolumler)




@app.route("/toplu_mesaj_gonder", methods=["POST"])
def toplu_mesaj_gonder():
    secim_tipi = request.form.get("secim_tipi")
    baslik = request.form.get("baslik")
    mesaj = request.form.get("mesaj")
    gorsel = request.files.get("gorsel")

    print(f"\n🚀 Toplu Mesaj Gönderiliyor!")
    print(f"📝 Seçim Tipi: {secim_tipi}")
    print(f"📌 Başlık: {baslik}")
    print(f"📨 Mesaj: {mesaj}")

    # 📎 Görsel kaydı
    image_url = None
    if gorsel and gorsel.filename != "":
        from datetime import datetime
        import os

        uploads_dir = os.path.join("static", "uploads")
        os.makedirs(uploads_dir, exist_ok=True)
        dosya_adi = datetime.now().strftime("%Y%m%d%H%M%S_") + gorsel.filename.replace(" ", "_")
        dosya_yolu = os.path.join(uploads_dir, dosya_adi)
        gorsel.save(dosya_yolu)

        image_url = f"https://izindefteri.com/static/uploads/{dosya_adi}"
        print(f"🖼 Görsel kaydedildi: {image_url}")

    hedef_kullanicilar = []

    if secim_tipi == "bolum":
        secilen_bolumler = request.form.getlist("bolumler")
        print(f"🎯 Seçilen Bölümler: {secilen_bolumler}")
        for bolum_adi in secilen_bolumler:
            kullanicilar = User.query.filter(User.department.like(f"%{bolum_adi}%")).all()
            print(f"📦 {bolum_adi} bölümünden {len(kullanicilar)} kullanıcı bulundu.")
            hedef_kullanicilar.extend(kullanicilar)

    elif secim_tipi == "rol":
        secilen_roller = request.form.getlist("roller")
        print(f"🎯 Seçilen Roller: {secilen_roller}")
        for rol in secilen_roller:
            kullanicilar = User.query.filter_by(role=rol).all()
            print(f"📦 {rol} rolünden {len(kullanicilar)} kullanıcı bulundu.")
            hedef_kullanicilar.extend(kullanicilar)

    benzersiz_kullanicilar = {k.phone_number: k for k in hedef_kullanicilar}.values()
    print(f"✅ Toplam Gönderim Yapılacak Kişi Sayısı: {len(benzersiz_kullanicilar)}")

    for kullanici in benzersiz_kullanicilar:
        if kullanici.phone_number:
            tam_mesaj = f"📌 {baslik}\n\n{mesaj}"
            numara = kullanici.phone_number

            if numara.startswith("+"):
                numara = numara[1:]

            print(f"📲 Mesaj Gönderiliyor: {kullanici.first_name} {kullanici.last_name} - {numara}")
            if image_url:
                print(f"📎 Görsel mesajla birlikte gönderiliyor: {image_url}")

            try:
                cevap = send_whatsapp_message(numara, tam_mesaj, image_url=image_url)
                if "error" in cevap:
                    print(f"❌ WhatsApp gönderim hatası: {cevap['error']}")
                else:
                    print(f"✅ WhatsApp gönderim başarılı: {cevap}")
            except Exception as e:
                print(f"🚨 Beklenmeyen hata: {str(e)}")
        else:
            print(f"⚠️ Telefon numarası eksik: {kullanici.first_name} {kullanici.last_name}")

    return redirect(url_for("toplu_mesaj"))




if __name__ == "__main__":
    with app.app_context():
        db.create_all()
    app.run(debug=True, host="0.0.0.0", port=8080)
