This commit is contained in:
2026-01-06 11:52:03 +01:00
parent b74cf45c5c
commit 34f040df30
11 changed files with 1027 additions and 264 deletions

Binary file not shown.

View File

@@ -1,20 +1,21 @@
from django.contrib import admin
from .models import Client # Only import Client
from .models import SecondTableEntry
from .models import Institute, Client, ExcelEntry, SecondTableEntry, Betriebskosten
# Register Institute model
admin.site.register(Institute)
# Register only the Client model
@admin.register(Client)
class ClientAdmin(admin.ModelAdmin):
list_display = ('name', 'address')
search_fields = ('name',)
list_display = ('name', 'institute', 'address') # Added institute here
search_fields = ('name', 'institute__name') # Added institute search
# Optional: Customize the add form fields
fields = ['name', 'address']
# FIX: Include 'institute' in the fields list
fields = ['name', 'institute', 'address'] # Added 'institute' here
@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_display_links = ('id', 'client')
list_editable = ('is_warm',)
list_filter = ('is_warm', 'client')
search_fields = ('client__name', 'notes')
@@ -35,11 +36,14 @@ class SecondTableEntryAdmin(admin.ModelAdmin):
})
)
# 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'
notes_preview.short_description = 'Notes Preview'
# Register other models
admin.site.register(ExcelEntry)
admin.site.register(Betriebskosten)

View File

@@ -1,5 +1,7 @@
from django import forms
from .models import ExcelEntry, Betriebskosten
from .models import ExcelEntry, Betriebskosten, Institute
class ExcelEntryForm(forms.ModelForm):
class Meta:

View File

@@ -0,0 +1,31 @@
# Generated by Django 5.1.5 on 2025-10-27 10:08
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('sheets', '0007_betriebskosten'),
]
operations = [
migrations.CreateModel(
name='Institute',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
],
),
migrations.AlterField(
model_name='betriebskosten',
name='kostentyp',
field=models.CharField(choices=[('sach', 'Sachkostöen'), ('ln2', 'LN2'), ('helium', 'Helium'), ('inv', 'Inventar')], max_length=10, verbose_name='Kostentyp'),
),
migrations.AddField(
model_name='client',
name='institute',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sheets.institute'),
),
]

View File

@@ -0,0 +1,20 @@
# Generated by Django 5.1.5 on 2025-10-27 10:28
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('sheets', '0008_institute_alter_betriebskosten_kostentyp_and_more'),
]
operations = [
migrations.AlterField(
model_name='client',
name='institute',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='sheets.institute'),
preserve_default=False,
),
]

View File

@@ -0,0 +1,49 @@
# Generated by Django 5.1.5 on 2025-11-25 11:08
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('sheets', '0009_alter_client_institute'),
]
operations = [
migrations.AddField(
model_name='excelentry',
name='constant_300',
field=models.DecimalField(decimal_places=3, default=300.0, max_digits=10),
),
migrations.AddField(
model_name='excelentry',
name='druckkorrektur',
field=models.DecimalField(decimal_places=3, default=1.0, max_digits=10, validators=[django.core.validators.MinValueValidator(0)]),
),
migrations.AddField(
model_name='excelentry',
name='korrig_druck',
field=models.DecimalField(decimal_places=6, default=0.0, max_digits=12),
),
migrations.AddField(
model_name='excelentry',
name='lhe',
field=models.DecimalField(decimal_places=6, default=0.0, max_digits=12),
),
migrations.AddField(
model_name='excelentry',
name='lhe_ges',
field=models.DecimalField(decimal_places=6, default=0.0, max_digits=12),
),
migrations.AddField(
model_name='excelentry',
name='lhe_zus',
field=models.DecimalField(decimal_places=3, default=0.0, max_digits=10, validators=[django.core.validators.MinValueValidator(0)]),
),
migrations.AddField(
model_name='excelentry',
name='nm3',
field=models.DecimalField(decimal_places=6, default=0.0, max_digits=12),
),
]

View File

@@ -2,6 +2,11 @@ from django.db import models
from django.utils import timezone
from django.core.validators import MinValueValidator, MaxValueValidator
class Institute(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Betriebskosten(models.Model):
KOSTENTYP_CHOICES = [
@@ -30,9 +35,10 @@ class Betriebskosten(models.Model):
class Client(models.Model):
name = models.CharField(max_length=100)
address = models.TextField()
institute = models.ForeignKey(Institute, on_delete=models.CASCADE) # Remove null=True, blank=True
def __str__(self):
return self.name
return f"{self.name} ({self.institute.name})"
class ExcelEntry(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
@@ -52,23 +58,65 @@ class ExcelEntry(models.Model):
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}"
# Manual input
lhe_zus = models.DecimalField(
max_digits=10,
decimal_places=3,
validators=[MinValueValidator(0)],
default=0.0
)
druckkorrektur = models.DecimalField(
max_digits=10,
decimal_places=3,
validators=[MinValueValidator(0)],
default=1.0
)
# Auto-calculated values (saved)
constant_300 = models.DecimalField(
max_digits=10,
decimal_places=3,
default=300.0
)
korrig_druck = models.DecimalField(
max_digits=12,
decimal_places=6,
default=0.0
)
nm3 = models.DecimalField(
max_digits=12,
decimal_places=6,
default=0.0
)
lhe = models.DecimalField(
max_digits=12,
decimal_places=6,
default=0.0
)
lhe_ges = models.DecimalField(
max_digits=12,
decimal_places=6,
default=0.0
)
class SecondTableEntry(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
date = models.DateField(default=timezone.now) # Added default value
date = models.DateField(default=timezone.now)
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
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}"
return f"{self.client.name} - {self.date}"

View File

@@ -15,11 +15,12 @@
background-color: #f4f4f9;
}
.table-container {
width: 48%;
width: 100%;
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
overflow-x: auto;
}
h2 {
text-align: center;
@@ -34,15 +35,23 @@
padding: 12px;
text-align: center;
border-bottom: 1px solid #ddd;
word-wrap: break-word;
}
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 */
th:nth-child(1), td:nth-child(1) { width: 3%; } /* # column */
th:nth-child(2), td:nth-child(2) { width: 3%; } /* ID column */
th:nth-child(3), td:nth-child(3) { width: 8%; } /* Institute */
th:nth-child(4), td:nth-child(4) { width: 8%; } /* Client */
th:nth-child(5), td:nth-child(5) { width: 5%; } /* Druck */
th:nth-child(6), td:nth-child(6) { width: 5%; } /* Reinheit */
th:nth-child(7), td:nth-child(7) { width: 5%; } /* Druckkorrektur */
th:nth-child(8), td:nth-child(8) { width: 6%; } /* ges. Flasch. Inhalt */
th:nth-child(9), td:nth-child(9) { width: 6%; } /* Korrig. Druck */
th:nth-child(10), td:nth-child(10) { width: 5%; } /* Nm³ */
th:nth-child(11), td:nth-child(11) { width: 5%; } /* L-He */
th:nth-child(12), td:nth-child(12) { width: 5%; } /* L-He zus. */
th:nth-child(13), td:nth-child(13) { width: 6%; } /* L-He ges. */
th:nth-child(14), td:nth-child(14) { width: 6%; } /* Date Joined */
th:nth-child(15), td:nth-child(15) { width: 8%; } /* Actions */
.actions {
white-space: nowrap; /* Prevent buttons from wrapping */
@@ -84,23 +93,58 @@
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
z-index: 1000;
width: 500px;
max-height: 90vh;
overflow-y: auto;
}
.popup input, .popup select {
.popup h3 {
margin-top: 0;
border-bottom: 1px solid #ddd;
padding-bottom: 10px;
}
.popup label {
display: block;
margin-bottom: 10px;
margin-bottom: 5px;
font-weight: bold;
}
.popup input, .popup select, .popup textarea {
display: block;
margin-bottom: 15px;
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
.popup textarea {
height: 100px;
resize: vertical;
}
.popup-buttons {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 20px;
}
.popup button {
margin-top: 10px;
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
.save-btn {
background-color: #28a745;
color: white;
}
.cancel-btn {
background-color: #6c757d;
color: white;
}
.help-btn {
background-color: #17a2b8;
color: white;
}
.close-btn {
cursor: pointer;
float: right;
@@ -120,7 +164,34 @@
.add-row-btn:hover {
background-color: #0056b3;
}
.input-with-label {
display: flex;
align-items: center;
margin-bottom: 15px;
}
.input-with-label label {
width: 150px;
margin-bottom: 0;
margin-right: 10px;
}
.input-with-label input {
flex: 1;
margin-bottom: 0;
}
.formula-display {
background-color: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 4px;
padding: 8px;
margin-bottom: 15px;
font-size: 12px;
color: #6c757d;
font-style: italic;
}
.readonly-field {
background-color: #e9ecef;
color: #6c757d;
}
</style>
</head>
<body>
@@ -133,64 +204,96 @@
<div class="table-container">
<button class="add-row-btn" id="add-row-one">Add Row</button>
<table id="table-one">
<colgroup>
<col style="width: 5%"> <!-- # -->
<col style="width: 5%"> <!-- ID -->
<col style="width: 15%"> <!-- Client -->
<col style="width: 10%"> <!-- Druck -->
<col style="width: 10%"> <!-- Reinheit -->
<col style="width: 15%"> <!-- Date Joined -->
<col style="width: 25%"> <!-- Notes -->
<col style="width: 15%"> <!-- Actions -->
</colgroup>
<thead>
<tr>
<th>#</th>
<th>ID</th>
<th>Client</th>
<th>Druck</th>
<th>Reinheit</th>
<th>Date Joined</th>
<th>Notes</th>
<th>Actions</th>
<colgroup>
<col style="width: 3%"> <!-- # -->
<col style="width: 3%"> <!-- ID -->
<col style="width: 8%"> <!-- Institute -->
<col style="width: 8%"> <!-- Client -->
<col style="width: 5%"> <!-- Druck -->
<col style="width: 5%"> <!-- Reinheit -->
<col style="width: 5%"> <!-- Druckkorrektur -->
<col style="width: 6%"> <!-- ges. Flasch. Inhalt -->
<col style="width: 6%"> <!-- Korrig. Druck -->
<col style="width: 5%"> <!-- Nm³ -->
<col style="width: 5%"> <!-- L-He -->
<col style="width: 5%"> <!-- L-He zus. -->
<col style="width: 6%"> <!-- L-He ges. -->
<col style="width: 6%"> <!-- Date Joined -->
<col style="width: 8%"> <!-- Actions -->
</colgroup>
<thead>
<tr>
<th>#</th>
<th>ID</th>
<th>Institute</th>
<th>Client</th>
<th>Druck</th>
<th>Reinheit</th>
<th>Druckkorrektur</th>
<th>ges. Flasch. Inhalt</th>
<th>Korrig. Druck</th>
<th>Nm³</th>
<th>L-He</th>
<th>L-He zus.</th>
<th>L-He ges.</th>
<th>Date Joined</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for entry in entries_table1 %}
<tr data-id="{{ entry.id }}">
<td>{{ forloop.counter }}</td>
<td>{{ entry.id }}</td>
<td>{{ entry.client.institute.name }}</td>
<td>{{ entry.client.name }}</td>
<td>{{ entry.pressure|floatformat:2 }}</td>
<td>{{ entry.purity|floatformat:2 }}</td>
<td>{{ entry.druckkorrektur|floatformat:3 }}</td>
<td>{{ entry.constant_300|floatformat:3 }}</td>
<td>{{ entry.korrig_druck|floatformat:6 }}</td>
<td>{{ entry.nm3|floatformat:6 }}</td>
<td>{{ entry.lhe|floatformat:6 }}</td>
<td>{{ entry.lhe_zus|floatformat:3 }}</td>
<td>{{ entry.lhe_ges|floatformat:6 }}</td>
<td>{{ entry.date_joined|date:"Y-m-d" }}</td>
<td class="actions">
<button class="edit-btn-one">Edit</button>
<button class="delete-btn-one">Delete</button>
</td>
</tr>
</thead>
<tbody>
{% for entry in entries_table1 %}
<tr data-id="{{ entry.id }}">
<td>{{ forloop.counter }}</td>
<td>{{ entry.id }}</td>
<td>{{ entry.client.name }}</td>
<td>{{ entry.pressure|floatformat:2 }}</td>
<td>{{ entry.purity|floatformat:2 }}</td>
<td>{{ entry.date_joined|date:"Y-m-d" }}</td>
<td>{{ entry.notes|default:"" }}</td>
<td class="actions">
<button class="edit-btn-one">Edit</button>
<button class="delete-btn-one">Delete</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endfor %}
</tbody>
</table>
</div>
<!-- Add Popup -->
<div id="add-popup-one" class="popup">
<span class="close-btn">&times;</span>
<h3>He Gas Bundle</h3>
<!-- Institute Selection -->
<label for="add-institute-id">Institute:</label>
<select id="add-institute-id">
<option value="">Select Institute</option>
{% for institute in institutes %}
<option value="{{ institute.id }}">{{ institute.name }}</option>
{% endfor %}
</select>
<!-- Client Selection -->
<label for="add-client-id">Kunde:</label>
<select id="add-client-id">
<select id="add-client-id" disabled>
<option value="">Select Institute first</option>
{% for client in clients %}
<option value="{{ client.id }}">{{ client.name }}</option>
<option value="{{ client.id }}" data-institute="{{ client.institute.id }}">{{ client.name }}</option>
{% endfor %}
</select>
<label for="add-date">Date:</label>
<input type="date" id="add-date">
<!-- Manual Input Fields -->
<div class="input-with-label">
<label for="add-pressure">Druck:</label>
<input type="number" id="add-pressure" placeholder="Enter pressure" step="0.01" min="0">
@@ -201,8 +304,46 @@
<input type="number" id="add-purity" placeholder="Enter purity" step="0.01" min="0" max="100">
</div>
<label for="add-notes">Notes:</label>
<textarea id="add-notes" placeholder="Additional notes"></textarea>
<div class="input-with-label">
<label for="add-druckkorrektur">Druckkorrektur:</label>
<input type="number" id="add-druckkorrektur" placeholder="Enter Druckkorrektur" step="0.001" min="0" value="1.0">
</div>
<div class="input-with-label">
<label for="add-lhe-zus">L-He zus.:</label>
<input type="number" id="add-lhe-zus" placeholder="Enter L-He zus." step="0.001" min="0" value="0.0">
</div>
<!-- Auto-calculated Fields with Formulas -->
<div class="input-with-label">
<label for="add-constant-300">ges. Flasch. Inhalt:</label>
<input type="number" id="add-constant-300" value="300.000" step="0.001" readonly class="readonly-field">
</div>
<div class="formula-display">Formula: Fixed value (300)</div>
<div class="input-with-label">
<label for="add-korrig-druck">Korrig. Druck:</label>
<input type="number" id="add-korrig-druck" step="0.000001" readonly class="readonly-field">
</div>
<div class="formula-display">Formula: Druck * Druckkorrektur / ((Druck * Druckkorrektur) / 2000 + 1)</div>
<div class="input-with-label">
<label for="add-nm3">Nm³:</label>
<input type="number" id="add-nm3" step="0.000001" readonly class="readonly-field">
</div>
<div class="formula-display">Formula: (ges. Flasch. Inhalt * Korrig. Druck) / 1000</div>
<div class="input-with-label">
<label for="add-lhe">L-He:</label>
<input type="number" id="add-lhe" step="0.000001" readonly class="readonly-field">
</div>
<div class="formula-display">Formula: Nm³ * (1 - Reinheit/100) / 0.75</div>
<div class="input-with-label">
<label for="add-lhe-ges">L-He ges.:</label>
<input type="number" id="add-lhe-ges" step="0.000001" readonly class="readonly-field">
</div>
<div class="formula-display">Formula: L-He zus. + L-He</div>
<div class="popup-buttons">
<button class="save-btn" id="save-add-one">Save</button>
@@ -217,16 +358,28 @@
<h3>He Gas Bundle</h3>
<input type="hidden" id="edit-id">
<!-- Institute Selection -->
<label for="edit-institute-id">Institute:</label>
<select id="edit-institute-id">
<option value="">Select Institute</option>
{% for institute in institutes %}
<option value="{{ institute.id }}">{{ institute.name }}</option>
{% endfor %}
</select>
<!-- Client Selection -->
<label for="edit-client-id">Kunde:</label>
<select id="edit-client-id">
<select id="edit-client-id" disabled>
<option value="">Select Institute first</option>
{% for client in clients %}
<option value="{{ client.id }}">{{ client.name }}</option>
<option value="{{ client.id }}" data-institute="{{ client.institute.id }}">{{ client.name }}</option>
{% endfor %}
</select>
<label for="edit-date">Date:</label>
<input type="date" id="edit-date">
<!-- Manual Input Fields -->
<div class="input-with-label">
<label for="edit-pressure">Druck:</label>
<input type="number" id="edit-pressure" placeholder="Enter pressure" step="0.01" min="0">
@@ -237,8 +390,46 @@
<input type="number" id="edit-purity" placeholder="Enter purity" step="0.01" min="0" max="100">
</div>
<label for="edit-notes">Notes:</label>
<textarea id="edit-notes" placeholder="Additional notes"></textarea>
<div class="input-with-label">
<label for="edit-druckkorrektur">Druckkorrektur:</label>
<input type="number" id="edit-druckkorrektur" placeholder="Enter Druckkorrektur" step="0.001" min="0" value="1.0">
</div>
<div class="input-with-label">
<label for="edit-lhe-zus">L-He zus.:</label>
<input type="number" id="edit-lhe-zus" placeholder="Enter L-He zus." step="0.001" min="0" value="0.0">
</div>
<!-- Auto-calculated Fields with Formulas -->
<div class="input-with-label">
<label for="edit-constant-300">ges. Flasch. Inhalt:</label>
<input type="number" id="edit-constant-300" value="300.000" step="0.001" readonly class="readonly-field">
</div>
<div class="formula-display">Formula: Fixed value (300)</div>
<div class="input-with-label">
<label for="edit-korrig-druck">Korrig. Druck:</label>
<input type="number" id="edit-korrig-druck" step="0.000001" readonly class="readonly-field">
</div>
<div class="formula-display">Formula: Druck * Druckkorrektur / ((Druck * Druckkorrektur) / 2000 + 1)</div>
<div class="input-with-label">
<label for="edit-nm3">Nm³:</label>
<input type="number" id="edit-nm3" step="0.000001" readonly class="readonly-field">
</div>
<div class="formula-display">Formula: (ges. Flasch. Inhalt * Korrig. Druck) / 1000</div>
<div class="input-with-label">
<label for="edit-lhe">L-He:</label>
<input type="number" id="edit-lhe" step="0.000001" readonly class="readonly-field">
</div>
<div class="formula-display">Formula: Nm³ * (1 - Reinheit/100) / 0.75</div>
<div class="input-with-label">
<label for="edit-lhe-ges">L-He ges.:</label>
<input type="number" id="edit-lhe-ges" step="0.000001" readonly class="readonly-field">
</div>
<div class="formula-display">Formula: L-He zus. + L-He</div>
<div class="popup-buttons">
<button class="save-btn" id="save-edit-one">Save</button>
@@ -252,16 +443,127 @@
let currentTableId = 'table-one';
let currentModelName = 'ExcelEntry';
// Store all client options for both dropdowns
const allClientOptions = $('#add-client-id').html();
const allEditClientOptions = $('#edit-client-id').html();
// Function to filter clients based on institute selection
function filterClients(instituteId, targetSelect, allOptions) {
if (!instituteId) {
// Show only the default option if no institute selected
targetSelect.html('<option value="">Select Institute first</option>');
targetSelect.prop('disabled', true);
} else {
// Restore all options first
targetSelect.html(allOptions);
// Enable the dropdown
targetSelect.prop('disabled', false);
// Hide all options first
targetSelect.find('option').hide();
// Always show the "Select Client" option
targetSelect.find('option[value=""]').show().text('Select Client');
// Show only clients from selected institute
const clientsFromInstitute = targetSelect.find(`option[data-institute="${instituteId}"]`);
if (clientsFromInstitute.length > 0) {
clientsFromInstitute.show();
} else {
targetSelect.html('<option value="">No clients found for this institute</option>');
}
// Reset selection
targetSelect.val('');
}
}
// Function to calculate all derived values
function calculateDerivedValues(prefix) {
const pressure = parseFloat($(`#${prefix}-pressure`).val()) || 0;
const purity = parseFloat($(`#${prefix}-purity`).val()) || 0;
const druckkorrektur = parseFloat($(`#${prefix}-druckkorrektur`).val()) || 1.0;
const lheZus = parseFloat($(`#${prefix}-lhe-zus`).val()) || 0;
const gesFlaschInhalt = parseFloat($(`#${prefix}-constant-300`).val()) || 300.0;
// Calculate Korrig. Druck
const korrigDruck = pressure * druckkorrektur / ((pressure * druckkorrektur) / 2000 + 1);
$(`#${prefix}-korrig-druck`).val(korrigDruck.toFixed(6));
// Calculate Nm³ - Updated to divide by 1000
const nm3 = (gesFlaschInhalt * korrigDruck) / 1000;
$(`#${prefix}-nm3`).val(nm3.toFixed(6));
// Calculate L-He
const lhe = nm3 * (1 - purity/100) / 0.75;
$(`#${prefix}-lhe`).val(lhe.toFixed(6));
// Calculate L-He ges.
const lheGes = lheZus + lhe;
$(`#${prefix}-lhe-ges`).val(lheGes.toFixed(6));
}
// Institute change handler for add popup
$('#add-institute-id').on('change', function() {
const instituteId = $(this).val();
filterClients(instituteId, $('#add-client-id'), allClientOptions);
});
// Institute change handler for edit popup
$('#edit-institute-id').on('change', function() {
const instituteId = $(this).val();
filterClients(instituteId, $('#edit-client-id'), allEditClientOptions);
});
// Add event listeners for calculation triggers in add popup
$('#add-pressure, #add-purity, #add-druckkorrektur, #add-lhe-zus').on('input change', function() {
calculateDerivedValues('add');
});
// Add event listeners for calculation triggers in edit popup
$('#edit-pressure, #edit-purity, #edit-druckkorrektur, #edit-lhe-zus').on('input change', function() {
calculateDerivedValues('edit');
});
$('#add-row-one').on('click', function () {
// Reset form
$('#add-institute-id').val('');
$('#add-client-id').html('<option value="">Select Institute first</option>');
$('#add-client-id').prop('disabled', true);
$('#add-date').val('');
$('#add-pressure').val('');
$('#add-purity').val('');
$('#add-druckkorrektur').val('1.0');
$('#add-lhe-zus').val('0.0');
$('#add-constant-300').val('300.000');
$('#add-korrig-druck').val('');
$('#add-nm3').val('');
$('#add-lhe').val('');
$('#add-lhe-ges').val('');
$('#add-popup-one').fadeIn();
});
$('.close-btn').on('click', function () {
$('.close-btn, .cancel-btn').on('click', function () {
$('.popup').fadeOut();
});
// Add
$('#save-add-one').on('click', function() {
const clientId = $('#add-client-id').val();
const instituteId = $('#add-institute-id').val();
if (!instituteId) {
alert('Please select an institute');
return;
}
if (!clientId) {
alert('Please select a client');
return;
}
// Validate date first
let dateInput = $('#add-date').val();
if (!dateInput) {
@@ -272,6 +574,9 @@
// Validate numbers
let pressure = parseFloat($('#add-pressure').val());
let purity = parseFloat($('#add-purity').val());
let druckkorrektur = parseFloat($('#add-druckkorrektur').val()) || 1.0;
let lheZus = parseFloat($('#add-lhe-zus').val()) || 0;
let gesFlaschInhalt = parseFloat($('#add-constant-300').val()) || 300.0;
if (isNaN(pressure) || pressure < 0) {
alert('Please enter a valid pressure value');
@@ -283,13 +588,37 @@
return;
}
if (isNaN(druckkorrektur) || druckkorrektur < 0) {
alert('Please enter a valid Druckkorrektur value');
return;
}
if (isNaN(lheZus) || lheZus < 0) {
alert('Please enter a valid L-He zus. value');
return;
}
// Calculate final values
calculateDerivedValues('add');
const korrigDruck = parseFloat($('#add-korrig-druck').val()) || 0;
const nm3 = parseFloat($('#add-nm3').val()) || 0;
const lhe = parseFloat($('#add-lhe').val()) || 0;
const lheGes = parseFloat($('#add-lhe-ges').val()) || 0;
// Prepare the form data
let formData = {
'client_id': $('#add-client-id').val(),
'client_id': clientId,
'date': dateInput,
'pressure': pressure,
'purity': purity,
'notes': $('#add-notes').val(),
'druckkorrektur': druckkorrektur,
'lhe_zus': lheZus,
'constant_300': gesFlaschInhalt,
'korrig_druck': korrigDruck,
'nm3': nm3,
'lhe': lhe,
'lhe_ges': lheGes,
'csrfmiddlewaretoken': '{{ csrf_token }}'
};
@@ -304,11 +633,18 @@
<tr data-id="${response.id}">
<td>${$('#table-one tbody tr').length + 1}</td>
<td>${response.id}</td>
<td>${response.institute_name || ''}</td>
<td>${response.client_name}</td>
<td>${response.pressure}</td>
<td>${response.purity}</td>
<td>${response.druckkorrektur}</td>
<td>${response.constant_300}</td>
<td>${response.korrig_druck}</td>
<td>${response.nm3}</td>
<td>${response.lhe}</td>
<td>${response.lhe_zus}</td>
<td>${response.lhe_ges}</td>
<td>${response.date || ''}</td>
<td>${response.notes || ''}</td>
<td class="actions">
<button class="edit-btn-one">Edit</button>
<button class="delete-btn-one">Delete</button>
@@ -328,32 +664,120 @@
});
// Edit
$(document).on('click', '.edit-btn-one', function() {
$(document).on('click', '.edit-btn-one', function() {
let row = $(this).closest('tr');
$('#edit-id').val(row.data('id'));
$('#edit-client-id').val(row.find('td:eq(2)').text().trim());
const entryId = row.data('id');
const clientName = row.find('td:eq(2)').text().trim();
// Reset edit form first
$('#edit-institute-id').val('');
$('#edit-client-id').html(allEditClientOptions);
$('#edit-client-id').prop('disabled', true);
// Find the client and set the institute
const clientOptions = $('#edit-client-id option');
let foundInstituteId = '';
let foundClientId = '';
clientOptions.each(function() {
if ($(this).text() === clientName) {
foundInstituteId = $(this).data('institute');
foundClientId = $(this).val();
return false; // break the loop
}
});
if (foundInstituteId) {
$('#edit-institute-id').val(foundInstituteId);
filterClients(foundInstituteId, $('#edit-client-id'), allEditClientOptions);
$('#edit-client-id').val(foundClientId);
}
// Set other fields
$('#edit-id').val(entryId);
// Handle date - ensure it's in correct format
let dateText = row.find('td:eq(5)').text().trim();
let dateText = row.find('td:eq(13)').text().trim();
if (dateText) {
$('#edit-date').val(dateText);
}
$('#edit-pressure').val(row.find('td:eq(3)').text().trim());
$('#edit-purity').val(row.find('td:eq(4)').text().trim());
$('#edit-notes').val(row.find('td:eq(6)').text().trim());
$('#edit-pressure').val(row.find('td:eq(4)').text().trim());
$('#edit-purity').val(row.find('td:eq(5)').text().trim());
$('#edit-druckkorrektur').val(row.find('td:eq(6)').text().trim());
$('#edit-lhe-zus').val(row.find('td:eq(11)').text().trim());
$('#edit-constant-300').val(row.find('td:eq(7)').text().trim());
$('#edit-korrig-druck').val(row.find('td:eq(8)').text().trim());
$('#edit-nm3').val(row.find('td:eq(9)').text().trim());
$('#edit-lhe').val(row.find('td:eq(10)').text().trim());
$('#edit-lhe-ges').val(row.find('td:eq(12)').text().trim());
$('#edit-popup-one').fadeIn();
});
// Update the save-edit-one handler
$('#save-edit-one').on('click', function() {
const clientId = $('#edit-client-id').val();
const instituteId = $('#edit-institute-id').val();
if (!instituteId) {
alert('Please select an institute');
return;
}
if (!clientId) {
alert('Please select a client');
return;
}
// Validate numbers
let pressure = parseFloat($('#edit-pressure').val());
let purity = parseFloat($('#edit-purity').val());
let druckkorrektur = parseFloat($('#edit-druckkorrektur').val()) || 1.0;
let lheZus = parseFloat($('#edit-lhe-zus').val()) || 0;
let gesFlaschInhalt = parseFloat($('#edit-constant-300').val()) || 300.0;
if (isNaN(pressure) || pressure < 0) {
alert('Please enter a valid pressure value');
return;
}
if (isNaN(purity) || purity < 0 || purity > 100) {
alert('Please enter a valid purity value (0-100)');
return;
}
if (isNaN(druckkorrektur) || druckkorrektur < 0) {
alert('Please enter a valid Druckkorrektur value');
return;
}
if (isNaN(lheZus) || lheZus < 0) {
alert('Please enter a valid L-He zus. value');
return;
}
// Calculate final values
calculateDerivedValues('edit');
const korrigDruck = parseFloat($('#edit-korrig-druck').val()) || 0;
const nm3 = parseFloat($('#edit-nm3').val()) || 0;
const lhe = parseFloat($('#edit-lhe').val()) || 0;
const lheGes = parseFloat($('#edit-lhe-ges').val()) || 0;
let formData = {
'id': $('#edit-id').val(),
'client_id': $('#edit-client-id').val(),
'date': $('#edit-date').val(), // Already in YYYY-MM-DD format
'pressure': $('#edit-pressure').val(),
'purity': $('#edit-purity').val(),
'notes': $('#edit-notes').val(),
'client_id': clientId,
'date': $('#edit-date').val(),
'pressure': pressure,
'purity': purity,
'druckkorrektur': druckkorrektur,
'lhe_zus': lheZus,
'constant_300': gesFlaschInhalt,
'korrig_druck': korrigDruck,
'nm3': nm3,
'lhe': lhe,
'lhe_ges': lheGes,
'csrfmiddlewaretoken': '{{ csrf_token }}'
};
@@ -362,14 +786,6 @@
alert('Please select a date');
return;
}
if (isNaN(formData.pressure) || formData.pressure < 0) {
alert('Please enter a valid pressure value');
return;
}
if (isNaN(formData.purity) || formData.purity < 0 || formData.purity > 100) {
alert('Please enter a valid purity value (0-100)');
return;
}
$.ajax({
url: '/update-entry/ExcelEntry/',
@@ -379,10 +795,16 @@
if (response.status === 'success') {
let row = $(`tr[data-id="${response.id}"]`);
row.find('td:eq(2)').text(response.client_name);
row.find('td:eq(3)').text(response.pressure);
row.find('td:eq(4)').text(response.purity);
row.find('td:eq(5)').text(response.date || '');
row.find('td:eq(6)').text(response.notes || '');
row.find('td:eq(4)').text(response.pressure);
row.find('td:eq(5)').text(response.purity);
row.find('td:eq(6)').text(response.druckkorrektur);
row.find('td:eq(7)').text(response.constant_300);
row.find('td:eq(8)').text(response.korrig_druck);
row.find('td:eq(9)').text(response.nm3);
row.find('td:eq(10)').text(response.lhe);
row.find('td:eq(11)').text(response.lhe_zus);
row.find('td:eq(12)').text(response.lhe_ges);
row.find('td:eq(13)').text(response.date || '');
$('#edit-popup-one').fadeOut();
} else {
alert('Error: ' + (response.message || 'Failed to update entry'));
@@ -424,4 +846,4 @@
</script>
</body>
</html>
</html>

View File

@@ -168,6 +168,21 @@
flex: 1;
margin-bottom: 0;
}
.number-input-container {
display: flex;
align-items: center;
margin-bottom: 15px;
}
.number-input-container label {
width: 120px;
margin-bottom: 0;
margin-right: 10px;
font-weight: bold;
}
.number-input-container input {
width: 80px;
margin-bottom: 0;
}
</style>
</head>
<body>
@@ -184,126 +199,245 @@
<div class="table-container">
<button class="add-row-btn" id="add-row-two">Add Output</button>
<table id="table-two">
<thead>
<tr>
<th>#</th>
<th>ID</th>
<th>Client</th>
<th>Date</th>
<th>Warm</th>
<th>LHe Delivery</th>
<th>LHe Output</th>
<th>Notes</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for entry in entries_table2 %}
<tr data-id="{{ entry.id }}">
<td>{{ forloop.counter }}</td>
<td>{{ entry.id }}</td>
<td>{{ entry.client.name }}</td>
<td>{{ entry.date }}</td>
<td>{{ entry.is_warm|yesno:"Yes,No" }}</td>
<td>{{ entry.lhe_delivery }}</td>
<td>{{ entry.lhe_output }}</td>
<td>{{ entry.notes }}</td>
<td class="actions">
<button class="edit-btn-two">Edit</button>
<button class="delete-btn-two">Delete</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<thead>
<tr>
<th>#</th>
<th>ID</th>
<th>Institute</th>
<th>Client</th>
<th>Date</th>
<th>Warm</th>
<th>LHe Delivery</th>
<th>LHe Output</th>
<th>Notes</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for entry in entries_table2 %}
<tr data-id="{{ entry.id }}">
<td>{{ forloop.counter }}</td>
<td>{{ entry.id }}</td>
<td>{{ entry.client.institute.name }}</td>
<td>{{ entry.client.name }}</td>
<td>{{ entry.date }}</td>
<td>{{ entry.is_warm|yesno:"Yes,No" }}</td>
<td>{{ entry.lhe_delivery }}</td>
<td>{{ entry.lhe_output }}</td>
<td>{{ entry.notes }}</td>
<td class="actions">
<button class="edit-btn-two">Edit</button>
<button class="delete-btn-two">Delete</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Add Entry Popup -->
<div id="add-popup-two" class="popup">
<span class="close-btn">&times;</span>
<h3>LHe Dewar Output</h3>
<label for="add-client-id">Client:</label>
<select id="add-client-id">
{% for client in clients %}
<option value="{{ client.id }}">{{ client.name }}</option>
{% endfor %}
</select>
<label for="add-date">Date:</label>
<input type="date" id="add-date">
<div class="checkbox-container">
<input type="checkbox" id="add-is-warm">
<label for="add-is-warm">Warm</label>
</div>
<div class="input-with-label">
<label for="add-lhe-delivery">LHe Anlieferung:</label>
<input type="text" id="add-lhe-delivery" placeholder="Enter delivery amount">
</div>
<div class="input-with-label">
<label for="add-lhe-output">LHe Ausgabe:</label>
<input type="number" id="add-lhe-output" placeholder="Enter output amount (numbers only)" step="0.01" min="0" placeholder="Enter output amount">
</div>
<label for="add-notes">Notes:</label>
<textarea id="add-notes" placeholder="Additional notes"></textarea>
<div class="popup-buttons">
<button class="save-btn" id="save-add-two">Save</button>
<button class="cancel-btn" id="cancel-add-two">Cancel</button>
<button class="help-btn">Help</button>
</div>
<span class="close-btn">&times;</span>
<h3>LHe Dewar Output</h3>
<!-- Institute Selection -->
<label for="add-institute-id">Institute:</label>
<select id="add-institute-id">
<option value="">Select Institute</option>
{% for institute in institutes %}
<option value="{{ institute.id }}">{{ institute.name }}</option>
{% endfor %}
</select>
<!-- Client Selection (will be populated based on institute) -->
<label for="add-client-id">Client:</label>
<select id="add-client-id" disabled>
<option value="">Select Institute first</option>
{% for client in clients %}
<option value="{{ client.id }}" data-institute="{{ client.institute.id }}">{{ client.name }}</option>
{% endfor %}
</select>
<label for="add-date">Date:</label>
<input type="date" id="add-date">
<!-- Changed from checkbox to number input -->
<div class="number-input-container">
<label for="add-is-warm">Warm:</label>
<input type="number" id="add-is-warm" min="0" max="1" step="1" value="0">
</div>
<div class="input-with-label">
<label for="add-lhe-delivery">LHe Anlieferung:</label>
<input type="text" id="add-lhe-delivery" placeholder="Enter delivery amount">
</div>
<div class="input-with-label">
<label for="add-lhe-output">LHe Ausgabe:</label>
<input type="number" id="add-lhe-output" placeholder="Enter output amount (numbers only)" step="0.01" min="0">
</div>
<label for="add-notes">Notes:</label>
<textarea id="add-notes" placeholder="Additional notes"></textarea>
<div class="popup-buttons">
<button class="save-btn" id="save-add-two">Save</button>
<button class="cancel-btn" id="cancel-add-two">Cancel</button>
<button class="help-btn">Help</button>
</div>
</div>
<!-- Edit Entry Popup -->
<div id="edit-popup-two" class="popup">
<span class="close-btn">&times;</span>
<h3>LHe Dewar Output</h3>
<input type="hidden" id="edit-id">
<label for="edit-client-id">Client:</label>
<select id="edit-client-id">
{% for client in clients %}
<option value="{{ client.id }}">{{ client.name }}</option>
{% endfor %}
</select>
<label for="edit-date">Date:</label>
<input type="date" id="edit-date">
<div class="checkbox-container">
<input type="checkbox" id="edit-is-warm">
<label for="edit-is-warm">Warm</label>
</div>
<div class="input-with-label">
<label for="edit-lhe-delivery">LHe Anlieferung:</label>
<input type="text" id="edit-lhe-delivery" placeholder="Enter delivery amount">
</div>
<div class="input-with-label">
<label for="edit-lhe-output">LHe Ausgabe:</label>
<input type="number" id="edit-lhe-output" placeholder="Enter output amount">
</div>
<label for="edit-notes">Notes:</label>
<textarea id="edit-notes" placeholder="Additional notes"></textarea>
<div class="popup-buttons">
<button class="save-btn" id="save-edit-two">Save</button>
<button class="cancel-btn" id="cancel-edit-two">Cancel</button>
<button class="help-btn">Help</button>
</div>
<span class="close-btn">&times;</span>
<h3>LHe Dewar Output</h3>
<input type="hidden" id="edit-id">
<!-- Institute Selection -->
<label for="edit-institute-id">Institute:</label>
<select id="edit-institute-id">
<option value="">Select Institute</option>
{% for institute in institutes %}
<option value="{{ institute.id }}">{{ institute.name }}</option>
{% endfor %}
</select>
<!-- Client Selection (will be populated based on institute) -->
<label for="edit-client-id">Client:</label>
<select id="edit-client-id" disabled>
<option value="">Select Institute first</option>
{% for client in clients %}
<option value="{{ client.id }}" data-institute="{{ client.institute.id }}">{{ client.name }}</option>
{% endfor %}
</select>
<label for="edit-date">Date:</label>
<input type="date" id="edit-date">
<!-- Changed from checkbox to number input -->
<div class="number-input-container">
<label for="edit-is-warm">Warm:</label>
<input type="number" id="edit-is-warm" min="0" max="1" step="1" value="0">
</div>
<div class="input-with-label">
<label for="edit-lhe-delivery">LHe Anlieferung:</label>
<input type="text" id="edit-lhe-delivery" placeholder="Enter delivery amount">
</div>
<div class="input-with-label">
<label for="edit-lhe-output">LHe Ausgabe:</label>
<input type="number" id="edit-lhe-output" placeholder="Enter output amount">
</div>
<label for="edit-notes">Notes:</label>
<textarea id="edit-notes" placeholder="Additional notes"></textarea>
<div class="popup-buttons">
<button class="save-btn" id="save-edit-two">Save</button>
<button class="cancel-btn" id="cancel-edit-two">Cancel</button>
<button class="help-btn">Help</button>
</div>
</div>
<script>
$(document).ready(function () {
let currentTableId = null;
let currentModelName = null;
// Store all client options for both dropdowns
const allClientOptions = $('#add-client-id').html();
const allEditClientOptions = $('#edit-client-id').html();
// Function to filter clients based on institute selection
function filterClients(instituteId, targetSelect, allOptions) {
if (!instituteId) {
// Show only the default option if no institute selected
targetSelect.html('<option value="">Select Institute first</option>');
targetSelect.prop('disabled', true);
} else {
// Restore all options first
targetSelect.html(allOptions);
// Enable the dropdown
targetSelect.prop('disabled', false);
// Hide all options first
targetSelect.find('option').hide();
// Always show the "Select Client" option
targetSelect.find('option[value=""]').show().text('Select Client');
// Show only clients from selected institute
const clientsFromInstitute = targetSelect.find(`option[data-institute="${instituteId}"]`);
if (clientsFromInstitute.length > 0) {
clientsFromInstitute.show();
} else {
targetSelect.html('<option value="">No clients found for this institute</option>');
}
// Reset selection
targetSelect.val('');
}
}
// Function to handle warm field change and control LHe Anlieferung field
function handleWarmFieldChange(warmField, deliveryField) {
const warmValue = parseInt(warmField.val());
// Ensure value is only 0 or 1
if (warmValue !== 0 && warmValue !== 1) {
warmField.val(0);
}
// If warm is 1, set delivery to 0 and disable it
if (parseInt(warmField.val()) === 1) {
deliveryField.val('0');
deliveryField.prop('disabled', true);
deliveryField.prop('readonly', true);
} else {
deliveryField.prop('disabled', false);
deliveryField.prop('readonly', false);
}
}
// Initialize warm field handlers for add popup
$('#add-is-warm').on('change input', function() {
handleWarmFieldChange($(this), $('#add-lhe-delivery'));
});
// Initialize warm field handlers for edit popup
$('#edit-is-warm').on('change input', function() {
handleWarmFieldChange($(this), $('#edit-lhe-delivery'));
});
// Institute change handler for add popup
$('#add-institute-id').on('change', function() {
const instituteId = $(this).val();
filterClients(instituteId, $('#add-client-id'), allClientOptions);
});
// Institute change handler for edit popup
$('#edit-institute-id').on('change', function() {
const instituteId = $(this).val();
filterClients(instituteId, $('#edit-client-id'), allEditClientOptions);
});
// Open Add Popup for Table 2
$('#add-row-two').on('click', function () {
currentTableId = 'table-two';
currentModelName = 'SecondTableEntry';
// Reset form
$('#add-institute-id').val('');
$('#add-client-id').html('<option value="">Select Institute first</option>');
$('#add-client-id').prop('disabled', true);
$('#add-date').val('');
$('#add-is-warm').val('0');
$('#add-lhe-delivery').val('');
$('#add-lhe-delivery').prop('disabled', false);
$('#add-lhe-delivery').prop('readonly', false);
$('#add-lhe-output').val('');
$('#add-notes').val('');
// Apply initial warm field logic
handleWarmFieldChange($('#add-is-warm'), $('#add-lhe-delivery'));
$('#add-popup-two').fadeIn();
});
@@ -314,10 +448,30 @@
// Save Add Entry
$('#save-add-two').on('click', function() {
const clientId = $('#add-client-id').val();
const instituteId = $('#add-institute-id').val();
if (!instituteId) {
alert('Please select an institute');
return;
}
if (!clientId) {
alert('Please select a client');
return;
}
// Validate warm field
const warmValue = parseInt($('#add-is-warm').val());
if (warmValue !== 0 && warmValue !== 1) {
alert('Warm field must be 0 or 1');
return;
}
let formData = {
'client_id': $('#add-client-id').val(),
'date': $('#add-date').val(), // Ensure this is in YYYY-MM-DD format
'is_warm': $('#add-is-warm').is(':checked'),
'client_id': clientId,
'date': $('#add-date').val(),
'is_warm': warmValue,
'lhe_delivery': $('#add-lhe-delivery').val(),
'lhe_output': $('#add-lhe-output').val(),
'notes': $('#add-notes').val(),
@@ -331,7 +485,7 @@
}
// Validate LHe Output is a number
if (isNaN(parseFloat(formData.lhe_output))) {
if (formData.lhe_output && isNaN(parseFloat(formData.lhe_output))) {
alert('LHe Output must be a valid number');
return;
}
@@ -347,6 +501,7 @@
<tr data-id="${response.id}">
<td>${$('#table-two tbody tr').length + 1}</td>
<td>${response.id}</td>
<td>${response.institute_name || ''}</td>
<td>${response.client_name}</td>
<td>${response.date || ''}</td>
<td>${response.is_warm ? 'Yes' : 'No'}</td>
@@ -371,53 +526,81 @@
});
});
// Add this new function to load table data
function loadTableData() {
$.ajax({
url: window.location.href,
method: 'GET',
success: function(data) {
// Parse the HTML response to extract the table body
let newBody = $(data).find('#table-two tbody').html();
$('#table-two tbody').html(newBody);
},
error: function() {
alert('Failed to refresh table data');
}
});
}
// Open Edit Popup
$(document).on('click', '.edit-btn-two', function() {
let row = $(this).closest('tr');
$('#edit-id').val(row.data('id'));
const entryId = row.data('id');
const clientName = row.find('td:eq(2)').text().trim();
// Set client - find by name since we're showing names in the table
let clientName = row.find('td:eq(2)').text().trim();
$(`#edit-client-id option:contains("${clientName}")`).prop('selected', true);
// Reset edit form first
$('#edit-institute-id').val('');
$('#edit-client-id').html(allEditClientOptions);
$('#edit-client-id').prop('disabled', true);
// Set date - ensure proper format
let dateText = row.find('td:eq(3)').text().trim();
if (dateText) {
$('#edit-date').val(dateText);
// Find the client and set the institute
const clientOptions = $('#edit-client-id option');
let foundInstituteId = '';
let foundClientId = '';
clientOptions.each(function() {
if ($(this).text() === clientName) {
foundInstituteId = $(this).data('institute');
foundClientId = $(this).val();
return false; // break the loop
}
});
if (foundInstituteId) {
$('#edit-institute-id').val(foundInstituteId);
filterClients(foundInstituteId, $('#edit-client-id'), allEditClientOptions);
$('#edit-client-id').val(foundClientId);
}
// Set other fields
$('#edit-is-warm').prop('checked', row.find('td:eq(4)').text().trim() === 'Yes');
$('#edit-id').val(entryId);
$('#edit-date').val(row.find('td:eq(3)').text().trim());
// Set warm value (convert from "Yes"/"No" to 1/0)
const warmValue = row.find('td:eq(4)').text().trim() === 'Yes' ? 1 : 0;
$('#edit-is-warm').val(warmValue);
$('#edit-lhe-delivery').val(row.find('td:eq(5)').text().trim());
$('#edit-lhe-output').val(row.find('td:eq(6)').text().trim());
$('#edit-notes').val(row.find('td:eq(7)').text().trim());
// Apply warm field logic
handleWarmFieldChange($('#edit-is-warm'), $('#edit-lhe-delivery'));
$('#edit-popup-two').fadeIn();
});
// Save Edit Entry
$('#save-edit-two').on('click', function() {
const clientId = $('#edit-client-id').val();
const instituteId = $('#edit-institute-id').val();
if (!instituteId) {
alert('Please select an institute');
return;
}
if (!clientId) {
alert('Please select a client');
return;
}
// Validate warm field
const warmValue = parseInt($('#edit-is-warm').val());
if (warmValue !== 0 && warmValue !== 1) {
alert('Warm field must be 0 or 1');
return;
}
let formData = {
'id': $('#edit-id').val(),
'client_id': $('#edit-client-id').val(),
'date': $('#edit-date').val(), // Already in YYYY-MM-DD format
'is_warm': $('#edit-is-warm').is(':checked'),
'client_id': clientId,
'date': $('#edit-date').val(),
'is_warm': warmValue,
'lhe_delivery': $('#edit-lhe-delivery').val(),
'lhe_output': $('#edit-lhe-output').val(),
'notes': $('#edit-notes').val(),
@@ -429,7 +612,7 @@
alert('Please select a date');
return;
}
if (isNaN(parseFloat(formData.lhe_output))) {
if (formData.lhe_output && isNaN(parseFloat(formData.lhe_output))) {
alert('Please enter a valid LHe Output value');
return;
}
@@ -462,13 +645,11 @@
$(document).on('click', '.delete-btn-two', function () {
let row = $(this).closest('tr');
let id = row.data('id');
currentTableId = row.closest('table').attr('id');
currentModelName = 'SecondTableEntry';
if (!confirm('Are you sure you want to delete this entry?')) return;
$.ajax({
url: `/delete-entry/${currentModelName}/`,
url: '/delete-entry/SecondTableEntry/',
method: 'POST',
data: {
'id': id,

View File

@@ -11,4 +11,5 @@ urlpatterns = [
path('betriebskosten/', views.betriebskosten_list, name='betriebskosten_list'),
path('betriebskosten/create/', views.betriebskosten_create, name='betriebskosten_create'),
path('betriebskosten/delete/', views.betriebskosten_delete, name='betriebskosten_delete'),
]

View File

@@ -6,7 +6,7 @@ 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 .models import Client, SecondTableEntry, Institute
from django.db.models import Sum
from django.urls import reverse
from django.db.models.functions import Coalesce
@@ -14,11 +14,7 @@ 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):
@@ -68,10 +64,13 @@ def clients_list(request):
def table_one_view(request):
ExcelEntry = apps.get_model('sheets', 'ExcelEntry')
entries_table1 = ExcelEntry.objects.all().select_related('client')
clients = Client.objects.all()
clients = Client.objects.all().select_related('institute') # Add select_related
institutes = Institute.objects.all() # Add institutes
return render(request, 'table_one.html', {
'entries_table1': entries_table1,
'clients': clients,
'institutes': institutes, # Add institutes to context
})
@@ -80,20 +79,22 @@ def table_two_view(request):
try:
SecondTableEntry = apps.get_model('sheets', 'SecondTableEntry')
entries = SecondTableEntry.objects.all().order_by('-date')
clients = Client.objects.all()
clients = Client.objects.all().select_related('institute') # Add select_related
institutes = Institute.objects.all()
return render(request, 'table_two.html', {
'entries_table2': entries,
'clients': clients,
'institutes': institutes,
})
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()
})
'clients': Client.objects.all().select_related('institute'),
'institutes': Institute.objects.all()
})
# Add Entry (Generic)
@@ -128,6 +129,7 @@ def add_entry(request, model_name):
'status': 'success',
'id': entry.id,
'client_name': entry.client.name,
'institute_name': entry.client.institute.name, # Add this line
'date': entry.date.strftime('%Y-%m-%d') if entry.date else '',
'is_warm': entry.is_warm,
'lhe_delivery': entry.lhe_delivery,
@@ -157,6 +159,7 @@ def add_entry(request, model_name):
'status': 'success',
'id': entry.id,
'client_name': entry.client.name,
'institute_name': entry.client.institute.name, # Add this line
'pressure': str(entry.pressure),
'purity': str(entry.purity),
'notes': entry.notes
@@ -219,6 +222,7 @@ def update_entry(request, model_name):
'status': 'success',
'id': entry.id,
'client_name': entry.client.name,
'institute_name': entry.client.institute.name, # Add this line
'date': entry.date.strftime('%Y-%m-%d') if entry.date else '',
'is_warm': entry.is_warm,
'lhe_delivery': entry.lhe_delivery,
@@ -243,6 +247,7 @@ def update_entry(request, model_name):
'status': 'success',
'id': entry.id,
'client_name': entry.client.name,
'institute_name': entry.client.institute.name, # Add this line
'date': entry.date.strftime('%Y-%m-%d') if entry.date else '',
'pressure': str(entry.pressure),
'purity': str(entry.purity),