From 13b86106cea943cb9941530edf55c9e3800918ef Mon Sep 17 00:00:00 2001 From: CataX Date: Mon, 7 Sep 2026 14:44:20 +0300 Subject: [PATCH] Pregatire pentru productie si adaugare whitenoise --- Z_comenzi.txt | 4 + docker-compose.yml | 14 ++-- .../management/commands/clear_database.py | 47 +++++++++++ .../management/commands/import_access.py | 83 ++++++++++++++++--- equipment/templates/equipment/dashboard.html | 4 +- equipment/views.py | 5 ++ eumi__v4_project/settings.py | 9 +- requirements.txt | 1 + 8 files changed, 142 insertions(+), 25 deletions(-) create mode 100644 equipment/management/commands/clear_database.py diff --git a/Z_comenzi.txt b/Z_comenzi.txt index 8148d2f..6259e5a 100644 --- a/Z_comenzi.txt +++ b/Z_comenzi.txt @@ -46,3 +46,7 @@ docker compose exec web python manage.py migrate docker compose exec web python manage.py makemigrations equipment docker compose exec web python manage.py migrate + +docker compose exec web python manage.py import_access + +docker compose exec web python manage.py clear_database diff --git a/docker-compose.yml b/docker-compose.yml index d65066b..5eec5bf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,15 +4,15 @@ services: volumes: - postgres_data:/var/lib/postgresql/data environment: - - POSTGRES_DB=djangodb - - POSTGRES_USER=djangouser - - POSTGRES_PASSWORD=djangopass + - POSTGRES_DB=eumi-db + - POSTGRES_USER=eumi-user + - POSTGRES_PASSWORD=kBGedy4ScgI7g pgadmin: image: dpage/pgadmin4 environment: - PGADMIN_DEFAULT_EMAIL=catalin@x3c.ro - - PGADMIN_DEFAULT_PASSWORD=Parola123 + - PGADMIN_DEFAULT_PASSWORD=CFratxlTiJ0TB ports: - "5050:80" depends_on: @@ -26,9 +26,9 @@ services: ports: - "8000:8000" environment: - - DB_NAME=djangodb - - DB_USER=djangouser - - DB_PASSWORD=djangopass + - DB_NAME=eumi-db + - DB_USER=eumi-user + - DB_PASSWORD=kBGedy4ScgI7g - DB_HOST=db - DB_PORT=5432 depends_on: diff --git a/equipment/management/commands/clear_database.py b/equipment/management/commands/clear_database.py new file mode 100644 index 0000000..818fbd4 --- /dev/null +++ b/equipment/management/commands/clear_database.py @@ -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!")) diff --git a/equipment/management/commands/import_access.py b/equipment/management/commands/import_access.py index a4919ef..7bffe35 100644 --- a/equipment/management/commands/import_access.py +++ b/equipment/management/commands/import_access.py @@ -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...") diff --git a/equipment/templates/equipment/dashboard.html b/equipment/templates/equipment/dashboard.html index f8c1f65..93bb8d1 100644 --- a/equipment/templates/equipment/dashboard.html +++ b/equipment/templates/equipment/dashboard.html @@ -17,7 +17,9 @@
-

Total Calculatoare: {{ total_computers }}

+

Total Calculatoare: {{ total_computers }}

+

Total Monitoare: {{ total_monitors }}

+

Total Periferice: {{ total_peripherals }}


Calculatoare Neasignate: