changes to the encryption to the users and Items

This commit is contained in:
2026-07-31 19:55:59 +02:00
parent 9b12d9a3d0
commit 258e287a39
2 changed files with 1056 additions and 1108 deletions
File diff suppressed because it is too large Load Diff
+359 -55
View File
@@ -102,12 +102,37 @@ def add_item(name, ort, beschreibung, images=None, filter=None, filter2=None, fi
isbn=None, item_type='general', library_category=None, is_library=False): isbn=None, item_type='general', library_category=None, is_library=False):
""" """
Add a new item to the inventory. Add a new item to the inventory.
Args:
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
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
series_group_id (str, optional): Shared group id for same-type batch items
series_count (int, optional): Total items in the created batch
series_position (int, optional): Position inside the batch (1-based)
is_grouped_sub_item (bool, optional): Whether this item is hidden as sub-item
parent_item_id (str, optional): Parent item id if this is a sub-item
isbn (str, optional): ISBN for books or media items
item_type (str, optional): Type of the item (e.g., 'general', 'book', 'cd')
library_category (str, optional): Library category for the item
Returns:
ObjectId: ID of the new item or None if failed
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: 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
if images is None: if images is None:
images = [] images = []
@@ -137,7 +162,10 @@ def add_item(name, ort, beschreibung, images=None, filter=None, filter2=None, fi
'LastUpdated': datetime.datetime.now() 'LastUpdated': datetime.datetime.now()
} }
result = items.insert_one(item) result = items.insert_one(item)
return result.inserted_id item_id = result.inserted_id
client.close()
return item_id
except Exception as e: except Exception as e:
print(f"Error adding item: {e}") print(f"Error adding item: {e}")
return None return None
@@ -146,9 +174,15 @@ def add_item(name, ort, beschreibung, images=None, filter=None, filter2=None, fi
def remove_item(id): def remove_item(id):
""" """
Soft-delete an item from the inventory. Soft-delete an item from the inventory.
Args:
id (str): ID of the item to remove
Returns:
bool: True if successful, False otherwise
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
result = items.update_one( result = items.update_one(
@@ -160,6 +194,7 @@ def remove_item(id):
'Verfuegbar': False, 'Verfuegbar': False,
}} }}
) )
client.close()
return result.modified_count > 0 return result.modified_count > 0
except Exception as e: except Exception as e:
print(f"Error removing item: {e}") print(f"Error removing item: {e}")
@@ -169,19 +204,29 @@ def remove_item(id):
def get_group_item_ids(id): def get_group_item_ids(id):
""" """
Resolve all item ids that belong to the same grouped series as the given item. Resolve all item ids that belong to the same grouped series as the given item.
For non-grouped items, this returns only the provided id.
Args:
id (str): ID of any item in the group
Returns:
list[str]: All related item IDs (including the parent item)
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
base_item = items.find_one(_active_record_query({'_id': ObjectId(id)})) base_item = items.find_one(_active_record_query({'_id': ObjectId(id)}))
if not base_item: if not base_item:
client.close()
return [] return []
resolved_ids = set() resolved_ids = set()
series_group_id = base_item.get('SeriesGroupId')
# Prefer SeriesGroupId because it represents the full logical group.
series_group_id = base_item.get('SeriesGroupId')
if series_group_id: if series_group_id:
for group_item in items.find(_active_record_query({'SeriesGroupId': series_group_id}), {'_id': 1}): for group_item in items.find(_active_record_query({'SeriesGroupId': series_group_id}), {'_id': 1}):
resolved_ids.add(str(group_item['_id'])) resolved_ids.add(str(group_item['_id']))
@@ -197,6 +242,7 @@ def get_group_item_ids(id):
for child in items.find(_active_record_query({'ParentItemId': str(base_item['_id']), 'IsGroupedSubItem': True}), {'_id': 1}): for child in items.find(_active_record_query({'ParentItemId': str(base_item['_id']), 'IsGroupedSubItem': True}), {'_id': 1}):
resolved_ids.add(str(child['_id'])) resolved_ids.add(str(child['_id']))
client.close()
return list(resolved_ids) return list(resolved_ids)
except Exception as e: except Exception as e:
print(f"Error resolving group item IDs: {e}") print(f"Error resolving group item IDs: {e}")
@@ -206,7 +252,7 @@ def get_group_item_ids(id):
def update_item(id, name, ort, beschreibung, images, verfuegbar, filter1, filter2, filter3, def update_item(id, name, ort, beschreibung, images, verfuegbar, filter1, filter2, filter3,
ansch_jahr, ansch_kost, code_4, reservierbar, isbn=None, item_type='general'): ansch_jahr, ansch_kost, code_4, reservierbar, isbn=None, item_type='general'):
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
@@ -247,18 +293,26 @@ def update_item(id, name, ort, beschreibung, images, verfuegbar, filter1, filter
{'$set': shared_update} {'$set': shared_update}
) )
client.close()
return True 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.
Args:
id (str): ID of the item to update
verfuegbar (bool): New availability status
user (str, optional): Username of person who borrowed the item
Returns:
bool: True if successful, False otherwise
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
@@ -272,6 +326,7 @@ def update_item_status(id, verfuegbar, user=None):
if user is not None: if user is not None:
update_data['User'] = dp.encrypt_text(user) update_data['User'] = dp.encrypt_text(user)
elif verfuegbar: elif verfuegbar:
# If item is being marked as available, clear the user field
update_query['$unset'] = {'User': ""} update_query['$unset'] = {'User': ""}
result = items.update_one( result = items.update_one(
@@ -279,6 +334,7 @@ def update_item_status(id, verfuegbar, user=None):
update_query update_query
) )
client.close()
return result.modified_count > 0 return result.modified_count > 0
except Exception as e: except Exception as e:
print(f"Error updating item status: {e}") print(f"Error updating item status: {e}")
@@ -288,9 +344,16 @@ def update_item_status(id, verfuegbar, user=None):
def update_item_exemplare_status(id, exemplare_status): def update_item_exemplare_status(id, exemplare_status):
""" """
Update the exemplar status of an inventory item. Update the exemplar status of an inventory item.
Args:
id (str): ID of the item to update
exemplare_status (list): List of status objects for each exemplar
Returns:
bool: True if successful, False otherwise
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
@@ -304,6 +367,7 @@ def update_item_exemplare_status(id, exemplare_status):
{'$set': update_data} {'$set': update_data}
) )
client.close()
return result.modified_count > 0 return result.modified_count > 0
except Exception as e: except Exception as e:
print(f"Error updating exemplar status: {e}") print(f"Error updating exemplar status: {e}")
@@ -313,20 +377,33 @@ def update_item_exemplare_status(id, exemplare_status):
def is_code_unique(code_4, exclude_id=None): def is_code_unique(code_4, exclude_id=None):
""" """
Check if a given code is unique (not used by any other item). Check if a given code is unique (not used by any other item).
Args:
code_4 (str): The code to check
exclude_id (str, optional): ID of item to exclude from the check (for edit operations)
Returns:
bool: True if code is unique, False if already in use
""" """
if not code_4 or code_4.strip() == "": if not code_4 or code_4.strip() == "":
# Empty codes are not considered unique
return False return False
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
# Build query to find items with this code
query = {'Code_4': code_4, 'Deleted': {'$ne': True}} query = {'Code_4': code_4, 'Deleted': {'$ne': True}}
# If we're editing an item, exclude it from the uniqueness check
if exclude_id: if exclude_id:
query['_id'] = {'$ne': ObjectId(exclude_id)} query['_id'] = {'$ne': ObjectId(exclude_id)}
# Check if any items with this code exist
count = items.count_documents(query) count = items.count_documents(query)
client.close()
return count == 0 return count == 0
@@ -335,18 +412,20 @@ def is_code_unique(code_4, exclude_id=None):
def get_items(): def get_items():
""" """
Retrieve all inventory items. Retrieve all inventory items.
Returns:
list: List of all inventory item documents with string IDs
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
items_return = items.find(_active_record_query(_non_library_query())) items_return = items.find(_active_record_query(_non_library_query()))
items_list = [] items_list = []
for item in items_return: for item in items_return:
item['_id'] = str(item['_id']) item['_id'] = str(item['_id'])
items_list.append(item) items_list.append(item)
client.close()
return items_list return items_list
except Exception as e: except Exception as e:
print(f"Error retrieving items: {e}") print(f"Error retrieving items: {e}")
@@ -356,18 +435,20 @@ def get_items():
def get_available_items(): def get_available_items():
""" """
Retrieve all available inventory items. Retrieve all available inventory items.
Returns:
list: List of available inventory item documents with string IDs
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
items_return = items.find(_active_record_query(_non_library_query({'Verfuegbar': True}))) items_return = items.find(_active_record_query(_non_library_query({'Verfuegbar': True})))
items_list = [] items_list = []
for item in items_return: for item in items_return:
item['_id'] = str(item['_id']) item['_id'] = str(item['_id'])
items_list.append(item) items_list.append(item)
client.close()
return items_list return items_list
except Exception as e: except Exception as e:
print(f"Error retrieving available items: {e}") print(f"Error retrieving available items: {e}")
@@ -377,24 +458,25 @@ def get_available_items():
def get_borrowed_items(): def get_borrowed_items():
""" """
Retrieve all currently borrowed inventory items. Retrieve all currently borrowed inventory items.
Returns:
list: List of borrowed inventory item documents with string IDs
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
items_return = items.find(_active_record_query(_non_library_query({'Verfuegbar': False}))) items_return = items.find(_active_record_query(_non_library_query({'Verfuegbar': False})))
items_list = [] items_list = []
for item in items_return: for item in items_return:
item['_id'] = str(item['_id']) item['_id'] = str(item['_id'])
items_list.append(item) items_list.append(item)
client.close()
return items_list return items_list
except Exception as e: except Exception as e:
print(f"Error retrieving borrowed items: {e}") print(f"Error retrieving borrowed items: {e}")
return [] return []
def get_item(id, decrypt=True): def get_item(id, decrypt=True):
""" """
Retrieve an inventory item by ID, with optional decryption. Retrieve an inventory item by ID, with optional decryption.
@@ -404,12 +486,11 @@ def get_item(id, decrypt=True):
return None return None
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
query = _active_record_query({'_id': item_id}) query = _active_record_query({'_id': item_id})
item = items.find_one(query) item = items.find_one(query)
if item: if item:
item['_id'] = str(item['_id']) item['_id'] = str(item['_id'])
if decrypt: if decrypt:
@@ -419,16 +500,22 @@ def get_item(id, decrypt=True):
print(f"Error retrieving item {id}: {e}") print(f"Error retrieving item {id}: {e}")
return None return None
def get_item_by_name(name): def get_item_by_name(name):
""" """
Retrieve a specific inventory item by its name. Retrieve a specific inventory item by its name.
Args:
name (str): Name of the item to retrieve
Returns:
dict: The inventory item document or None if not found
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
item = items.find_one(_active_record_query(_non_library_query({'Name': name}))) item = items.find_one(_active_record_query({'Name': name}))
client.close()
return item return item
except Exception as e: except Exception as e:
print(f"Error retrieving item by name: {e}") print(f"Error retrieving item by name: {e}")
@@ -438,12 +525,19 @@ def get_item_by_name(name):
def get_items_by_filter(filter_value): def get_items_by_filter(filter_value):
""" """
Retrieve inventory items matching a specific filter/category. Retrieve inventory items matching a specific filter/category.
Args:
filter_value (str): Filter value to search for
Returns:
list: List of items matching the filter in primary, secondary, or tertiary category
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
# Use $or to find matches in any filter field
query = _active_record_query(_non_library_query({ query = _active_record_query(_non_library_query({
'$or': [ '$or': [
{'Filter': filter_value}, {'Filter': filter_value},
@@ -453,6 +547,9 @@ def get_items_by_filter(filter_value):
})) }))
results = list(items.find(query)) results = list(items.find(query))
client.close()
# Convert ObjectId to string
for item in results: for item in results:
item['_id'] = str(item['_id']) item['_id'] = str(item['_id'])
@@ -465,24 +562,29 @@ def get_items_by_filter(filter_value):
def get_filters(): def get_filters():
""" """
Retrieve all unique filter/category values from the inventory. Retrieve all unique filter/category values from the inventory.
Returns:
list: Combined list of all primary, secondary and tertiary filter values
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
non_library = _active_record_query(_non_library_query()) non_library = _active_record_query(_non_library_query())
filters = items.distinct('Filter', non_library) filters = items.distinct('Filter', non_library)
filters2 = items.distinct('Filter2', non_library) filters2 = items.distinct('Filter2', non_library)
filters3 = items.distinct('Filter3', non_library) filters3 = items.distinct('Filter3', non_library)
# Combine filters and remove None/empty values
all_filters = [f for f in filters + filters2 + filters3 if f] all_filters = [f for f in filters + filters2 + filters3 if f]
# Remove duplicates while preserving order
unique_filters = [] unique_filters = []
for f in all_filters: for f in all_filters:
if f not in unique_filters: if f not in unique_filters:
unique_filters.append(f) unique_filters.append(f)
client.close()
return unique_filters return unique_filters
except Exception as e: except Exception as e:
print(f"Error retrieving filters: {e}") print(f"Error retrieving filters: {e}")
@@ -490,13 +592,20 @@ def get_filters():
def get_primary_filters(): def get_primary_filters():
"""Retrieve all unique primary filter values.""" """
Retrieve all unique primary filter values.
Returns:
list: List of all primary filter values
"""
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
filters = [f for f in items.distinct('Filter', _active_record_query(_non_library_query())) if f] filters = [f for f in items.distinct('Filter', _active_record_query(_non_library_query())) if f]
client.close()
# Add predefined values
predefined = get_predefined_filter_values(1) predefined = get_predefined_filter_values(1)
return sorted(list(set(filters + predefined))) return sorted(list(set(filters + predefined)))
except Exception as e: except Exception as e:
@@ -505,13 +614,20 @@ def get_primary_filters():
def get_secondary_filters(): def get_secondary_filters():
"""Retrieve all unique secondary filter values.""" """
Retrieve all unique secondary filter values.
Returns:
list: List of all secondary filter values
"""
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
filters = [f for f in items.distinct('Filter2', _active_record_query(_non_library_query())) if f] filters = [f for f in items.distinct('Filter2', _active_record_query(_non_library_query())) if f]
client.close()
# Add predefined values
predefined = get_predefined_filter_values(2) predefined = get_predefined_filter_values(2)
return sorted(list(set(filters + predefined))) return sorted(list(set(filters + predefined)))
except Exception as e: except Exception as e:
@@ -520,13 +636,20 @@ def get_secondary_filters():
def get_tertiary_filters(): def get_tertiary_filters():
"""Retrieve all unique tertiary filter values.""" """
Retrieve all unique tertiary filter values.
Returns:
list: List of all tertiary filter values
"""
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
filters = [f for f in items.distinct('Filter3', _active_record_query(_non_library_query())) if f] filters = [f for f in items.distinct('Filter3', _active_record_query(_non_library_query())) if f]
client.close()
# Add predefined values
predefined = get_predefined_filter_values(3) predefined = get_predefined_filter_values(3)
return sorted(list(set(filters + predefined))) return sorted(list(set(filters + predefined)))
except Exception as e: except Exception as e:
@@ -537,16 +660,24 @@ def get_tertiary_filters():
def get_item_by_code_4(code_4): def get_item_by_code_4(code_4):
""" """
Retrieve inventory items matching a specific 4-digit code. Retrieve inventory items matching a specific 4-digit code.
Args:
code_4 (str): 4-digit code to search for
Returns:
list: List of items matching the code
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
results = list(items.find(_active_record_query(_non_library_query({"Code_4": code_4})))) results = list(items.find(_active_record_query(_non_library_query({"Code_4": code_4}))))
# Convert ObjectId to string
for item in results: for item in results:
item['_id'] = str(item['_id']) item['_id'] = str(item['_id'])
client.close()
return results return results
except Exception as e: except Exception as e:
print(f"Error retrieving item by code: {e}") print(f"Error retrieving item by code: {e}")
@@ -558,13 +689,19 @@ def get_item_by_code_4(code_4):
def unstuck_item(id): def unstuck_item(id):
""" """
Remove all borrowing records for a specific item to reset its status. Remove all borrowing records for a specific item to reset its status.
Used to fix problematic or stuck items.
Args:
id (str): ID of the item to unstick
Returns:
bool: True if successful, False otherwise
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
ausleihungen = db['ausleihungen'] ausleihungen = db['ausleihungen']
result = ausleihungen.update_many(
ausleihungen.update_many(
{'Item': id, 'Status': {'$nin': ['cancelled', 'deleted']}}, {'Item': id, 'Status': {'$nin': ['cancelled', 'deleted']}},
{'$set': { {'$set': {
'Status': 'cancelled', 'Status': 'cancelled',
@@ -573,6 +710,7 @@ def unstuck_item(id):
}} }}
) )
# Also reset the item status
items = db['items'] items = db['items']
items.update_one( items.update_one(
{'_id': ObjectId(id)}, {'_id': ObjectId(id)},
@@ -584,6 +722,8 @@ def unstuck_item(id):
'$unset': {'User': ""} '$unset': {'User': ""}
} }
) )
client.close()
return True return True
except Exception as e: except Exception as e:
print(f"Error unsticking item: {e}") print(f"Error unsticking item: {e}")
@@ -593,79 +733,128 @@ def unstuck_item(id):
def get_predefined_filter_values(filter_num): def get_predefined_filter_values(filter_num):
""" """
Get predefined values for a specific filter. Get predefined values for a specific filter.
Args:
filter_num (int): Filter number (1 for Unterrichtsfach, 2 for Jahrgangsstufe)
Returns:
list: List of predefined filter values
""" """
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
# Use a dedicated collection for filter presets
filter_presets = db['filter_presets'] filter_presets = db['filter_presets']
# Find the document for the specified filter
filter_doc = filter_presets.find_one({'filter_num': filter_num}) filter_doc = filter_presets.find_one({'filter_num': filter_num})
client.close()
if filter_doc and 'values' in filter_doc: if filter_doc and 'values' in filter_doc:
# Sort values alphabetically
return sorted(filter_doc['values']) return sorted(filter_doc['values'])
else: else:
# Create empty document if it doesn't exist
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB]
filter_presets = db['filter_presets']
filter_presets.update_one( filter_presets.update_one(
{'filter_num': filter_num}, {'filter_num': filter_num},
{'$set': {'values': []}}, {'$set': {'values': []}},
upsert=True upsert=True
) )
client.close()
return [] return []
def add_predefined_filter_value(filter_num, value): def add_predefined_filter_value(filter_num, value):
""" """
Add a new predefined value to a filter. Add a new predefined value to a filter.
Args:
filter_num (int): Filter number (1 for Unterrichtsfach, 2 for Jahrgangsstufe)
value (str): Value to add
Returns:
bool: True if value was added, False if it already existed
""" """
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
filter_presets = db['filter_presets'] filter_presets = db['filter_presets']
# Check if value already exists
filter_doc = filter_presets.find_one({ filter_doc = filter_presets.find_one({
'filter_num': filter_num, 'filter_num': filter_num,
'values': value 'values': value
}) })
if filter_doc: if filter_doc:
# Value already exists
client.close()
return False return False
# Add the value to the filter
result = filter_presets.update_one( result = filter_presets.update_one(
{'filter_num': filter_num}, {'filter_num': filter_num},
{'$push': {'values': value}}, {'$push': {'values': value}},
upsert=True upsert=True
) )
return result.modified_count > 0 or result.upserted_id is not None
client.close()
return result.modified_count > 0 or result.upserted_id is not None
def remove_predefined_filter_value(filter_num, value): def remove_predefined_filter_value(filter_num, value):
""" """
Remove a predefined value from a filter. Remove a predefined value from a filter.
Args:
filter_num (int): Filter number (1 for Unterrichtsfach, 2 for Jahrgangsstufe)
value (str): Value to remove
Returns:
bool: True if value was removed, False otherwise
""" """
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
filter_presets = db['filter_presets'] filter_presets = db['filter_presets']
# Remove the value from the filter
result = filter_presets.update_one( result = filter_presets.update_one(
{'filter_num': filter_num}, {'filter_num': filter_num},
{'$pull': {'values': value}} {'$pull': {'values': value}}
) )
client.close()
return result.modified_count > 0 return result.modified_count > 0
def edit_predefined_filter_value(filter_num, old_value, new_value): def edit_predefined_filter_value(filter_num, old_value, new_value):
""" """
Edit a predefined value from a filter and update all matching items. Edit a predefined value from a filter and update all matching items.
Args:
filter_num (int): Filter number (1 for Unterrichtsfach, 2 for Jahrgangsstufe)
old_value (str): Value to replace
new_value (str): New value
Returns:
bool: True if value was updated, False otherwise
""" """
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
filter_presets = db['filter_presets'] filter_presets = db['filter_presets']
# Check if the new value already exists
existing = filter_presets.find_one({ existing = filter_presets.find_one({
'filter_num': filter_num, 'filter_num': filter_num,
'values': new_value 'values': new_value
}) })
if existing and old_value != new_value: if existing and old_value != new_value:
client.close()
return False return False
# Update the value in the filter
result = filter_presets.update_one( result = filter_presets.update_one(
{'filter_num': filter_num, 'values': old_value}, {'filter_num': filter_num, 'values': old_value},
{'$set': {'values.$': new_value}} {'$set': {'values.$': new_value}}
@@ -675,42 +864,41 @@ def edit_predefined_filter_value(filter_num, old_value, new_value):
items = db['items'] items = db['items']
filter_field = 'Filter' if filter_num == 1 else f'Filter{filter_num}' filter_field = 'Filter' if filter_num == 1 else f'Filter{filter_num}'
# Also update all items that use this filter
items.update_many( items.update_many(
{filter_field: old_value}, {filter_field: old_value},
{'$set': {filter_field: new_value}} {'$set': {filter_field: new_value}}
) )
client.close()
return result.modified_count > 0 return result.modified_count > 0
def get_filter_names(): def get_filter_names():
"""Get customized filter category names.""" """Get customized filter category names."""
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
names_doc = db.settings.find_one({'setting_type': 'filter_names'}) names_doc = db.settings.find_one({'setting_type': 'filter_names'})
client.close()
if names_doc and 'names' in names_doc: if names_doc and 'names' in names_doc:
return names_doc['names'] return names_doc['names']
return { return {
'1': 'Fach/Kategorie', '1': 'Fach/Kategorie',
'2': 'System/Bereich', '2': 'System/Bereich',
'3': 'Typ/Art' '3': 'Typ/Art'
} }
def set_filter_name(filter_num, name): def set_filter_name(filter_num, name):
"""Set custom name for a filter category.""" """Set custom name for a filter category."""
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
names = get_filter_names() names = get_filter_names()
names[str(filter_num)] = name names[str(filter_num)] = name
db.settings.update_one( db.settings.update_one(
{'setting_type': 'filter_names'}, {'setting_type': 'filter_names'},
{'$set': {'names': names}}, {'$set': {'names': names}},
upsert=True upsert=True
) )
client.close()
return True return True
@@ -719,25 +907,33 @@ def set_filter_name(filter_num, name):
def get_predefined_locations(): def get_predefined_locations():
""" """
Get list of all predefined locations/placement options. Get list of all predefined locations/placement options.
Returns:
list: List of predefined location strings
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
# Check if settings collection exists, create if not
if 'settings' not in db.list_collection_names(): if 'settings' not in db.list_collection_names():
db.create_collection('settings') db.create_collection('settings')
# Get settings document or create if it doesn't exist
settings_collection = db['settings'] settings_collection = db['settings']
location_settings = settings_collection.find_one({'setting_type': 'predefined_locations'}) location_settings = settings_collection.find_one({'setting_type': 'predefined_locations'})
if not location_settings: if not location_settings:
# Create default settings document if it doesn't exist
settings_collection.insert_one({ settings_collection.insert_one({
'setting_type': 'predefined_locations', 'setting_type': 'predefined_locations',
'locations': [] 'locations': []
}) })
return [] return []
# Return the predefined locations
locations = location_settings.get('locations', []) locations = location_settings.get('locations', [])
client.close()
return sorted(locations) return sorted(locations)
except Exception as e: except Exception as e:
@@ -748,6 +944,12 @@ def get_predefined_locations():
def add_predefined_location(location): def add_predefined_location(location):
""" """
Add a new predefined location. Add a new predefined location.
Args:
location (str): Location to add
Returns:
bool: True if added successfully, False if already exists
""" """
if not location or not isinstance(location, str): if not location or not isinstance(location, str):
return False return False
@@ -757,27 +959,35 @@ def add_predefined_location(location):
return False return False
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
settings_collection = db['settings'] settings_collection = db['settings']
# Check if settings document exists, create if not
location_settings = settings_collection.find_one({'setting_type': 'predefined_locations'}) location_settings = settings_collection.find_one({'setting_type': 'predefined_locations'})
if not location_settings: if not location_settings:
# Create with the new location
settings_collection.insert_one({ settings_collection.insert_one({
'setting_type': 'predefined_locations', 'setting_type': 'predefined_locations',
'locations': [location] 'locations': [location]
}) })
client.close()
return True return True
# Check if location already exists (case-insensitive)
current_locations = location_settings.get('locations', []) current_locations = location_settings.get('locations', [])
if any(loc.lower() == location.lower() for loc in current_locations): if any(loc.lower() == location.lower() for loc in current_locations):
client.close()
return False return False
# Add the new location
settings_collection.update_one( settings_collection.update_one(
{'setting_type': 'predefined_locations'}, {'setting_type': 'predefined_locations'},
{'$push': {'locations': location}} {'$push': {'locations': location}}
) )
client.close()
return True return True
except Exception as e: except Exception as e:
@@ -788,12 +998,18 @@ def add_predefined_location(location):
def remove_predefined_location(location): def remove_predefined_location(location):
""" """
Remove a predefined location. Remove a predefined location.
Args:
location (str): Location to remove
Returns:
bool: True if removed successfully
""" """
if not location: if not location:
return False return False
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
settings_collection = db['settings'] settings_collection = db['settings']
@@ -801,6 +1017,8 @@ def remove_predefined_location(location):
{'setting_type': 'predefined_locations'}, {'setting_type': 'predefined_locations'},
{'$pull': {'locations': location}} {'$pull': {'locations': location}}
) )
client.close()
return result.modified_count > 0 return result.modified_count > 0
except Exception as e: except Exception as e:
@@ -811,20 +1029,31 @@ def remove_predefined_location(location):
def update_item_next_appointment(item_id, appointment_data): def update_item_next_appointment(item_id, appointment_data):
""" """
Update an item with information about its next scheduled appointment. Update an item with information about its next scheduled appointment.
Args:
item_id (str): ID of the item
appointment_data (dict or None): Dictionary containing appointment details
(e.g., user, start_time, end_time) or None to clear it.
Returns:
bool: True if successful, False otherwise
""" """
try: try:
with MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) as client: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB] db = client[cfg.MONGODB_DB]
items = db['items'] items = db['items']
# If clearing the appointment
if appointment_data is None: if appointment_data is None:
update_query = { update_query = {
'$unset': {'NextAppointment': ""}, '$unset': {'NextAppointment': ""},
'$set': {'LastUpdated': datetime.datetime.now()} '$set': {'LastUpdated': datetime.datetime.now()}
} }
else: else:
# Create a copy so we don't mutate the original dictionary passed in
data_to_save = appointment_data.copy() data_to_save = appointment_data.copy()
# Encrypt the user field if it exists to match the decryption logic at the top
if 'user' in data_to_save and data_to_save['user']: if 'user' in data_to_save and data_to_save['user']:
data_to_save['user'] = dp.encrypt_text(data_to_save['user']) data_to_save['user'] = dp.encrypt_text(data_to_save['user'])
@@ -840,7 +1069,82 @@ def update_item_next_appointment(item_id, appointment_data):
update_query update_query
) )
client.close()
return result.modified_count > 0 return result.modified_count > 0
except Exception as e: except Exception as e:
print(f"Error updating item next appointment: {e}") print(f"Error updating item next appointment: {e}")
return False return False
def clear_item_next_appointment(item_id):
"""
Clear the next appointment information from an item.
Args:
item_id (str): ID of the item to update
Returns:
bool: True if successful, False otherwise
"""
try:
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB]
items = db['items']
result = items.update_one(
{'_id': ObjectId(item_id)},
{'$unset': {'NextAppointment': ""}, '$set': {'LastUpdated': datetime.datetime.now()}}
)
client.close()
return result.modified_count > 0
except Exception as e:
print(f"Error clearing item next appointment: {e}")
return False
def get_items_with_appointments():
"""
Retrieve all items that have scheduled appointments.
Returns:
list: List of items with NextAppointment field
"""
try:
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB]
items = db['items']
items_return = items.find({'NextAppointment': {'$exists': True}, 'Deleted': {'$ne': True}})
items_list = []
for item in items_return:
item['_id'] = str(item['_id'])
items_list.append(item)
client.close()
return items_list
except Exception as e:
print(f"Error retrieving items with appointments: {e}")
return []
def get_current_status(item_id, decrypt=True):
"""
Retrieve the current status of an item, decrypting the user field if present.
"""
oid = _to_object_id(item_id)
if not oid:
return None
try:
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = client[cfg.MONGODB_DB]
items = db['items']
item = items.find_one({'_id': oid}, {'Verfuegbar': 1, 'User': 1})
if item:
item['_id'] = str(item['_id'])
if decrypt:
decrypt_item_user_data(item)
return item
return None
except Exception as e:
print(f"Error retrieving current status for item {item_id}: {e}")
return None