edit Modal changes to accomidate the library Modul
This commit is contained in:
+14
-5
@@ -6601,17 +6601,26 @@ def edit_item(id):
|
|||||||
if ort and ort not in predefined_locations:
|
if ort and ort not in predefined_locations:
|
||||||
it.add_predefined_location(ort)
|
it.add_predefined_location(ort)
|
||||||
|
|
||||||
# Update the item
|
|
||||||
result = it.update_item(
|
result = it.update_item(
|
||||||
id, name, ort, beschreibung,
|
id=id,
|
||||||
images, verfuegbar, filter1, filter2, filter3,
|
name=name,
|
||||||
anschaffungs_jahr, anschaffungs_kosten, code_4, reservierbar,
|
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,
|
isbn=item_isbn,
|
||||||
item_type=item_type
|
item_type=item_type
|
||||||
)
|
)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
flash('Element erfolgreich aktualisiert', 'success')
|
flash('Element erfolgreich aktualisiert (und ggf. Gruppe synchronisiert)', 'success')
|
||||||
else:
|
else:
|
||||||
flash('Fehler beim Aktualisieren des Elements', 'error')
|
flash('Fehler beim Aktualisieren des Elements', 'error')
|
||||||
|
|
||||||
|
|||||||
@@ -198,70 +198,61 @@ def get_group_item_ids(id):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def update_item(id, name, ort, beschreibung, images=None, verfuegbar=True,
|
def update_item(id, name, ort, beschreibung, images, verfuegbar, filter1, filter2, filter3,
|
||||||
filter=None, filter2=None, filter3=None, ansch_jahr=None, ansch_kost=None, code_4=None, reservierbar=True,
|
ansch_jahr, ansch_kost, code_4, reservierbar, isbn=None, item_type='general'):
|
||||||
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
|
|
||||||
"""
|
|
||||||
try:
|
try:
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = client[cfg.MONGODB_DB]
|
||||||
items = db['items']
|
items = db['items']
|
||||||
|
|
||||||
# Set default values for optional parameters
|
# 1. Altes Item laden, um SeriesGroupId zu bestimmen
|
||||||
if images is None:
|
old_item = items.find_one({'_id': ObjectId(id)})
|
||||||
images = []
|
if not old_item:
|
||||||
|
return False
|
||||||
|
|
||||||
|
series_group_id = old_item.get('SeriesGroupId')
|
||||||
|
|
||||||
update_data = {
|
# 2. Shared Data: Daten, die für ALLE in der Gruppe gleich sind
|
||||||
|
shared_update = {
|
||||||
'Name': name,
|
'Name': name,
|
||||||
'Ort': ort,
|
'Ort': ort,
|
||||||
'Beschreibung': beschreibung,
|
'Beschreibung': beschreibung,
|
||||||
'Images': images,
|
'Images': images,
|
||||||
'Verfuegbar': verfuegbar,
|
'Filter': filter1,
|
||||||
'Reservierbar': reservierbar,
|
|
||||||
'Filter': filter,
|
|
||||||
'Filter2': filter2,
|
'Filter2': filter2,
|
||||||
'Filter3': filter3,
|
'Filter3': filter3,
|
||||||
'Anschaffungsjahr': ansch_jahr,
|
'Anschaffungsjahr': ansch_jahr,
|
||||||
'Anschaffungskosten': ansch_kost,
|
'Anschaffungskosten': ansch_kost,
|
||||||
'Code_4': code_4,
|
'Reservierbar': reservierbar,
|
||||||
'ISBN': isbn,
|
'ISBN': isbn,
|
||||||
'library_category': library_category,
|
|
||||||
'ItemType': item_type,
|
'ItemType': item_type,
|
||||||
|
'Verfuegbar': verfuegbar, # Wir behalten den Status bei
|
||||||
'LastUpdated': datetime.datetime.now()
|
'LastUpdated': datetime.datetime.now()
|
||||||
}
|
}
|
||||||
|
|
||||||
result = items.update_one(
|
# 3. Spezifische Daten: Was NICHT synchronisiert wird
|
||||||
{'_id': ObjectId(id)},
|
specific_update = shared_update.copy()
|
||||||
{'$set': update_data}
|
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()
|
client.close()
|
||||||
return result.modified_count > 0
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error updating item: {e}")
|
print(f"Error updating item: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def update_item_status(id, verfuegbar, user=None):
|
def update_item_status(id, verfuegbar, user=None):
|
||||||
"""
|
"""
|
||||||
Update the availability status of an inventory item.
|
Update the availability status of an inventory item.
|
||||||
|
|||||||
@@ -1192,7 +1192,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Modal Control Functions (accessible globally from table buttons)
|
|
||||||
function openEditLibraryItem(itemId) {
|
function openEditLibraryItem(itemId) {
|
||||||
const item = libraryItems.find(i => i._id === itemId);
|
const item = libraryItems.find(i => i._id === itemId);
|
||||||
|
|
||||||
@@ -1201,7 +1200,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate the form fields - Using correct German properties from MongoDB fields
|
// Felder befüllen
|
||||||
document.getElementById('editLibraryItemId').value = item._id || '';
|
document.getElementById('editLibraryItemId').value = item._id || '';
|
||||||
document.getElementById('editLibraryName').value = item.Name || '';
|
document.getElementById('editLibraryName').value = item.Name || '';
|
||||||
document.getElementById('editLibraryType').value = item.ItemType || 'book';
|
document.getElementById('editLibraryType').value = item.ItemType || 'book';
|
||||||
@@ -1210,56 +1209,124 @@
|
|||||||
document.getElementById('editLibraryLocation').value = item.Ort || '';
|
document.getElementById('editLibraryLocation').value = item.Ort || '';
|
||||||
document.getElementById('editLibraryDescription').value = item.Beschreibung || '';
|
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';
|
document.getElementById('editLibraryModal').style.display = 'flex';
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeEditLibraryModal() {
|
function closeEditLibraryModal() {
|
||||||
document.getElementById('editLibraryModal').style.display = 'none';
|
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>
|
</script>
|
||||||
|
|
||||||
<div id="editLibraryModal" class="modal" style="display:none;">
|
<div id="editLibraryModal" class="modal" style="display:none;">
|
||||||
<div class="modal-content" style="max-width: 760px;">
|
<div class="modal-content" style="max-width: 760px;">
|
||||||
<span class="close" onclick="closeEditLibraryModal()">×</span>
|
<span class="close" onclick="closeEditLibraryModal()">×</span>
|
||||||
<h3 style="margin-top:0;">Bibliotheksmedium bearbeiten</h3>
|
<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">
|
<form id="editLibraryForm">
|
||||||
|
<!-- Formularfelder wie gehabt... -->
|
||||||
<input type="hidden" id="editLibraryItemId">
|
<input type="hidden" id="editLibraryItemId">
|
||||||
<div class="edit-grid">
|
<div class="edit-grid">
|
||||||
<div class="full">
|
<!-- ... (Dein restliches Formular) ... -->
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
|
<!-- ... -->
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user