38233-vm/core/views.py
2026-02-06 00:30:42 +00:00

254 lines
10 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django.shortcuts import render, get_object_or_404, redirect
from django.db.models import Sum, Count, Avg, Q
from django.db import transaction
from django.core.files.storage import default_storage
from django.contrib import messages
from .models import Firma, Fatura, FaturaKalemi
from .forms import FirmaForm, FaturaForm
from .utils import extract_text_from_pdf, analyze_invoice_text
import os
def home(request):
"""Fatura Yönetimi Gösterge Paneli."""
toplam_firma = Firma.objects.count()
toplam_fatura = Fatura.objects.count()
toplam_harcama = Fatura.objects.aggregate(Sum('genel_toplam'))['genel_toplam__sum'] or 0
son_faturalar = Fatura.objects.select_related('firma').all().order_by('-olusturulma_tarihi')[:10]
context = {
"toplam_firma": toplam_firma,
"toplam_fatura": toplam_fatura,
"toplam_harcama": toplam_harcama,
"son_faturalar": son_faturalar,
"active_menu": "dashboard"
}
return render(request, "core/index.html", context)
def fatura_arsivi(request):
"""Firmalara göre gruplanmış fatura arşivi."""
firmalar = Firma.objects.annotate(
fatura_sayisi=Count('faturalar'),
toplam_tutar=Sum('faturalar__genel_toplam')
).order_by('ad')
context = {
"firmalar": firmalar,
"active_menu": "archive"
}
return render(request, "core/fatura_arsivi.html", context)
def firma_detay(request, pk):
"""Belirli bir firmanın fatura listesi."""
firma = get_object_or_404(Firma, pk=pk)
faturalar = firma.faturalar.all().order_by('-tarih')
context = {
"firma": firma,
"faturalar": faturalar,
"active_menu": "archive"
}
return render(request, "core/firma_detay.html", context)
def fatura_detay(request, pk):
"""Fatura detay önizleme ve kalemleri."""
fatura = get_object_or_404(Fatura.objects.select_related('firma'), pk=pk)
kalemler = fatura.kalemler.all()
context = {
"fatura": fatura,
"kalemler": kalemler,
"active_menu": "archive"
}
return render(request, "core/fatura_detay.html", context)
def raporlar(request):
"""İstatistik ve Raporlar."""
# Aylık harcama trendi
aylik_harcama = Fatura.objects.values('tarih__month').annotate(
toplam=Sum('genel_toplam'),
adet=Count('id')
).order_by('tarih__month')
# KDV dağılımı
kdv_ozet = Fatura.objects.aggregate(
toplam_kdv=Sum('kdv_toplam'),
ortalama_kdv=Avg('kdv_toplam')
)
context = {
"aylik_harcama": aylik_harcama,
"kdv_ozet": kdv_ozet,
"active_menu": "reports"
}
return render(request, "core/raporlar.html", context)
def firma_ekle(request):
if request.method == 'POST':
form = FirmaForm(request.POST)
if form.is_valid():
form.save()
return redirect('fatura_arsivi')
else:
form = FirmaForm()
return render(request, 'core/firma_form.html', {'form': form, 'title': 'Yeni Firma Ekle'})
def fatura_ekle(request):
firma_id = request.GET.get('firma')
initial = {}
if firma_id:
initial['firma'] = firma_id
if request.method == 'POST':
form = FaturaForm(request.POST, request.FILES)
if form.is_valid():
fatura = form.save()
return redirect('fatura_detay', pk=fatura.pk)
else:
form = FaturaForm(initial=initial)
return render(request, 'core/fatura_form.html', {'form': form, 'title': 'Yeni Fatura Yükle'})
def fatura_otomatik_yukle(request):
if request.method == 'POST' and request.FILES.get('pdf_dosyasi'):
pdf_file = request.FILES['pdf_dosyasi']
# Save temporary file to extract text
temp_name = 'temp_' + pdf_file.name
path = default_storage.save('temp/' + temp_name, pdf_file)
full_path = default_storage.path(path)
try:
text = extract_text_from_pdf(full_path)
if not text:
messages.error(request, "PDF dosyasından metin okunamadı. Dosya taranmış bir resim olabilir veya şifreli olabilir.")
else:
data = analyze_invoice_text(text)
if not data:
messages.error(request, "Yapay zeka faturayı analiz edemedi. Lütfen dosyanın geçerli bir fatura olduğundan emin olun.")
else:
with transaction.atomic():
# Smarter Firma matching
vergi_no = str(data.get('vergi_no', '')).strip()
mersis_no = str(data.get('mersis_no', '')).strip()
firma_adi = data.get('firma_adi', '').strip() or 'Bilinmeyen Firma'
firma = None
# 1. Try by Vergi No / TCKN
if vergi_no and vergi_no != 'None' and vergi_no != 'null':
firma = Firma.objects.filter(vergi_no=vergi_no).first()
# 2. Try by Mersis No
if not firma and mersis_no and mersis_no != 'None' and mersis_no != 'null':
firma = Firma.objects.filter(mersis_no=mersis_no).first()
# 3. Try by Name (Exact)
if not firma and firma_adi != 'Bilinmeyen Firma':
firma = Firma.objects.filter(ad__iexact=firma_adi).first()
# 4. Create if not found
if not firma:
# Ensure we have a unique vergi_no even if AI failed
if not vergi_no or vergi_no == 'None' or vergi_no == 'null':
vergi_no = f"AUTO-{os.urandom(4).hex()}"
firma = Firma.objects.create(
ad=firma_adi,
vergi_no=vergi_no,
mersis_no=mersis_no if (mersis_no != 'None' and mersis_no != 'null') else None,
adres=data.get('adres', '')
)
else:
# Update missing info if found existing firma
updated = False
if not firma.mersis_no and mersis_no and mersis_no != 'None' and mersis_no != 'null':
firma.mersis_no = mersis_no
updated = True
if not firma.adres and data.get('adres'):
firma.adres = data.get('adres')
updated = True
if updated:
firma.save()
# Create Fatura
fatura_no = data.get('fatura_no') or f"AUTO-{os.urandom(4).hex()}"
# Check if this invoice already exists for this firm
fatura = Fatura.objects.filter(fatura_no=fatura_no, firma=firma).first()
if not fatura:
fatura = Fatura.objects.create(
firma=firma,
fatura_no=fatura_no,
tarih=data.get('tarih') or '2026-01-01',
ara_toplam=data.get('ara_toplam') or 0,
kdv_toplam=data.get('kdv_toplam') or 0,
genel_toplam=data.get('genel_toplam') or 0,
pdf_dosyasi=pdf_file,
islenmis=True
)
# Add Items
kalemler = data.get('kalemler', [])
if isinstance(kalemler, list):
for k in kalemler:
FaturaKalemi.objects.create(
fatura=fatura,
urun_adi=k.get('urun_adi') or 'Ürün',
adet=k.get('adet') or 1,
birim_fiyat=k.get('birim_fiyat') or 0,
kdv_orani=k.get('kdv_orani') or 20,
kdv_tutari=k.get('kdv_tutari') or 0,
toplam_tutar=k.get('toplam_tutar') or 0
)
# Clean up temp file
if default_storage.exists(path):
default_storage.delete(path)
messages.success(request, f"Fatura başarıyla analiz edildi ve {firma.ad} firmasına eklendi.")
return redirect('fatura_detay', pk=fatura.pk)
except Exception as e:
messages.error(request, f"Fatura işlenirken bir hata oluştu: {str(e)}")
print(f"Error processing automatic invoice: {e}")
finally:
# Clean up temp file
if default_storage.exists(path):
default_storage.delete(path)
return render(request, 'core/fatura_form_otomatik.html', {'title': 'Otomatik Fatura Yükle', 'active_menu': 'dashboard'})
def search(request):
query = request.GET.get('q', '')
faturalar = []
firmalar = []
if query:
faturalar = Fatura.objects.filter(
Q(fatura_no__icontains=query) |
Q(firma__ad__icontains=query)
).select_related('firma')
firmalar = Firma.objects.filter(
Q(ad__icontains=query) |
Q(vergi_no__icontains=query)
)
context = {
'query': query,
'faturalar': faturalar,
'firmalar': firmalar,
}
return render(request, 'core/search_results.html', context)
def firma_sil(request, pk):
firma = get_object_or_404(Firma, pk=pk)
if request.method == 'POST':
firma.delete()
return redirect('fatura_arsivi')
return render(request, 'core/confirm_delete.html', {'object': firma, 'type': 'Firma'})
def fatura_sil(request, pk):
fatura = get_object_or_404(Fatura, pk=pk)
firma_pk = fatura.firma.pk
if request.method == 'POST':
fatura.delete()
return redirect('firma_detay', pk=firma_pk)
return render(request, 'core/confirm_delete.html', {'object': fatura, 'type': 'Fatura'})