Auto commit: 2026-02-06T00:08:49.034Z

This commit is contained in:
Flatlogic Bot 2026-02-06 00:08:49 +00:00
parent e6fa05f94e
commit cddb69516f
21 changed files with 871 additions and 234 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

@ -43,14 +43,9 @@ CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = "None" SESSION_COOKIE_SAMESITE = "None"
CSRF_COOKIE_SAMESITE = "None" CSRF_COOKIE_SAMESITE = "None"
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
@ -63,10 +58,7 @@ MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
# Disable X-Frame-Options middleware to allow Flatlogic preview iframes.
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ]
X_FRAME_OPTIONS = 'ALLOWALL' X_FRAME_OPTIONS = 'ALLOWALL'
@ -81,7 +73,6 @@ TEMPLATES = [
'OPTIONS': { 'OPTIONS': {
'context_processors': [ 'context_processors': [
'django.template.context_processors.request', 'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages', 'django.contrib.messages.context_processors.messages',
# IMPORTANT: do not remove injects PROJECT_DESCRIPTION/PROJECT_IMAGE_URL and cache-busting timestamp # IMPORTANT: do not remove injects PROJECT_DESCRIPTION/PROJECT_IMAGE_URL and cache-busting timestamp
'core.context_processors.project_context', 'core.context_processors.project_context',
@ -110,26 +101,6 @@ DATABASES = {
}, },
} }
# Password validation
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/5.2/topics/i18n/ # https://docs.djangoproject.com/en/5.2/topics/i18n/

View File

@ -14,13 +14,11 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path 1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
from django.contrib import admin
from django.urls import include, path from django.urls import include, path
from django.conf import settings from django.conf import settings
from django.conf.urls.static import static from django.conf.urls.static import static
urlpatterns = [ urlpatterns = [
path("admin/", admin.site.urls),
path("", include("core.urls")), path("", include("core.urls")),
] ]

Binary file not shown.

27
core/forms.py Normal file
View File

@ -0,0 +1,27 @@
from django import forms
from .models import Firma, Fatura, FaturaKalemi
class FirmaForm(forms.ModelForm):
class Meta:
model = Firma
fields = ['ad', 'vergi_no', 'mersis_no', 'adres']
widgets = {
'ad': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Firma Tam Adı'}),
'vergi_no': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Vergi No / TC Kimlik No'}),
'mersis_no': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'MERSİS No (Opsiyonel)'}),
'adres': forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': 'Firma Adresi'}),
}
class FaturaForm(forms.ModelForm):
class Meta:
model = Fatura
fields = ['firma', 'fatura_no', 'tarih', 'ara_toplam', 'kdv_toplam', 'genel_toplam', 'pdf_dosyasi']
widgets = {
'firma': forms.Select(attrs={'class': 'form-select'}),
'fatura_no': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Fatura No'}),
'tarih': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
'ara_toplam': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}),
'kdv_toplam': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}),
'genel_toplam': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}),
'pdf_dosyasi': forms.FileInput(attrs={'class': 'form-control'}),
}

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Fatura Yönetim Sistemi{% endblock %}</title> <title>{% block title %}FaturaYol - Akıllı Fatura Yönetimi{% endblock %}</title>
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
@ -13,9 +13,10 @@
<style> <style>
:root { :root {
--primary-color: #2563eb; --primary-color: #2563eb;
--sidebar-bg: #1e293b; --sidebar-bg: #0f172a;
--sidebar-hover: #334155; --sidebar-hover: #1e293b;
--bg-body: #f8fafc; --sidebar-active: #334155;
--bg-body: #f1f5f9;
--text-main: #1e293b; --text-main: #1e293b;
--text-muted: #64748b; --text-muted: #64748b;
} }
@ -24,94 +25,105 @@
background-color: var(--bg-body); background-color: var(--bg-body);
color: var(--text-main); color: var(--text-main);
overflow-x: hidden; overflow-x: hidden;
margin: 0;
padding: 0;
} }
#wrapper { #wrapper {
display: flex; display: flex;
width: 100%; width: 100%;
align-items: stretch; min-height: 100vh;
} }
#sidebar { #sidebar {
min-width: 260px; width: 280px;
max-width: 260px; min-width: 280px;
background: var(--sidebar-bg); background: var(--sidebar-bg);
color: #fff; color: #fff;
transition: all 0.3s; transition: all 0.3s;
min-height: 100vh;
z-index: 1000; z-index: 1000;
box-shadow: 4px 0 10px rgba(0,0,0,0.1);
display: flex;
flex-direction: column;
} }
#sidebar .sidebar-header { #sidebar .sidebar-header {
padding: 20px; padding: 30px 25px;
background: rgba(0,0,0,0.1); background: rgba(0,0,0,0.2);
border-bottom: 1px solid rgba(255,255,255,0.05);
} }
#sidebar ul.components { #sidebar ul.components {
padding: 20px 0; padding: 20px 15px;
} }
#sidebar ul li { #sidebar ul li {
padding: 0 10px; margin-bottom: 5px;
} }
#sidebar ul li a { #sidebar ul li a {
padding: 12px 15px; padding: 12px 20px;
display: block; display: flex;
color: #cbd5e1; align-items: center;
color: #94a3b8;
text-decoration: none; text-decoration: none;
border-radius: 8px; border-radius: 10px;
margin-bottom: 5px;
font-weight: 500; font-weight: 500;
transition: 0.2s; transition: all 0.2s;
} }
#sidebar ul li a:hover, #sidebar ul li.active > a { #sidebar ul li a:hover {
color: #fff; color: #fff;
background: var(--sidebar-hover); background: var(--sidebar-hover);
} }
#sidebar ul li.active > a {
color: #fff;
background: var(--sidebar-active);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.2);
}
#sidebar ul li a i { #sidebar ul li a i {
margin-right: 10px; margin-right: 15px;
font-size: 1.1rem; font-size: 1.2rem;
} }
#content { #content {
width: 100%; flex: 1;
padding: 30px; min-width: 0;
padding: 40px;
transition: all 0.3s; transition: all 0.3s;
} }
.navbar { .top-navbar {
background: #fff; background: #fff;
border-bottom: 1px solid #e2e8f0; border-bottom: 1px solid #e2e8f0;
margin-bottom: 30px; padding: 15px 25px;
border-radius: 12px; margin-bottom: 35px;
box-shadow: 0 1px 3px rgba(0,0,0,0.05); border-radius: 15px;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
display: flex;
align-items: center;
justify-content: space-between;
} }
.card { .card {
border: none; border: none;
border-radius: 12px; border-radius: 16px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
margin-bottom: 24px; transition: transform 0.2s;
} }
.stat-card { .card:hover {
padding: 24px; transform: translateY(-2px);
display: flex;
align-items: center;
} }
.stat-icon { .btn-primary {
width: 48px; background-color: var(--primary-color);
height: 48px; border: none;
border-radius: 12px; padding: 10px 20px;
display: flex; border-radius: 10px;
align-items: center; font-weight: 600;
justify-content: center;
font-size: 24px;
margin-right: 16px;
} }
.bg-primary-soft { background-color: #dbeafe; color: #2563eb; } .badge-soft-success { background-color: #d1fae5; color: #065f46; }
.bg-success-soft { background-color: #d1fae5; color: #10b981; } .badge-soft-primary { background-color: #dbeafe; color: #1e40af; }
.bg-warning-soft { background-color: #fef3c7; color: #f59e0b; }
@media (max-width: 992px) {
.table thead th { #sidebar {
background-color: #f8fafc; margin-left: -280px;
border-bottom: 2px solid #e2e8f0; }
text-transform: uppercase; #sidebar.active {
font-size: 0.75rem; margin-left: 0;
font-weight: 700; }
letter-spacing: 0.05em; #content {
color: var(--text-muted); padding: 20px;
}
} }
</style> </style>
{% block extra_css %}{% endblock %} {% block extra_css %}{% endblock %}
@ -121,49 +133,68 @@
<!-- Sidebar --> <!-- Sidebar -->
<nav id="sidebar"> <nav id="sidebar">
<div class="sidebar-header"> <div class="sidebar-header">
<h4 class="mb-0 fw-bold"><i class="bi bi-receipt-cutoff me-2"></i>FaturaYol</h4> <a href="{% url 'home' %}" class="text-white text-decoration-none">
<h3 class="mb-0 fw-bold d-flex align-items-center">
<i class="bi bi-lightning-charge-fill text-primary me-2"></i>
FaturaYol
</h3>
</a>
<small class="text-muted">Akıllı Arşivleme Sistemi</small>
</div> </div>
<ul class="list-unstyled components"> <ul class="list-unstyled components">
<li class="{% if active_menu == 'dashboard' %}active{% endif %}"> <li class="{% if active_menu == 'dashboard' %}active{% endif %}">
<a href="{% url 'home' %}"><i class="bi bi-speedometer2"></i> Gösterge Paneli</a> <a href="{% url 'home' %}">
<i class="bi bi-grid-1x2-fill"></i>
<span>Gösterge Paneli</span>
</a>
</li> </li>
<li class="{% if active_menu == 'archive' %}active{% endif %}"> <li class="{% if active_menu == 'archive' %}active{% endif %}">
<a href="#"><i class="bi bi-archive"></i> Fatura Arşivi</a> <a href="{% url 'fatura_arsivi' %}">
<i class="bi bi-collection-fill"></i>
<span>Fatura Arşivi</span>
</a>
</li> </li>
<li class="{% if active_menu == 'reports' %}active{% endif %}"> <li class="{% if active_menu == 'reports' %}active{% endif %}">
<a href="#"><i class="bi bi-graph-up"></i> İstatistik & Raporlar</a> <a href="{% url 'raporlar' %}">
</li> <i class="bi bi-bar-chart-line-fill"></i>
<li class="mt-4 px-3"> <span>İstatistik & Raporlar</span>
<span class="text-muted small text-uppercase fw-bold">Yönetim</span> </a>
</li>
<li>
<a href="/admin/"><i class="bi bi-gear"></i> Sistem Ayarları</a>
</li> </li>
</ul> </ul>
<div class="mt-auto p-4">
<div class="card bg-primary text-white border-0 p-3" style="background: linear-gradient(45deg, #2563eb, #4f46e5);">
<small class="opacity-75 mb-1">Kullanım Durumu</small>
<div class="progress mb-2" style="height: 6px; background: rgba(255,255,255,0.2);">
<div class="progress-bar bg-white" style="width: 45%;"></div>
</div>
<small class="small">Sürüm 1.0.4</small>
</div>
</div>
</nav> </nav>
<!-- Page Content --> <!-- Page Content -->
<div id="content"> <div id="content">
<nav class="navbar navbar-expand-lg"> <div class="container-fluid p-0">
<div class="container-fluid"> <div class="top-navbar">
<span class="navbar-text fw-semibold">Hoş geldiniz!</span> <div class="d-flex align-items-center">
<div class="ms-auto d-flex align-items-center"> <h5 class="mb-0 fw-bold">{% block page_title %}Genel Bakış{% endblock %}</h5>
<div class="dropdown"> </div>
<button class="btn btn-link text-dark text-decoration-none dropdown-toggle" type="button" data-bs-toggle="dropdown"> <div class="d-flex align-items-center">
<i class="bi bi-person-circle me-1"></i> Yönetici <div class="me-4 d-none d-md-block">
</button> <form action="{% url 'search' %}" method="get">
<ul class="dropdown-menu dropdown-menu-end"> <div class="input-group">
<li><a class="dropdown-item" href="#">Profil</a></li> <span class="input-group-text bg-light border-0"><i class="bi bi-search"></i></span>
<li><hr class="dropdown-divider"></li> <input type="text" name="q" class="form-control bg-light border-0" placeholder="Fatura veya firma ara..." style="width: 300px;" value="{{ query|default:'' }}">
<li><a class="dropdown-item" href="#">Çıkış Yap</a></li> </div>
</ul> </form>
</div> </div>
</div> </div>
</div> </div>
</nav>
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,30 @@
{% extends "base.html" %}
{% block title %}Silmeyi Onayla - FaturaYol{% endblock %}
{% block page_title %}{{ type }} Silme İşlemi{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card border-0 shadow-sm">
<div class="card-body p-5 text-center">
<div class="bg-danger bg-opacity-10 text-danger mx-auto mb-4 rounded-circle d-flex align-items-center justify-content-center" style="width: 80px; height: 80px;">
<i class="bi bi-exclamation-triangle-fill fs-1"></i>
</div>
<h4 class="fw-bold mb-3">Emin misiniz?</h4>
<p class="text-muted mb-4">
<strong>{{ object }}</strong> isimli {{ type|lower }} kaydını silmek üzeresiniz.
Bu işlem geri alınamaz ve bu kayda bağlı tüm veriler silinecektir.
</p>
<form method="post">
{% csrf_token %}
<div class="d-grid gap-2">
<button type="submit" class="btn btn-danger rounded-pill py-2 fw-bold">Evet, Sil</button>
<a href="{{ request.META.HTTP_REFERER|default:'/' }}" class="btn btn-light rounded-pill py-2">İptal</a>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,57 @@
{% extends "base.html" %}
{% block title %}Fatura Arşivi - FaturaYol{% endblock %}
{% block page_title %}Fatura Arşivi{% endblock %}
{% block content %}
<div class="row mb-4">
<div class="col-md-8">
<p class="text-muted">Firmalara göre gruplanmış fatura listesi. Detaylı görüntülemek için bir firmaya tıklayın.</p>
</div>
<div class="col-md-4 text-end">
<a href="{% url 'firma_ekle' %}" class="btn btn-primary rounded-pill px-4">
<i class="bi bi-folder-plus me-2"></i> Yeni Firma Ekle
</a>
</div>
</div>
<div class="row">
{% for firma in firmalar %}
<div class="col-md-4 col-xl-3 mb-4">
<div class="card h-100 shadow-sm border-0">
<div class="card-body p-4 text-center">
<div class="position-absolute top-0 end-0 p-2">
<a href="{% url 'firma_sil' firma.pk %}" class="btn btn-link text-danger p-0" title="Firmayı Sil"><i class="bi bi-trash"></i></a>
</div>
<div class="bg-primary-soft stat-icon mx-auto mb-3" style="width: 60px; height: 60px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: #e0e7ff; color: #4338ca;">
<i class="bi bi-building" style="font-size: 1.5rem;"></i>
</div>
<h5 class="fw-bold mb-1 text-truncate">{{ firma.ad }}</h5>
<p class="text-muted small mb-3">VN: {{ firma.vergi_no }}</p>
<div class="d-flex justify-content-between align-items-center bg-light p-2 rounded-3 mb-3">
<div class="text-start ps-2">
<small class="text-muted d-block" style="font-size: 0.65rem; text-transform: uppercase;">Fatura</small>
<span class="fw-bold">{{ firma.fatura_sayisi }} Adet</span>
</div>
<div class="text-end pe-2">
<small class="text-muted d-block" style="font-size: 0.65rem; text-transform: uppercase;">Toplam</small>
<span class="fw-bold text-primary">{{ firma.toplam_tutar|default:0|floatformat:2 }} ₺</span>
</div>
</div>
<a href="{% url 'firma_detay' firma.pk %}" class="btn btn-outline-primary btn-sm w-100 rounded-pill">
Dosyaları Görüntüle <i class="bi bi-chevron-right ms-1"></i>
</a>
</div>
</div>
</div>
{% empty %}
<div class="col-12 text-center py-5">
<i class="bi bi-folder2-open text-muted" style="font-size: 4rem;"></i>
<p class="mt-3 text-muted">Henüz kayıtlı bir firma veya fatura bulunamadı.</p>
<a href="{% url 'firma_ekle' %}" class="btn btn-primary mt-2">İlk Firmayı Ekle</a>
</div>
{% endfor %}
</div>
{% endblock %}

View File

@ -0,0 +1,105 @@
{% extends "base.html" %}
{% block title %}Fatura Detayı - {{ fatura.fatura_no }}{% endblock %}
{% block page_title %}Fatura Detayı{% endblock %}
{% block content %}
<nav aria-label="breadcrumb" class="mb-4">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'fatura_arsivi' %}" class="text-decoration-none">Arşiv</a></li>
<li class="breadcrumb-item"><a href="{% url 'firma_detay' fatura.firma.pk %}" class="text-decoration-none">{{ fatura.firma.ad }}</a></li>
<li class="breadcrumb-item active">{{ fatura.fatura_no }}</li>
</ol>
</nav>
<div class="row">
<div class="col-lg-8">
<!-- PDF Önizleme Kartı (Simüle edilmiş, PDF.js veya iframe kullanılabilir) -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-white py-3 d-flex justify-content-between align-items-center">
<h5 class="mb-0 fw-bold">PDF Önizleme</h5>
<a href="{{ fatura.pdf_dosyasi.url }}" target="_blank" class="btn btn-sm btn-outline-primary">
<i class="bi bi-box-arrow-up-right me-1"></i> Tam Ekran
</a>
</div>
<div class="card-body p-0" style="height: 600px; background: #525659;">
{% if fatura.pdf_dosyasi %}
<iframe src="{{ fatura.pdf_dosyasi.url }}" width="100%" height="100%" frameborder="0"></iframe>
{% else %}
<div class="h-100 d-flex align-items-center justify-content-center text-white flex-column">
<i class="bi bi-file-earmark-pdf mb-3" style="font-size: 3rem;"></i>
<p>PDF dosyası bulunamadı.</p>
</div>
{% endif %}
</div>
</div>
</div>
<div class="col-lg-4">
<!-- Fatura Bilgileri Yan Panel -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-body">
<h5 class="fw-bold mb-4">Fatura Bilgileri</h5>
<div class="mb-3">
<label class="text-muted small text-uppercase fw-bold">Firma</label>
<p class="fw-bold mb-0 text-primary">{{ fatura.firma.ad }}</p>
</div>
<div class="row mb-3">
<div class="col-6">
<label class="text-muted small text-uppercase fw-bold">Tarih</label>
<p class="fw-bold mb-0">{{ fatura.tarih|date:"d.m.Y" }}</p>
</div>
<div class="col-6">
<label class="text-muted small text-uppercase fw-bold">Fatura No</label>
<p class="fw-bold mb-0">{{ fatura.fatura_no }}</p>
</div>
</div>
<hr class="my-4">
<div class="d-flex justify-content-between mb-2">
<span class="text-muted">Ara Toplam</span>
<span class="fw-bold">{{ fatura.ara_toplam }} ₺</span>
</div>
<div class="d-flex justify-content-between mb-2">
<span class="text-muted">KDV Toplam</span>
<span class="fw-bold">{{ fatura.kdv_toplam }} ₺</span>
</div>
<div class="d-flex justify-content-between mt-3 pt-3 border-top">
<span class="h5 fw-bold mb-0">Genel Toplam</span>
<span class="h5 fw-bold mb-0 text-primary">{{ fatura.genel_toplam }} ₺</span>
</div>
</div>
</div>
<!-- Kalem Detayları -->
<div class="card border-0 shadow-sm">
<div class="card-body p-0">
<div class="p-3 border-bottom">
<h5 class="fw-bold mb-0">Ürün / Hizmet Kalemleri</h5>
</div>
<div class="list-group list-group-flush">
{% for kalem in kalemler %}
<div class="list-group-item p-3">
<div class="d-flex justify-content-between align-items-start mb-1">
<h6 class="fw-bold mb-0">{{ kalem.urun_adi }}</h6>
<span class="badge bg-light text-dark">{{ kalem.adet }} Adet</span>
</div>
<div class="d-flex justify-content-between small text-muted">
<span>Birim: {{ kalem.birim_fiyat }} ₺</span>
<span class="fw-bold text-dark">Toplam: {{ kalem.toplam_tutar }} ₺</span>
</div>
</div>
{% empty %}
<div class="p-4 text-center text-muted">
Kalem verisi bulunamadı.
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,37 @@
{% extends "base.html" %}
{% block title %}{{ title }} - FaturaYol{% endblock %}
{% block page_title %}{{ title }}{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card border-0 shadow-sm">
<div class="card-body p-4">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="mb-4">
<h5 class="fw-bold mb-3">Fatura Detayları</h5>
{% for field in form %}
<div class="mb-3">
<label class="form-label fw-medium">{{ field.label }}</label>
{{ field }}
{% if field.help_text %}
<div class="form-text">{{ field.help_text }}</div>
{% endif %}
{% for error in field.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
</div>
{% endfor %}
</div>
<div class="d-flex justify-content-between align-items-center mt-4">
<a href="{% url 'home' %}" class="btn btn-light rounded-pill px-4">İptal</a>
<button type="submit" class="btn btn-primary rounded-pill px-5">Faturayı Yükle</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,76 @@
{% extends "base.html" %}
{% block title %}Fatura Arşivi - FaturaYol{% endblock %}
{% block page_title %}{{ firma.ad }}{% endblock %}
{% block content %}
<nav aria-label="breadcrumb" class="mb-4">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'fatura_arsivi' %}" class="text-decoration-none">Arşiv</a></li>
<li class="breadcrumb-item active" aria-current="page">{{ firma.ad }}</li>
</ol>
</nav>
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-white py-3">
<div class="d-flex justify-content-between align-items-center">
<h5 class="mb-0 fw-bold"><i class="bi bi-files me-2 text-primary"></i>Tüm Faturalar</h5>
<div class="btn-group">
<a href="{% url 'fatura_ekle' %}?firma={{ firma.pk }}" class="btn btn-sm btn-primary rounded-pill px-3"><i class="bi bi-plus-lg me-1"></i> Yeni PDF Yükle</a>
</div>
</div>
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead>
<tr>
<th class="ps-4">Fatura No</th>
<th>Tarih</th>
<th>Ara Toplam</th>
<th>KDV</th>
<th>Genel Toplam</th>
<th>Durum</th>
<th class="text-end pe-4">İşlemler</th>
</tr>
</thead>
<tbody>
{% for fatura in faturalar %}
<tr>
<td class="ps-4 fw-medium">{{ fatura.fatura_no }}</td>
<td>{{ fatura.tarih|date:"d.m.Y" }}</td>
<td>{{ fatura.ara_toplam }} ₺</td>
<td>{{ fatura.kdv_toplam }} ₺</td>
<td class="fw-bold text-primary">{{ fatura.genel_toplam }} ₺</td>
<td>
{% if fatura.islenmis %}
<span class="badge badge-soft-success px-2 py-1 rounded-pill">İşlendi</span>
{% else %}
<span class="badge bg-light text-dark px-2 py-1 rounded-pill border">Bekliyor</span>
{% endif %}
</td>
<td class="text-end pe-4">
<a href="{% url 'fatura_detay' fatura.pk %}" class="btn btn-sm btn-light rounded-circle me-1" title="Görüntüle">
<i class="bi bi-eye"></i>
</a>
{% if fatura.pdf_dosyasi %}
<a href="{{ fatura.pdf_dosyasi.url }}" target="_blank" class="btn btn-sm btn-light rounded-circle me-1" title="PDF İndir">
<i class="bi bi-download"></i>
</a>
{% endif %}
<a href="{% url 'fatura_sil' fatura.pk %}" class="btn btn-sm btn-light text-danger rounded-circle" title="Faturayı Sil">
<i class="bi bi-trash"></i>
</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="7" class="text-center py-5 text-muted">
<p class="mb-0">Bu firmaya ait henüz fatura bulunamadı.</p>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,37 @@
{% extends "base.html" %}
{% block title %}{{ title }} - FaturaYol{% endblock %}
{% block page_title %}{{ title }}{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card border-0 shadow-sm">
<div class="card-body p-4">
<form method="post">
{% csrf_token %}
<div class="mb-4">
<h5 class="fw-bold mb-3">Firma Bilgileri</h5>
{% for field in form %}
<div class="mb-3">
<label class="form-label fw-medium">{{ field.label }}</label>
{{ field }}
{% if field.help_text %}
<div class="form-text">{{ field.help_text }}</div>
{% endif %}
{% for error in field.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
</div>
{% endfor %}
</div>
<div class="d-flex justify-content-between align-items-center mt-4">
<a href="{% url 'fatura_arsivi' %}" class="btn btn-light rounded-pill px-4">İptal</a>
<button type="submit" class="btn btn-primary rounded-pill px-5">Kaydet</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -3,132 +3,140 @@
{% block title %}Gösterge Paneli | FaturaYol{% endblock %} {% block title %}Gösterge Paneli | FaturaYol{% endblock %}
{% block content %} {% block content %}
<div class="container-fluid"> <div class="row">
<div class="row"> <div class="col-12 mb-4">
<div class="col-12 mb-4"> <h2 class="fw-bold">Gösterge Paneli</h2>
<h2 class="fw-bold">Gösterge Paneli</h2> <p class="text-muted">Fatura yönetim sistemine genel bakış ve hızlı istatistikler.</p>
<p class="text-muted">Fatura yönetim sistemine genel bakış.</p> </div>
</div>
<!-- Stats Cards -->
<div class="row mb-4">
<div class="col-md-4">
<div class="card stat-card border-0 shadow-sm">
<div class="card-body d-flex align-items-center p-4">
<div class="bg-primary-soft stat-icon me-3" style="width: 50px; height: 50px; border-radius: 12px; display: flex; align-items: center; justify-content: center; background: #dbeafe; color: #2563eb;">
<i class="bi bi-building" style="font-size: 1.5rem;"></i>
</div>
<div>
<h6 class="text-muted mb-1 small text-uppercase fw-bold">Toplam Firma</h6>
<h3 class="fw-bold mb-0 text-primary">{{ toplam_firma }}</h3>
</div>
</div>
</div> </div>
</div> </div>
<div class="col-md-4">
<div class="card stat-card border-0 shadow-sm">
<div class="card-body d-flex align-items-center p-4">
<div class="bg-success-soft stat-icon me-3" style="width: 50px; height: 50px; border-radius: 12px; display: flex; align-items: center; justify-content: center; background: #dcfce7; color: #15803d;">
<i class="bi bi-file-earmark-text" style="font-size: 1.5rem;"></i>
</div>
<div>
<h6 class="text-muted mb-1 small text-uppercase fw-bold">Toplam Fatura</h6>
<h3 class="fw-bold mb-0 text-success">{{ toplam_fatura }}</h3>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card stat-card border-0 shadow-sm">
<div class="card-body d-flex align-items-center p-4">
<div class="bg-warning-soft stat-icon me-3" style="width: 50px; height: 50px; border-radius: 12px; display: flex; align-items: center; justify-content: center; background: #fef9c3; color: #a16207;">
<i class="bi bi-cash-stack" style="font-size: 1.5rem;"></i>
</div>
<div>
<h6 class="text-muted mb-1 small text-uppercase fw-bold">Toplam Harcama</h6>
<h3 class="fw-bold mb-0 text-warning">₺{{ toplam_harcama|floatformat:2 }}</h3>
</div>
</div>
</div>
</div>
</div>
<!-- Stats Cards --> <div class="row mt-2">
<div class="row"> <!-- Recent Invoices Table -->
<div class="col-md-4"> <div class="col-lg-8">
<div class="card stat-card"> <div class="card border-0 shadow-sm h-100">
<div class="stat-icon bg-primary-soft"> <div class="card-header bg-white py-3 d-flex align-items-center justify-content-between border-0">
<i class="bi bi-building"></i> <h5 class="mb-0 fw-bold"><i class="bi bi-clock-history me-2 text-primary"></i>Son Eklenen Faturalar</h5>
</div> <a href="{% url 'fatura_arsivi' %}" class="btn btn-sm btn-link text-decoration-none">Tümünü Gör <i class="bi bi-arrow-right"></i></a>
<div>
<h6 class="text-muted mb-1">Toplam Firma</h6>
<h3 class="fw-bold mb-0">{{ toplam_firma }}</h3>
</div>
</div> </div>
</div> <div class="card-body p-0">
<div class="col-md-4"> <div class="table-responsive">
<div class="card stat-card"> <table class="table table-hover align-middle mb-0">
<div class="stat-icon bg-success-soft"> <thead>
<i class="bi bi-file-earmark-text"></i> <tr class="bg-light">
</div> <th class="ps-4 border-0">Fatura No</th>
<div> <th class="border-0">Firma</th>
<h6 class="text-muted mb-1">Toplam Fatura</h6> <th class="border-0">Tarih</th>
<h3 class="fw-bold mb-0">{{ toplam_fatura }}</h3> <th class="border-0">Toplam</th>
</div> <th class="text-end pe-4 border-0">İşlem</th>
</div> </tr>
</div> </thead>
<div class="col-md-4"> <tbody>
<div class="card stat-card"> {% for fatura in son_faturalar %}
<div class="stat-icon bg-warning-soft"> <tr>
<i class="bi bi-currency-dollar"></i> <td class="ps-4 fw-medium text-dark">{{ fatura.fatura_no }}</td>
</div> <td>
<div> <span class="badge bg-light text-dark fw-medium border px-2 py-1">{{ fatura.firma.ad }}</span>
<h6 class="text-muted mb-1">Toplam Harcama</h6> </td>
<h3 class="fw-bold mb-0">₺{{ toplam_harcama|floatformat:2 }}</h3> <td class="text-muted">{{ fatura.tarih|date:"d.m.Y" }}</td>
<td class="fw-bold text-primary">₺{{ fatura.genel_toplam }}</td>
<td class="text-end pe-4">
<a href="{% url 'fatura_detay' fatura.pk %}" class="btn btn-sm btn-light rounded-pill">
<i class="bi bi-eye"></i> İncele
</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="5" class="text-center py-5">
<div class="opacity-50 mb-3">
<i class="bi bi-file-earmark-plus" style="font-size: 3rem;"></i>
</div>
<p class="text-muted mb-0">Henüz fatura eklenmemiş.</p>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="row mt-4"> <!-- Quick Actions -->
<!-- Recent Invoices Table --> <div class="col-lg-4">
<div class="col-lg-8"> <div class="card border-0 shadow-sm h-100">
<div class="card"> <div class="card-header bg-white py-3 border-0">
<div class="card-header bg-white py-3 d-flex align-items-center justify-content-between"> <h5 class="mb-0 fw-bold"><i class="bi bi-lightning-fill me-2 text-warning"></i>Hızlı İşlemler</h5>
<h5 class="mb-0 fw-bold">Son Eklenen Faturalar</h5>
<a href="#" class="btn btn-sm btn-outline-primary">Tümünü Gör</a>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead>
<tr>
<th class="ps-4">Fatura No</th>
<th>Firma</th>
<th>Tarih</th>
<th>Toplam</th>
<th>Durum</th>
<th class="text-end pe-4">İşlem</th>
</tr>
</thead>
<tbody>
{% for fatura in son_faturalar %}
<tr>
<td class="ps-4 fw-medium">{{ fatura.fatura_no }}</td>
<td>{{ fatura.firma.ad }}</td>
<td>{{ fatura.tarih|date:"d.m.Y" }}</td>
<td class="fw-bold">₺{{ fatura.genel_toplam }}</td>
<td>
{% if fatura.islenmis %}
<span class="badge bg-success-soft text-success">İşlendi</span>
{% else %}
<span class="badge bg-warning-soft text-warning">Bekliyor</span>
{% endif %}
</td>
<td class="text-end pe-4">
<button class="btn btn-sm btn-light"><i class="bi bi-eye"></i></button>
</td>
</tr>
{% empty %}
<tr>
<td colspan="6" class="text-center py-5 text-muted">Henüz fatura eklenmemiş.</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div> </div>
</div> <div class="card-body">
<div class="d-grid gap-3">
<!-- Quick Actions --> <a href="{% url 'fatura_ekle' %}" class="btn btn-primary text-start p-3 rounded-4 d-flex align-items-center shadow-sm border-0 text-decoration-none" style="background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);">
<div class="col-lg-4"> <div class="bg-white bg-opacity-25 rounded-3 p-2 me-3">
<div class="card"> <i class="bi bi-plus-circle-fill fs-4"></i>
<div class="card-header bg-white py-3"> </div>
<h5 class="mb-0 fw-bold">Hızlı İşlemler</h5> <div>
<div class="fw-bold text-white">Fatura Yükle</div>
<div class="small text-white opacity-75">PDF dosyasını seçin</div>
</div>
</a>
<a href="{% url 'firma_ekle' %}" class="btn btn-outline-light text-dark text-start p-3 rounded-4 d-flex align-items-center border bg-light bg-opacity-50 text-decoration-none">
<div class="bg-white rounded-3 p-2 me-3 shadow-sm text-primary">
<i class="bi bi-folder-plus fs-4"></i>
</div>
<div>
<div class="fw-bold text-dark">Yeni Firma Ekle</div>
<div class="small text-muted">Sisteme yeni tedarikçi kaydet</div>
</div>
</a>
</div> </div>
<div class="card-body">
<div class="d-grid gap-2"> <div class="mt-4 p-4 rounded-4 bg-primary bg-opacity-10 border border-primary border-opacity-10">
<button class="btn btn-primary text-start py-3 px-4 rounded-3 d-flex align-items-center"> <h6 class="fw-bold text-primary mb-2"><i class="bi bi-info-circle-fill me-2"></i>Biliyor muydunuz?</h6>
<i class="bi bi-plus-circle-fill me-3 fs-4"></i> <p class="small text-muted mb-0">Sistemimiz OCR teknolojisi sayesinde faturadaki tüm kalemleri otomatik olarak ayrıştırabilir.</p>
<div>
<div class="fw-bold">Fatura Yükle</div>
<div class="small opacity-75">PDF dosyasını sürükle bırak</div>
</div>
</button>
<button class="btn btn-outline-secondary text-start py-3 px-4 rounded-3 d-flex align-items-center">
<i class="bi bi-folder-plus me-3 fs-4"></i>
<div>
<div class="fw-bold">Klasör Tara</div>
<div class="small opacity-75">Yerel dizindeki faturaları bul</div>
</div>
</button>
<button class="btn btn-outline-secondary text-start py-3 px-4 rounded-3 d-flex align-items-center">
<i class="bi bi-building-add me-3 fs-4"></i>
<div>
<div class="fw-bold">Yeni Firma Ekle</div>
<div class="small opacity-75">Firma bilgilerini manuel tanımla</div>
</div>
</button>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,68 @@
{% extends "base.html" %}
{% block title %}İstatistik & Raporlar - FaturaYol{% endblock %}
{% block page_title %}İstatistik & Raporlar{% endblock %}
{% block content %}
<div class="row mb-4">
<div class="col-md-6">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body">
<h5 class="fw-bold mb-4">Aylık Harcama Trendi</h5>
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>Ay</th>
<th>Fatura Adedi</th>
<th class="text-end">Toplam Tutar</th>
</tr>
</thead>
<tbody>
{% for harcama in aylik_harcama %}
<tr>
<td>{{ harcama.tarih__month }}. Ay</td>
<td>{{ harcama.adet }}</td>
<td class="text-end fw-bold">{{ harcama.toplam }} ₺</td>
</tr>
{% empty %}
<tr>
<td colspan="3" class="text-center py-4">Veri bulunamadı</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body">
<h5 class="fw-bold mb-4">KDV Özeti</h5>
<div class="p-4 bg-light rounded-4 text-center mb-4">
<small class="text-muted d-block mb-1">Toplam Ödenen KDV</small>
<h2 class="fw-bold text-success mb-0">{{ kdv_ozet.toplam_kdv|default:0 }} ₺</h2>
</div>
<div class="p-4 bg-light rounded-4 text-center">
<small class="text-muted d-block mb-1">Fatura Başı Ortalama KDV</small>
<h2 class="fw-bold text-primary mb-0">{{ kdv_ozet.ortalama_kdv|default:0|floatformat:2 }} ₺</h2>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card border-0 shadow-sm">
<div class="card-body py-5 text-center">
<i class="bi bi-graph-up-arrow text-primary opacity-25" style="font-size: 4rem;"></i>
<h4 class="mt-3 fw-bold">Gelişmiş Raporlama Yakında</h4>
<p class="text-muted">Grafikler, Excel dışa aktarma ve kategori bazlı analizler bir sonraki güncellemede eklenecektir.</p>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,61 @@
{% extends "base.html" %}
{% block title %}Arama Sonuçları - FaturaYol{% endblock %}
{% block page_title %}"{{ query }}" için Arama Sonuçları{% endblock %}
{% block content %}
<div class="mb-5">
<h5 class="fw-bold mb-3"><i class="bi bi-building me-2 text-primary"></i>Firmalar ({{ firmalar|length }})</h5>
<div class="row">
{% for firma in firmalar %}
<div class="col-md-4 mb-3">
<div class="card border-0 shadow-sm">
<div class="card-body">
<h6 class="fw-bold mb-1">{{ firma.ad }}</h6>
<p class="small text-muted mb-2">VN: {{ firma.vergi_no }}</p>
<a href="{% url 'firma_detay' firma.pk %}" class="btn btn-sm btn-outline-primary rounded-pill">Detaya Git</a>
</div>
</div>
</div>
{% empty %}
<div class="col-12 text-muted">Eşleşen firma bulunamadı.</div>
{% endfor %}
</div>
</div>
<div>
<h5 class="fw-bold mb-3"><i class="bi bi-file-earmark-text me-2 text-primary"></i>Faturalar ({{ faturalar|length }})</h5>
<div class="card border-0 shadow-sm">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead>
<tr>
<th class="ps-4">Fatura No</th>
<th>Firma</th>
<th>Tarih</th>
<th>Genel Toplam</th>
<th class="text-end pe-4">İşlem</th>
</tr>
</thead>
<tbody>
{% for fatura in faturalar %}
<tr>
<td class="ps-4 fw-medium">{{ fatura.fatura_no }}</td>
<td>{{ fatura.firma.ad }}</td>
<td>{{ fatura.tarih|date:"d.m.Y" }}</td>
<td class="fw-bold">₺{{ fatura.genel_toplam }}</td>
<td class="text-end pe-4">
<a href="{% url 'fatura_detay' fatura.pk %}" class="btn btn-sm btn-light rounded-pill">İncele</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="5" class="text-center py-4 text-muted">Eşleşen fatura bulunamadı.</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,7 +1,18 @@
from django.urls import path from django.urls import path
from .views import (
from .views import home home, fatura_arsivi, firma_detay, fatura_detay, raporlar,
firma_ekle, fatura_ekle, search, firma_sil, fatura_sil
)
urlpatterns = [ urlpatterns = [
path("", home, name="home"), path("", home, name="home"),
] path("arsiv/", fatura_arsivi, name="fatura_arsivi"),
path("firma/<int:pk>/", firma_detay, name="firma_detay"),
path("fatura/<int:pk>/", fatura_detay, name="fatura_detay"),
path("raporlar/", raporlar, name="raporlar"),
path("firma/ekle/", firma_ekle, name="firma_ekle"),
path("fatura/ekle/", fatura_ekle, name="fatura_ekle"),
path("arama/", search, name="search"),
path("firma/<int:pk>/sil/", firma_sil, name="firma_sil"),
path("fatura/<int:pk>/sil/", fatura_sil, name="fatura_sil"),
]

View File

@ -1,13 +1,14 @@
from django.shortcuts import render from django.shortcuts import render, get_object_or_404, redirect
from django.db.models import Sum, Count from django.db.models import Sum, Count, Avg, Q
from .models import Firma, Fatura from .models import Firma, Fatura, FaturaKalemi
from .forms import FirmaForm, FaturaForm
def home(request): def home(request):
"""Fatura Yönetimi Gösterge Paneli.""" """Fatura Yönetimi Gösterge Paneli."""
toplam_firma = Firma.objects.count() toplam_firma = Firma.objects.count()
toplam_fatura = Fatura.objects.count() toplam_fatura = Fatura.objects.count()
toplam_harcama = Fatura.objects.aggregate(Sum('genel_toplam'))['genel_toplam__sum'] or 0 toplam_harcama = Fatura.objects.aggregate(Sum('genel_toplam'))['genel_toplam__sum'] or 0
son_faturalar = Fatura.objects.select_related('firma').all()[:10] son_faturalar = Fatura.objects.select_related('firma').all().order_by('-olusturulma_tarihi')[:10]
context = { context = {
"toplam_firma": toplam_firma, "toplam_firma": toplam_firma,
@ -16,4 +17,123 @@ def home(request):
"son_faturalar": son_faturalar, "son_faturalar": son_faturalar,
"active_menu": "dashboard" "active_menu": "dashboard"
} }
return render(request, "core/index.html", context) 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('firma_detay', pk=fatura.firma.pk)
else:
form = FaturaForm(initial=initial)
return render(request, 'core/fatura_form.html', {'form': form, 'title': 'Yeni Fatura Yükle'})
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'})