Pregatire pentru productie si adaugare whitenoise

This commit is contained in:
2026-09-07 14:44:20 +03:00
parent 3649b0126d
commit 13b86106ce
8 changed files with 142 additions and 25 deletions
@@ -0,0 +1,47 @@
# management/commands/clear_database.py
from django.core.management.base import BaseCommand
from django.db import connection
from users.models import Employee
from equipment.models import Computer, Monitor, Peripheral
class Command(BaseCommand):
help = "Clear all data from equipment and users tables"
def add_arguments(self, parser):
parser.add_argument(
"--force",
action="store_true",
help="Skip confirmation prompt",
)
def handle(self, *args, **options):
if not options.get("force"):
confirm = input(
"This will DELETE ALL data from Employee, Computer, Monitor, and Peripheral tables. Are you sure? (y/n): "
)
if confirm.lower() != "y":
self.stdout.write("Operation cancelled.")
return
# Option A: Using Django's delete() - slower but triggers signals
Employee.objects.all().delete()
Computer.objects.all().delete()
Monitor.objects.all().delete()
Peripheral.objects.all().delete()
# Option B: Using raw SQL TRUNCATE - faster, resets sequences
with connection.cursor() as cursor:
# Truncate in correct order to respect foreign key constraints
cursor.execute("TRUNCATE TABLE equipment_peripheral CASCADE;")
cursor.execute("TRUNCATE TABLE equipment_monitor CASCADE;")
cursor.execute("TRUNCATE TABLE equipment_computer CASCADE;")
cursor.execute("TRUNCATE TABLE users_employee CASCADE;")
# Reset auto-increment sequences (if using serial/identity columns)
cursor.execute("ALTER SEQUENCE users_employee_id_seq RESTART WITH 1;")
cursor.execute("ALTER SEQUENCE equipment_computer_id_seq RESTART WITH 1;")
cursor.execute("ALTER SEQUENCE equipment_monitor_id_seq RESTART WITH 1;")
cursor.execute("ALTER SEQUENCE equipment_peripheral_id_seq RESTART WITH 1;")
self.stdout.write(self.style.SUCCESS("Database cleared successfully!"))
+71 -12
View File
@@ -18,6 +18,31 @@ class Command(BaseCommand):
# Funcție ajutătoare pentru a evita erorile la date calendaristice goale
# Funcție ajutătoare pentru conversia datelor din DD-MM-YYYY în YYYY-MM-DD
# def parse_date(date_str):
# # Definim data de rezervă dacă rubrică e goală
# fallback_date = "2000-01-01"
# if not date_str or str(date_str).strip() == "":
# return fallback_date
# clean_str = str(date_str).strip()
# try:
# parsed = datetime.strptime(clean_str, "%d-%m-%Y")
# return parsed.strftime("%Y-%m-%d")
# except ValueError:
# try:
# parsed = datetime.strptime(clean_str, "%d/%m/%Y")
# return parsed.strftime("%Y-%m-%d")
# except ValueError:
# # Dacă data există dar formatul e complet invalid, punem tot fallback
# self.stdout.write(
# self.style.WARNING(
# f"Atenție: Data '{clean_str}' e invalidă. Folosim data de azi."
# )
# )
# return fallback_date
def parse_date(date_str):
# Definim data de rezervă dacă rubrică e goală
fallback_date = "2000-01-01"
@@ -27,21 +52,55 @@ class Command(BaseCommand):
clean_str = str(date_str).strip()
# Elimină partea de timp (0:00:00) dacă există
if " " in clean_str:
clean_str = clean_str.split(" ")[0]
# Încearcă să parseze formatul DD-M-YYYY (cu sau fără leading zeros)
try:
parsed = datetime.strptime(clean_str, "%d-%m-%Y")
return parsed.strftime("%Y-%m-%d")
except ValueError:
try:
# Split după '-'
parts = clean_str.split("-")
if len(parts) == 3:
day = parts[0].zfill(2) # Adaugă zero în față dacă e necesar
month = parts[1].zfill(2) # Adaugă zero în față dacă e necesar
year = parts[2]
# Verifică dacă anul are 4 cifre
if len(year) == 2:
year = "20" + year
clean_str = f"{day}-{month}-{year}"
parsed = datetime.strptime(clean_str, "%d-%m-%Y")
return parsed.strftime("%Y-%m-%d")
except (ValueError, IndexError):
pass
# Încearcă și cu slash ca separator
try:
parts = clean_str.split("/")
if len(parts) == 3:
day = parts[0].zfill(2)
month = parts[1].zfill(2)
year = parts[2]
if len(year) == 2:
year = "20" + year
clean_str = f"{day}/{month}/{year}"
parsed = datetime.strptime(clean_str, "%d/%m/%Y")
return parsed.strftime("%Y-%m-%d")
except ValueError:
# Dacă data există dar formatul e complet invalid, punem tot fallback
self.stdout.write(
self.style.WARNING(
f"Atenție: Data '{clean_str}' e invalidă. Folosim data de azi."
)
)
return fallback_date
except (ValueError, IndexError):
pass
# Dacă data există dar formatul e complet invalid, punem fallback
self.stdout.write(
self.style.WARNING(
f"Atenție: Data '{date_str}' e invalidă. Folosim {fallback_date}."
)
)
return fallback_date
# 1. IMPORTUL ANGAJAȚILOR
self.stdout.write("Începe importul angajaților...")
+3 -1
View File
@@ -17,7 +17,9 @@
</div>
<!-- Am adăugat înălțime fixă (max-height) și overflow-y pentru scroll -->
<div class="card-body" style="max-height: 450px; overflow-y: auto;">
<p class="mb-2">Total Calculatoare: <strong>{{ total_computers }}</strong></p>
<p class="mb-1">Total Calculatoare: <strong>{{ total_computers }}</strong></p>
<p class="mb-1">Total Monitoare: <strong>{{ total_monitors }}</strong></p>
<p class="mb-0">Total Periferice: <strong>{{ total_peripherals }}</strong></p>
<hr>
<h6 class="fw-bold text-danger mt-3">Calculatoare Neasignate:</h6>
<ul class="list-unstyled mb-3">
+5
View File
@@ -557,6 +557,9 @@ def handover_protocol_form(request, pk=None):
def dashboard_view(request):
# --- Coloana 1: Sumar Inventar (Înlocuitor temporar pt. Tichete) ---
total_computers = Computer.objects.count()
total_monitors = Monitor.objects.count()
total_peripherals = Peripheral.objects.count()
unassigned_computers = Computer.objects.filter(assigned_to__isnull=True)
unassigned_monitors = Monitor.objects.filter(assigned_to__isnull=True)
@@ -578,6 +581,8 @@ def dashboard_view(request):
context = {
"total_computers": total_computers,
"total_monitors": total_monitors,
"total_peripherals": total_peripherals,
"unassigned_computers": unassigned_computers,
"unassigned_monitors": unassigned_monitors,
"activity_log": activity_log,