Files
he-database/sheets/views.py
2025-10-08 10:13:07 +02:00

353 lines
14 KiB
Python

from django.shortcuts import render ,redirect
from django.db.models import Sum, Value, DecimalField
from django.http import JsonResponse
from django.db.models import Q
from decimal import Decimal, InvalidOperation
from django.apps import apps
from datetime import date, datetime
from django.utils import timezone
from .models import Client, SecondTableEntry
from django.db.models import Sum
from django.urls import reverse
from django.db.models.functions import Coalesce
from .forms import BetriebskostenForm
from .models import Betriebskosten
from django.utils.dateparse import parse_date
# Clients Page (Main)
from django.shortcuts import render
from django.db.models import Sum
from datetime import datetime
from .models import Client, SecondTableEntry
def clients_list(request):
# Get all clients
clients = Client.objects.all()
# Get all years available in SecondTableEntry
available_years_qs = SecondTableEntry.objects.dates('date', 'year', order='DESC')
available_years = [y.year for y in available_years_qs]
# Determine selected year
year_param = request.GET.get('year')
if year_param:
selected_year = int(year_param)
else:
# If no year in GET, default to latest available year or current year if DB empty
selected_year = available_years[0] if available_years else datetime.now().year
# Prepare monthly totals per client
monthly_data = []
for client in clients:
monthly_totals = []
for month in range(1, 13):
total = SecondTableEntry.objects.filter(
client=client,
date__year=selected_year,
date__month=month
).aggregate(
total=Coalesce(Sum('lhe_output'), Value(0, output_field=DecimalField()))
)['total']
monthly_totals.append(total)
monthly_data.append({
'client': client,
'monthly_totals': monthly_totals,
'year_total': sum(monthly_totals)
})
return render(request, 'clients_table.html', {
'monthly_data': monthly_data,
'current_year': selected_year,
'available_years': available_years,
'months': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
})
# Table One View (ExcelEntry)
def table_one_view(request):
ExcelEntry = apps.get_model('sheets', 'ExcelEntry')
entries_table1 = ExcelEntry.objects.all().select_related('client')
clients = Client.objects.all()
return render(request, 'table_one.html', {
'entries_table1': entries_table1,
'clients': clients,
})
# Table Two View (SecondTableEntry)
def table_two_view(request):
try:
SecondTableEntry = apps.get_model('sheets', 'SecondTableEntry')
entries = SecondTableEntry.objects.all().order_by('-date')
clients = Client.objects.all()
return render(request, 'table_two.html', {
'entries_table2': entries,
'clients': clients,
})
except Exception as e:
return render(request, 'table_two.html', {
'error_message': f"Failed to load data: {str(e)}",
'entries_table2': [],
'clients': Client.objects.all()
})
# Add Entry (Generic)
def add_entry(request, model_name):
if request.method == 'POST':
try:
model = apps.get_model('sheets', model_name)
if model_name == 'SecondTableEntry':
# Handle date conversion
date_str = request.POST.get('date')
try:
date_obj = datetime.strptime(date_str, '%Y-%m-%d').date() if date_str else None
except (ValueError, TypeError):
return JsonResponse({
'status': 'error',
'message': 'Invalid date format. Use YYYY-MM-DD'
}, status=400)
# Handle Helium Output (Table Two)
lhe_output = request.POST.get('lhe_output')
entry = model.objects.create(
client=Client.objects.get(id=request.POST.get('client_id')),
date=date_obj,
is_warm=request.POST.get('is_warm') == 'true',
lhe_delivery=request.POST.get('lhe_delivery', ''),
lhe_output=Decimal(lhe_output) if lhe_output else None,
notes=request.POST.get('notes', '')
)
return JsonResponse({
'status': 'success',
'id': entry.id,
'client_name': entry.client.name,
'date': entry.date.strftime('%Y-%m-%d') if entry.date else '',
'is_warm': entry.is_warm,
'lhe_delivery': entry.lhe_delivery,
'lhe_output': str(entry.lhe_output) if entry.lhe_output else '',
'notes': entry.notes
})
elif model_name == 'ExcelEntry':
# Parse the date string into a date object
date_str = request.POST.get('date')
try:
date_obj = datetime.strptime(date_str, '%Y-%m-%d').date() if date_str else None
except (ValueError, TypeError):
date_obj = None
# Create the entry
entry = model.objects.create(
client=Client.objects.get(id=request.POST.get('client_id')),
date=date_obj,
pressure=Decimal(request.POST.get('pressure', 0)),
purity=Decimal(request.POST.get('purity', 0)),
notes=request.POST.get('notes', '')
)
# Prepare the response
response_data = {
'status': 'success',
'id': entry.id,
'client_name': entry.client.name,
'pressure': str(entry.pressure),
'purity': str(entry.purity),
'notes': entry.notes
}
# Only add date if it exists
if entry.date:
response_data['date'] = entry.date.strftime('%Y-%m-%d')
else:
response_data['date'] = None
return JsonResponse(response_data)
# Keep your existing SecondTableEntry code here...
except Exception as e:
return JsonResponse({'status': 'error', 'message': str(e)}, status=400)
return JsonResponse({'status': 'error', 'message': 'Invalid request'}, status=400)
# Update Entry (Generic)
def update_entry(request, model_name):
if request.method == 'POST':
try:
model = apps.get_model('sheets', model_name)
entry_id = int(request.POST.get('id'))
entry = model.objects.get(id=entry_id)
# Common updates for both models
entry.client = Client.objects.get(id=request.POST.get('client_id'))
entry.notes = request.POST.get('notes', '')
# Handle date properly for both models
date_str = request.POST.get('date')
if date_str:
try:
entry.date = datetime.strptime(date_str, '%Y-%m-%d').date()
except ValueError:
return JsonResponse({
'status': 'error',
'message': 'Invalid date format. Use YYYY-MM-DD'
}, status=400)
if model_name == 'SecondTableEntry':
# Handle Helium Output specific fields
entry.is_warm = request.POST.get('is_warm') == 'true'
entry.lhe_delivery = request.POST.get('lhe_delivery', '')
lhe_output = request.POST.get('lhe_output')
try:
entry.lhe_output = Decimal(lhe_output) if lhe_output else None
except InvalidOperation:
return JsonResponse({
'status': 'error',
'message': 'Invalid LHe Output value'
}, status=400)
entry.save()
return JsonResponse({
'status': 'success',
'id': entry.id,
'client_name': entry.client.name,
'date': entry.date.strftime('%Y-%m-%d') if entry.date else '',
'is_warm': entry.is_warm,
'lhe_delivery': entry.lhe_delivery,
'lhe_output': str(entry.lhe_output) if entry.lhe_output else '',
'notes': entry.notes
})
elif model_name == 'ExcelEntry':
# Handle Helium Input specific fields
try:
entry.pressure = Decimal(request.POST.get('pressure', 0))
entry.purity = Decimal(request.POST.get('purity', 0))
except InvalidOperation:
return JsonResponse({
'status': 'error',
'message': 'Invalid pressure or purity value'
}, status=400)
entry.save()
return JsonResponse({
'status': 'success',
'id': entry.id,
'client_name': entry.client.name,
'date': entry.date.strftime('%Y-%m-%d') if entry.date else '',
'pressure': str(entry.pressure),
'purity': str(entry.purity),
'notes': entry.notes
})
except model.DoesNotExist:
return JsonResponse({'status': 'error', 'message': 'Entry not found'}, status=404)
except Exception as e:
return JsonResponse({'status': 'error', 'message': str(e)}, status=400)
return JsonResponse({'status': 'error', 'message': 'Invalid request method'}, status=400)
# Delete Entry (Generic)
def delete_entry(request, model_name):
if request.method == 'POST':
try:
model = apps.get_model('sheets', model_name)
entry_id = request.POST.get('id')
entry = model.objects.get(id=entry_id)
entry.delete()
return JsonResponse({'status': 'success', 'message': 'Entry deleted'})
except model.DoesNotExist:
return JsonResponse({'status': 'error', 'message': 'Entry not found'}, status=404)
except Exception as e:
return JsonResponse({'status': 'error', 'message': str(e)}, status=400)
return JsonResponse({'status': 'error', 'message': 'Invalid request'}, status=400)
def betriebskosten_list(request):
items = Betriebskosten.objects.all().order_by('-buchungsdatum')
return render(request, 'betriebskosten_list.html', {'items': items})
def betriebskosten_create(request):
if request.method == 'POST':
try:
entry_id = request.POST.get('id')
if entry_id:
# Update existing entry
entry = Betriebskosten.objects.get(id=entry_id)
else:
# Create new entry
entry = Betriebskosten()
# Get form data
buchungsdatum_str = request.POST.get('buchungsdatum')
rechnungsnummer = request.POST.get('rechnungsnummer')
kostentyp = request.POST.get('kostentyp')
betrag = request.POST.get('betrag')
beschreibung = request.POST.get('beschreibung')
gas_volume = request.POST.get('gas_volume')
# Validate required fields
if not all([buchungsdatum_str, rechnungsnummer, kostentyp, betrag]):
return JsonResponse({'status': 'error', 'message': 'All required fields must be filled'})
# Convert date string to date object
try:
buchungsdatum = parse_date(buchungsdatum_str)
if not buchungsdatum:
return JsonResponse({'status': 'error', 'message': 'Invalid date format'})
except (ValueError, TypeError):
return JsonResponse({'status': 'error', 'message': 'Invalid date format'})
# Set entry values
entry.buchungsdatum = buchungsdatum
entry.rechnungsnummer = rechnungsnummer
entry.kostentyp = kostentyp
entry.betrag = betrag
entry.beschreibung = beschreibung
# Only set gas_volume if kostentyp is helium and gas_volume is provided
if kostentyp == 'helium' and gas_volume:
entry.gas_volume = gas_volume
else:
entry.gas_volume = None
entry.save()
return JsonResponse({
'status': 'success',
'id': entry.id,
'buchungsdatum': entry.buchungsdatum.strftime('%Y-%m-%d'),
'rechnungsnummer': entry.rechnungsnummer,
'kostentyp_display': entry.get_kostentyp_display(),
'gas_volume': str(entry.gas_volume) if entry.gas_volume else '-',
'betrag': str(entry.betrag),
'beschreibung': entry.beschreibung or ''
})
except Exception as e:
return JsonResponse({'status': 'error', 'message': str(e)})
return JsonResponse({'status': 'error', 'message': 'Invalid request method'})
def betriebskosten_delete(request):
if request.method == 'POST':
try:
entry_id = request.POST.get('id')
entry = Betriebskosten.objects.get(id=entry_id)
entry.delete()
return JsonResponse({'status': 'success'})
except Betriebskosten.DoesNotExist:
return JsonResponse({'status': 'error', 'message': 'Entry not found'})
except Exception as e:
return JsonResponse({'status': 'error', 'message': str(e)})
return JsonResponse({'status': 'error', 'message': 'Invalid request method'})