edit Modal changes to accomidate the library Modul

This commit is contained in:
2026-06-28 16:30:41 +02:00
parent 6f424cc8aa
commit c57b4a9a44
3 changed files with 147 additions and 80 deletions
+14 -5
View File
@@ -6601,17 +6601,26 @@ def edit_item(id):
if ort and ort not in predefined_locations:
it.add_predefined_location(ort)
# Update the item
result = it.update_item(
id, name, ort, beschreibung,
images, verfuegbar, filter1, filter2, filter3,
anschaffungs_jahr, anschaffungs_kosten, code_4, reservierbar,
id=id,
name=name,
ort=ort,
beschreibung=beschreibung,
images=images,
verfuegbar=verfuegbar,
filter1=filter1,
filter2=filter2,
filter3=filter3,
ansch_jahr=anschaffungs_jahr,
ansch_kost=anschaffungs_kosten,
code_4=code_4,
reservierbar=reservierbar,
isbn=item_isbn,
item_type=item_type
)
if result:
flash('Element erfolgreich aktualisiert', 'success')
flash('Element erfolgreich aktualisiert (und ggf. Gruppe synchronisiert)', 'success')
else:
flash('Fehler beim Aktualisieren des Elements', 'error')
+29 -38
View File
@@ -198,70 +198,61 @@ def get_group_item_ids(id):
return []
def update_item(id, name, ort, beschreibung, images=None, verfuegbar=True,
filter=None, filter2=None, filter3=None, ansch_jahr=None, ansch_kost=None, code_4=None, reservierbar=True,
isbn=None, item_type='general', library_category=None):
"""
Update an existing inventory item.
Args:
id (str): ID of the item to update
name (str): Name of the item
ort (str): Location of the item
beschreibung (str): Description of the item
images (list, optional): List of image filenames for the item
verfuegbar (bool, optional): Availability status of the item
filter (str, optional): Primary filter/category for the item
filter2 (str, optional): Secondary filter/category for the item
filter3 (str, optional): Tertiary filter/category for the item
ansch_jahr (int, optional): Year of acquisition
ansch_kost (float, optional): Cost of acquisition
code_4 (str, optional): 4-digit identification code
reservierbar (bool, optional): Whether the item can be reserved in advance
library_category (str, optional): Library category for the item
Returns:
bool: True if successful, False otherwise
"""
def update_item(id, name, ort, beschreibung, images, verfuegbar, filter1, filter2, filter3,
ansch_jahr, ansch_kost, code_4, reservierbar, isbn=None, item_type='general'):
try:
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB]
items = db['items']
# Set default values for optional parameters
if images is None:
images = []
# 1. Altes Item laden, um SeriesGroupId zu bestimmen
old_item = items.find_one({'_id': ObjectId(id)})
if not old_item:
return False
update_data = {
series_group_id = old_item.get('SeriesGroupId')
# 2. Shared Data: Daten, die für ALLE in der Gruppe gleich sind
shared_update = {
'Name': name,
'Ort': ort,
'Beschreibung': beschreibung,
'Images': images,
'Verfuegbar': verfuegbar,
'Reservierbar': reservierbar,
'Filter': filter,
'Filter': filter1,
'Filter2': filter2,
'Filter3': filter3,
'Anschaffungsjahr': ansch_jahr,
'Anschaffungskosten': ansch_kost,
'Code_4': code_4,
'Reservierbar': reservierbar,
'ISBN': isbn,
'library_category': library_category,
'ItemType': item_type,
'Verfuegbar': verfuegbar, # Wir behalten den Status bei
'LastUpdated': datetime.datetime.now()
}
result = items.update_one(
{'_id': ObjectId(id)},
{'$set': update_data}
# 3. Spezifische Daten: Was NICHT synchronisiert wird
specific_update = shared_update.copy()
specific_update['Code_4'] = code_4
# 4. Das aktuelle Item updaten
items.update_one({'_id': ObjectId(id)}, {'$set': specific_update})
# 5. Alle anderen Gruppen-Mitglieder synchronisieren
if series_group_id:
items.update_many(
{
'SeriesGroupId': series_group_id,
'_id': {'$ne': ObjectId(id)}
},
{'$set': shared_update}
)
client.close()
return result.modified_count > 0
return True
except Exception as e:
print(f"Error updating item: {e}")
return False
def update_item_status(id, verfuegbar, user=None):
"""
Update the availability status of an inventory item.
+103 -36
View File
@@ -1192,7 +1192,6 @@
}
});
// Modal Control Functions (accessible globally from table buttons)
function openEditLibraryItem(itemId) {
const item = libraryItems.find(i => i._id === itemId);
@@ -1201,7 +1200,7 @@
return;
}
// Populate the form fields - Using correct German properties from MongoDB fields
// Felder befüllen
document.getElementById('editLibraryItemId').value = item._id || '';
document.getElementById('editLibraryName').value = item.Name || '';
document.getElementById('editLibraryType').value = item.ItemType || 'book';
@@ -1210,56 +1209,124 @@
document.getElementById('editLibraryLocation').value = item.Ort || '';
document.getElementById('editLibraryDescription').value = item.Beschreibung || '';
// Gruppen-Logik für die Anzeige der gesamten Range
const warningDiv = document.getElementById('editLibraryGroupWarning');
const codesContainer = document.getElementById('editLibraryAllCodes');
if (item.SeriesGroupId) {
// Alle Mitglieder der Gruppe finden (sortiert nach SeriesPosition)
const groupMembers = libraryItems
.filter(i => i.SeriesGroupId === item.SeriesGroupId)
.sort((a, b) => a.SeriesPosition - b.SeriesPosition);
// Codes für die Anzeige formatieren
const codesHtml = groupMembers.map(member => {
const isCurrent = member._id === itemId;
return `<span style="background: ${isCurrent ? '#0ea5e9' : '#e0e0e0'};
color: ${isCurrent ? '#fff' : '#333'};
padding: 2px 8px; border-radius: 4px; margin-right: 5px; font-size: 12px;">
${member.Code_4 || 'n/a'}
</span>`;
}).join('');
document.getElementById('editLibraryGroupCount').textContent = groupMembers.length;
codesContainer.innerHTML = codesHtml;
warningDiv.style.display = 'block';
} else {
warningDiv.style.display = 'none';
}
document.getElementById('editLibraryModal').style.display = 'flex';
}
function closeEditLibraryModal() {
document.getElementById('editLibraryModal').style.display = 'none';
}
document.getElementById('editLibraryForm').addEventListener('submit', async function(e) {
e.preventDefault();
const itemId = document.getElementById('editLibraryItemId').value;
// Daten sammeln
const updateData = {
id: itemId,
name: document.getElementById('editLibraryName').value,
item_type: document.getElementById('editLibraryType').value,
isbn: document.getElementById('editLibraryIsbn').value,
code_4: document.getElementById('editLibraryCode4').value,
ort: document.getElementById('editLibraryLocation').value,
beschreibung: document.getElementById('editLibraryDescription').value
};
// Fetch zum Backend
const response = await fetch('/api/update-item', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(updateData)
});
if (response.ok) {
// Lokale Synchronisierung im Array (für sofortiges UI-Update)
const editedItem = libraryItems.find(i => i._id === itemId);
if (editedItem && editedItem.SeriesGroupId) {
libraryItems.forEach(item => {
if (item.SeriesGroupId === editedItem.SeriesGroupId) {
// Alle Felder synchronisieren
item.Name = updateData.name;
item.ItemType = updateData.item_type;
item.ISBN = updateData.isbn;
item.Ort = updateData.ort;
item.Beschreibung = updateData.beschreibung;
// Code nur für das aktive Item setzen
if (item._id === itemId) {
item.Code_4 = updateData.code_4;
}
}
});
} else if (editedItem) {
// Einzel-Update
Object.assign(editedItem, updateData);
}
closeEditLibraryModal();
// Hier ggf. deine Render-Funktion aufrufen, um die Tabelle zu aktualisieren
renderLibraryTable();
}
});
</script>
<div id="editLibraryModal" class="modal" style="display:none;">
<div class="modal-content" style="max-width: 760px;">
<span class="close" onclick="closeEditLibraryModal()">&times;</span>
<h3 style="margin-top:0;">Bibliotheksmedium bearbeiten</h3>
<!-- Bereich für Gruppen-Informationen (Range) -->
<div id="editLibraryGroupWarning" style="display:none; background-color: #f8f9fa; padding: 15px; border-radius: 6px; margin-bottom: 20px; border: 1px solid #dee2e6;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<strong style="color: #0ea5e9;">Gruppen-Synchronisierung aktiv</strong>
<span style="font-size: 12px; color: #666;">Gesamt: <span id="editLibraryGroupCount"></span> Exemplare</span>
</div>
<p style="margin: 0 0 10px 0; font-size: 13px;">Verfügbare Codes in dieser Range:</p>
<div id="editLibraryAllCodes" style="display: flex; flex-wrap: wrap; gap: 5px;">
<!-- Codes werden hier per JS eingefügt -->
</div>
<p style="margin-top: 15px; font-size: 12px; color: #555; border-top: 1px solid #eee; pt: 10px;">
<em>Änderungen an allgemeinen Daten (Titel, Ort, etc.) betreffen <strong>alle</strong> oben aufgeführten Codes.</em>
</p>
</div>
<form id="editLibraryForm">
<!-- Formularfelder wie gehabt... -->
<input type="hidden" id="editLibraryItemId">
<div class="edit-grid">
<div class="full">
<label for="editLibraryName">Titel</label>
<input id="editLibraryName" required>
</div>
<div>
<label for="editLibraryType">Medientyp</label>
<select id="editLibraryType">
<option value="book">Buch</option>
<option value="schulbuch">Schulbuch</option>
<option value="cd">CD</option>
<option value="dvd">DVD</option>
<option value="media">Sonstige Medien</option>
</select>
</div>
<div>
<label for="editLibraryIsbn">ISBN</label>
<input id="editLibraryIsbn" placeholder="optional ISBN-10/13">
</div>
<div>
<label for="editLibraryCode4">Code</label>
<input id="editLibraryCode4" placeholder="optional Mediencode">
</div>
<div class="full">
<label for="editLibraryLocation">Ort</label>
<input id="editLibraryLocation" required>
</div>
<div class="full">
<label for="editLibraryDescription">Beschreibung</label>
<textarea id="editLibraryDescription" rows="4" required></textarea>
</div>
</div>
<div class="edit-actions">
<button type="submit" class="button" style="background:#0ea5e9;color:#fff;">Speichern</button>
<button type="button" class="button" onclick="closeEditLibraryModal()">Abbrechen</button>
<!-- ... (Dein restliches Formular) ... -->
</div>
<!-- ... -->
</form>
</div>
</div>