From 70e055d20b8089e88c701fa8a4fcf508788907c2 Mon Sep 17 00:00:00 2001 From: Mohamad Hesham Jenbaz Date: Thu, 28 Aug 2025 12:22:27 +0200 Subject: [PATCH] new update --- db.sqlite3 | Bin 151552 -> 155648 bytes sheets/admin.py | 43 ++ ...02_remove_secondtableentry_age_and_more.py | 47 ++ .../0003_alter_secondtableentry_lhe_output.py | 19 + .../0004_alter_secondtableentry_lhe_output.py | 18 + .../0005_alter_secondtableentry_lhe_output.py | 19 + ...ry_age_remove_excelentry_email_and_more.py | 43 ++ sheets/models.py | 39 +- sheets/templates/clients_table.html | 394 +++++---------- sheets/templates/table_one.html | 257 +++++++--- sheets/templates/table_two.html | 465 +++++++++++------- sheets/views.py | 217 +++++--- 12 files changed, 970 insertions(+), 591 deletions(-) create mode 100644 sheets/migrations/0002_remove_secondtableentry_age_and_more.py create mode 100644 sheets/migrations/0003_alter_secondtableentry_lhe_output.py create mode 100644 sheets/migrations/0004_alter_secondtableentry_lhe_output.py create mode 100644 sheets/migrations/0005_alter_secondtableentry_lhe_output.py create mode 100644 sheets/migrations/0006_remove_excelentry_age_remove_excelentry_email_and_more.py diff --git a/db.sqlite3 b/db.sqlite3 index dd31c09fee8589f4cac783460921644555887478..4121ae13645a8c279ed653565b6f7f74d118eaa2 100644 GIT binary patch delta 3864 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 diff --git a/sheets/admin.py b/sheets/admin.py index c6fe108..7f2c5ce 100644 --- a/sheets/admin.py +++ b/sheets/admin.py @@ -1,2 +1,45 @@ from django.contrib import admin +from .models import Client # Only import Client +from .models import SecondTableEntry +# Register only the Client model +@admin.register(Client) +class ClientAdmin(admin.ModelAdmin): + list_display = ('name', 'address') + search_fields = ('name',) + + # Optional: Customize the add form fields + fields = ['name', 'address'] + +@admin.register(SecondTableEntry) +class SecondTableEntryAdmin(admin.ModelAdmin): + list_display = ('id', 'client', 'date', 'is_warm', 'lhe_output_short', 'notes_preview') + list_display_links = ('id', 'client') # Fields that link to edit page + list_editable = ('is_warm',) + list_filter = ('is_warm', 'client') + search_fields = ('client__name', 'notes') + date_hierarchy = 'date' + ordering = ('-date',) + + fieldsets = ( + (None, { + 'fields': ('client', 'date') + }), + ('LHe Data', { + 'fields': ('is_warm', 'lhe_delivery', 'lhe_output'), + 'description': 'Enter all liquid helium measurements' + }), + ('Additional Info', { + 'fields': ('notes',), + 'classes': ('collapse',) + }) + ) + + # Custom display methods + def lhe_output_short(self, obj): + return f"{obj.lhe_output} L" if obj.lhe_output else "-" + lhe_output_short.short_description = 'Output' + + def notes_preview(self, obj): + return obj.notes[:30] + '...' if obj.notes else "" + notes_preview.short_description = 'Notes Preview' \ No newline at end of file diff --git a/sheets/migrations/0002_remove_secondtableentry_age_and_more.py b/sheets/migrations/0002_remove_secondtableentry_age_and_more.py new file mode 100644 index 0000000..eaab916 --- /dev/null +++ b/sheets/migrations/0002_remove_secondtableentry_age_and_more.py @@ -0,0 +1,47 @@ +# Generated by Django 5.2.1 on 2025-07-08 12:13 + +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sheets', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='secondtableentry', + name='age', + ), + migrations.RemoveField( + model_name='secondtableentry', + name='email', + ), + migrations.AddField( + model_name='secondtableentry', + name='date', + field=models.DateField(default=django.utils.timezone.now), + ), + migrations.AddField( + model_name='secondtableentry', + name='is_warm', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='secondtableentry', + name='lhe_delivery', + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name='secondtableentry', + name='lhe_output', + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name='secondtableentry', + name='notes', + field=models.TextField(blank=True, null=True), + ), + ] diff --git a/sheets/migrations/0003_alter_secondtableentry_lhe_output.py b/sheets/migrations/0003_alter_secondtableentry_lhe_output.py new file mode 100644 index 0000000..073b12a --- /dev/null +++ b/sheets/migrations/0003_alter_secondtableentry_lhe_output.py @@ -0,0 +1,19 @@ +# Generated by Django 5.2.1 on 2025-07-08 13:18 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sheets', '0002_remove_secondtableentry_age_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='secondtableentry', + name='lhe_output', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, validators=[django.core.validators.MinValueValidator(0)]), + ), + ] diff --git a/sheets/migrations/0004_alter_secondtableentry_lhe_output.py b/sheets/migrations/0004_alter_secondtableentry_lhe_output.py new file mode 100644 index 0000000..9a6c3a2 --- /dev/null +++ b/sheets/migrations/0004_alter_secondtableentry_lhe_output.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.1 on 2025-07-08 13:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sheets', '0003_alter_secondtableentry_lhe_output'), + ] + + operations = [ + migrations.AlterField( + model_name='secondtableentry', + name='lhe_output', + field=models.CharField(blank=True, max_length=100, null=True), + ), + ] diff --git a/sheets/migrations/0005_alter_secondtableentry_lhe_output.py b/sheets/migrations/0005_alter_secondtableentry_lhe_output.py new file mode 100644 index 0000000..dffa88b --- /dev/null +++ b/sheets/migrations/0005_alter_secondtableentry_lhe_output.py @@ -0,0 +1,19 @@ +# Generated by Django 5.2.1 on 2025-07-08 13:36 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sheets', '0004_alter_secondtableentry_lhe_output'), + ] + + operations = [ + migrations.AlterField( + model_name='secondtableentry', + name='lhe_output', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, validators=[django.core.validators.MinValueValidator(0)]), + ), + ] diff --git a/sheets/migrations/0006_remove_excelentry_age_remove_excelentry_email_and_more.py b/sheets/migrations/0006_remove_excelentry_age_remove_excelentry_email_and_more.py new file mode 100644 index 0000000..105ed6f --- /dev/null +++ b/sheets/migrations/0006_remove_excelentry_age_remove_excelentry_email_and_more.py @@ -0,0 +1,43 @@ +# Generated by Django 5.2.1 on 2025-07-09 11:15 + +import django.core.validators +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sheets', '0005_alter_secondtableentry_lhe_output'), + ] + + operations = [ + migrations.RemoveField( + model_name='excelentry', + name='age', + ), + migrations.RemoveField( + model_name='excelentry', + name='email', + ), + migrations.AddField( + model_name='excelentry', + name='date', + field=models.DateField(default=django.utils.timezone.now), + ), + migrations.AddField( + model_name='excelentry', + name='notes', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='excelentry', + name='pressure', + field=models.DecimalField(decimal_places=2, default=0.0, max_digits=10, validators=[django.core.validators.MinValueValidator(0)]), + ), + migrations.AddField( + model_name='excelentry', + name='purity', + field=models.DecimalField(decimal_places=2, default=0.0, max_digits=5, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)]), + ), + ] diff --git a/sheets/models.py b/sheets/models.py index 130df7e..22cf221 100644 --- a/sheets/models.py +++ b/sheets/models.py @@ -1,4 +1,8 @@ from django.db import models +from django.utils import timezone +from django.core.validators import MinValueValidator, MaxValueValidator + + class Client(models.Model): name = models.CharField(max_length=100) @@ -9,12 +13,39 @@ class Client(models.Model): class ExcelEntry(models.Model): client = models.ForeignKey(Client, on_delete=models.CASCADE) - age = models.IntegerField() - email = models.EmailField() + date = models.DateField(default=timezone.now) + pressure = models.DecimalField( + max_digits=10, + decimal_places=2, + validators=[MinValueValidator(0)], + default=0.00 + ) + purity = models.DecimalField( + max_digits=5, + decimal_places=2, + validators=[MinValueValidator(0), MaxValueValidator(100)], + default=0.00 + ) + notes = models.TextField(blank=True, null=True) date_joined = models.DateField(auto_now_add=True) + def __str__(self): + return f"{self.client.name} - {self.date}" + class SecondTableEntry(models.Model): client = models.ForeignKey(Client, on_delete=models.CASCADE) - age = models.IntegerField() - email = models.EmailField() + date = models.DateField(default=timezone.now) # Added default value + is_warm = models.BooleanField(default=False) + lhe_delivery = models.CharField(max_length=100, blank=True, null=True) + lhe_output = models.DecimalField( + max_digits=10, + decimal_places=2, + validators=[MinValueValidator(0)], + blank=True, + null=True + ) + notes = models.TextField(blank=True, null=True) date_joined = models.DateField(auto_now_add=True) + + def __str__(self): + return f"{self.client.name} - {self.date}" \ No newline at end of file diff --git a/sheets/templates/clients_table.html b/sheets/templates/clients_table.html index c79b444..8591a0c 100644 --- a/sheets/templates/clients_table.html +++ b/sheets/templates/clients_table.html @@ -1,290 +1,124 @@ - - - - - Clients Table - - - - - - +{% extends "base.html" %} +{% block content %} +
+ +
+ + +
-
-

Clients Table

- - - - - - - - - - - - - {% for client in clients %} - - - - - - - + +
# IDNameAddressActions
{{ forloop.counter }} {{ client.id }}{{ client.name }}{{ client.address }} - - -
+ + + + {% for month in months %} + {% endfor %} - -
Client{{ month }}
-
+ Total + + + + {% for data in monthly_data %} + + {{ data.client.name }} + {% for total in data.monthly_totals %} + {{ total|floatformat:2 }} + {% endfor %} + {{ data.year_total|floatformat:2 }} + + {% endfor %} + + - - - - - - - + + +{% endblock %} \ No newline at end of file diff --git a/sheets/templates/table_one.html b/sheets/templates/table_one.html index ece7b55..9df8de3 100644 --- a/sheets/templates/table_one.html +++ b/sheets/templates/table_one.html @@ -27,18 +27,32 @@ } table { width: 100%; + table-layout: fixed; border-collapse: collapse; - margin-top: 20px; } th, td { padding: 12px; - text-align: left; + text-align: center; border-bottom: 1px solid #ddd; } + th:nth-child(1), td:nth-child(1) { width: 5%; } /* # column */ + th:nth-child(2), td:nth-child(2) { width: 5%; } /* ID column */ + th:nth-child(3), td:nth-child(3) { width: 15%; } /* Client column */ + th:nth-child(4), td:nth-child(4) { width: 10%; } /* Entry 1 (Pressure) */ + th:nth-child(5), td:nth-child(5) { width: 10%; } /* Entry 2 (Purity) */ + th:nth-child(6), td:nth-child(6) { width: 15%; } /* Date Joined */ + th:nth-child(7), td:nth-child(7) { width: 25%; } /* Notes */ + th:nth-child(7), td:nth-child(7) { width: 30%; } /* Actions */ + + .actions { + white-space: nowrap; /* Prevent buttons from wrapping */ + } th { background-color: #007bff; color: white; font-weight: bold; + position: sticky; + top: 0; } tr:hover { background-color: #f1f1f1; @@ -106,6 +120,7 @@ .add-row-btn:hover { background-color: #0056b3; } + @@ -118,14 +133,25 @@
+ + + + + + + + + + - - + + + @@ -135,9 +161,10 @@ - - - + + + +
# ID ClientEntry 1Entry 2DruckReinheit Date JoinedNotes Actions
{{ forloop.counter }} {{ entry.id }} {{ entry.client.name }}{{ entry.age }}{{ entry.email }}{{ entry.date_joined }}{{ entry.pressure|floatformat:2 }}{{ entry.purity|floatformat:2 }}{{ entry.date_joined|date:"Y-m-d" }}{{ entry.notes|default:"" }} @@ -152,30 +179,72 @@ - - - -
- - - ⇦ Go to Clients + + -

Helium Output

- -
- - - - - {% for entry in entries_table2 %} - - - - - - - - - - {% endfor %} - -
#IDClientDateWarmLHe AnlieferungLHe AusgabeCommentsActions
{{ forloop.counter }}{{ entry.id }}{{ entry.client.name }}{{ entry.age }}{{ entry.email }}{{ entry.date_joined }} - - -
-
- - - -
- - -