diff --git a/routes.py b/routes.py index f9ae3a2..8606406 100644 --- a/routes.py +++ b/routes.py @@ -1,4 +1,4 @@ -from flask import Blueprint, render_template, url_for, request, redirect, flash +from flask import Blueprint, render_template, url_for, request, redirect, flash, jsonify from flask import current_app as app from .models import Brand, Item, Inventory, RoomFunction, User, WorkLog, Room, Area from sqlalchemy import or_, delete @@ -152,8 +152,7 @@ def index(): active_worklog_headers=active_worklog_headers, active_worklog_rows=active_worklog_rows, labels=labels, - datasets=datasets, - endpoint='index' + datasets=datasets ) def link(text, endpoint, **values): @@ -205,8 +204,7 @@ def list_inventory(): breadcrumb=[{'label': 'Inventory', 'url': url_for('main.inventory_index')}], header=inventory_headers, rows=[{"id": item.id, "cells": [row_fn(item) for row_fn in inventory_headers.values()]} for item in inventory], - entry_route = 'inventory_item', - endpoint='list_inventory' + entry_route = 'inventory_item' ) @main.route("/inventory/index") @@ -235,8 +233,7 @@ def inventory_index(): 'inventory_index.html', title=f"Inventory ({category.capitalize()} Index)" if category else "Inventory", category=category, - listing=listing, - endpoint='inventory_index' + listing=listing ) @main.route("/inventory_item/", methods=['GET', 'POST']) @@ -271,9 +268,7 @@ def inventory_item(id): worklog=worklog, worklog_headers=filtered_worklog_headers, worklog_rows=[{"id": log.id, "cells": [fn(log) for fn in filtered_worklog_headers.values()]} for log in worklog], - types=types, - endpoint='inventory_item', - endpoint_args={'id': item.id} + types=types ) @main.route("/users") @@ -285,8 +280,7 @@ def list_users(): header = user_headers, rows = [{"id": user.id, "cells": [fn(user) for fn in user_headers.values()]} for user in users], title = "Users", - entry_route = 'user', - endpoint='list_users' + entry_route = 'user' ) @main.route("/user/") @@ -322,9 +316,7 @@ def user(id): return render_template( 'error.html', title=title, - message=f"User with id {id} not found!", - endpoint='user', - endpoint_args={'id': -1} + message=f"User with id {id} not found!" ) return render_template( @@ -335,9 +327,7 @@ def user(id): inventory_rows=[{"id": item.id, "cells": [fn(item) for fn in filtered_inventory_headers.values()]} for item in inventory], worklog=worklog, worklog_headers=filtered_worklog_headers, - worklog_rows=[{"id": log.id, "cells": [fn(log) for fn in filtered_worklog_headers.values()]} for log in worklog], - endpoint='user', - endpoint_args={'id': user.id} + worklog_rows=[{"id": log.id, "cells": [fn(log) for fn in filtered_worklog_headers.values()]} for log in worklog] ) @main.route("/worklog") @@ -349,8 +339,7 @@ def list_worklog(page=1): header=worklog_headers, rows=[{"id": log.id, "cells": [fn(log) for fn in worklog_headers.values()]} for log in query.all()], title="Work Log", - entry_route='worklog_entry', - endpoint='list_worklog' + entry_route='worklog_entry' ) @main.route("/worklog/") @@ -373,9 +362,7 @@ def worklog_entry(id): return render_template( 'error.html', title=title, - message=f"The work log with ID {id} is not found!", - endpoint='worklog_entry', - endpoint_args={'id': -1} + message=f"The work log with ID {id} is not found!" ) return render_template( @@ -384,9 +371,7 @@ def worklog_entry(id): log=log, users=users, items=items, - form_fields=worklog_form_fields, - endpoint='worklog_entry', - endpoint_args={'id': log.id} + form_fields=worklog_form_fields ) @main.route("/search") @@ -446,7 +431,7 @@ def search(): } } - return render_template('search.html', title=f"Database Search ({query})" if query else "Database Search", results=results, query=query, endpoint='search') + return render_template('search.html', title=f"Database Search ({query})" if query else "Database Search", results=results, query=query) @main.route('/settings', methods=['GET', 'POST']) def settings(): @@ -518,54 +503,35 @@ def settings(): types=[{"id": t.id, "name": t.description} for t in types], sections=[s.serialize() for s in sections], functions=[f.serialize() for f in functions], - rooms=[r.serialize() for r in rooms], - endpoint='settings' + rooms=[r.serialize() for r in rooms] ) -@main.route('/api/settings', methods=['POST']) +@main.route("/api/settings", methods=["POST"]) def api_settings(): try: - payload = request.get_json() - if not payload: - return {'error': 'No JSON payload'}, 400 - - for label, entries in [ - ('brands', payload.get('brands', [])), - ('types', payload.get('types', [])), - ('sections', payload.get('sections', [])), - ('functions', payload.get('functions', [])), - ('rooms', payload.get('rooms', [])), - ]: - if not isinstance(entries, list): - return {'error': f"{label} must be a list"}, 400 - for entry in entries: - if not isinstance(entry, dict): - return {'error': f'Each {label} entry must be a dict'}, 400 - - errors = [] - errors += Brand.validate_state(payload.get("brands", [])) - errors += Item.validate_state(payload.get("types", [])) - errors += Area.validate_state(payload.get("sections", [])) - errors += RoomFunction.validate_state(payload.get("functions", [])) - errors += Room.validate_state(payload.get("rooms", [])) - - if errors: - return {'status': 'error', 'errors': errors}, 400 - - with db.session.begin(): - brand_map = Brand.sync_from_state(payload.get('brands', [])) - type_map = Item.sync_from_state(payload.get('types', [])) - section_map = Area.sync_from_state(payload.get('sections', [])) - function_map = RoomFunction.sync_from_state(payload.get('functions', [])) - - Room.sync_from_state( - submitted_rooms=payload.get('rooms', []), - section_map=section_map, - function_map=function_map - ) - - return {'status': 'ok'}, 200 - + payload = request.get_json(force=True) except Exception as e: - traceback.print_exc() - return {'status': 'error', 'message': str(e)}, 500 \ No newline at end of file + return jsonify({"error": "Invalid JSON"}), 400 + + errors = [] + errors += Brand.validate_state(payload.get("brands", [])) + errors += Item.validate_state(payload.get("types", [])) + errors += Area.validate_state(payload.get("sections", [])) + errors += RoomFunction.validate_state(payload.get("functions", [])) + errors += Room.validate_state(payload.get("rooms", [])) + + if errors: + return jsonify({"errors": errors}), 400 + + try: + with db.session.begin(): + section_map = Area.sync_from_state(payload["sections"]) + function_map = RoomFunction.sync_from_state(payload["functions"]) + Brand.sync_from_state(payload["brands"]) + Item.sync_from_state(payload["types"]) + Room.sync_from_state(payload["rooms"], section_map, function_map) + except Exception as e: + db.session.rollback() + return jsonify({"errors": [str(e)]}), 500 + + return jsonify({"message": "Settings updated successfully."}), 200 diff --git a/templates/layout.html b/templates/layout.html index cf17e15..b71e6a8 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -53,10 +53,7 @@
-
{% block content %}{% endblock %} - -