107 lines
4 KiB
Python
107 lines
4 KiB
Python
import json
|
|
import traceback
|
|
|
|
from flask import request, flash, redirect, url_for, render_template, jsonify
|
|
|
|
from . import main
|
|
from .. import db
|
|
from ..models import Brand, Item, Area, RoomFunction, Room
|
|
from ..utils.load import eager_load_room_relationships
|
|
|
|
@main.route('/settings', methods=['GET', 'POST'])
|
|
def settings():
|
|
if request.method == 'POST':
|
|
form = request.form
|
|
|
|
try:
|
|
state = json.loads(form['formState'])
|
|
except Exception:
|
|
flash("Invalid form state submitted. JSON decode failed.", "danger")
|
|
traceback.print_exc()
|
|
return redirect(url_for('main.settings'))
|
|
|
|
try:
|
|
with db.session.begin():
|
|
# Sync each table and grab temp ID maps
|
|
brand_map = Brand.sync_from_state(state.get("brands", []))
|
|
type_map = Item.sync_from_state(state.get("types", []))
|
|
section_map = Area.sync_from_state(state.get("sections", []))
|
|
function_map = RoomFunction.sync_from_state(state.get("functions", []))
|
|
|
|
# Fix up room foreign keys based on real IDs
|
|
submitted_rooms = []
|
|
for room in state.get("rooms", []):
|
|
room = dict(room) # shallow copy
|
|
sid = room.get("section_id")
|
|
fid = room.get("function_id")
|
|
|
|
if sid is not None:
|
|
sid_key = str(sid)
|
|
if sid_key in section_map:
|
|
room["section_id"] = section_map[sid_key]
|
|
|
|
if fid is not None:
|
|
fid_key = str(fid)
|
|
if fid_key in function_map:
|
|
room["function_id"] = function_map[fid_key]
|
|
|
|
submitted_rooms.append(room)
|
|
|
|
Room.sync_from_state(
|
|
submitted_rooms=submitted_rooms,
|
|
section_map=section_map,
|
|
function_map=function_map
|
|
)
|
|
|
|
flash("Changes saved.", "success")
|
|
|
|
except Exception as e:
|
|
flash(f"Error saving changes: {e}", "danger")
|
|
|
|
return redirect(url_for('main.settings'))
|
|
|
|
# === GET ===
|
|
brands = db.session.query(Brand).order_by(Brand.name).all()
|
|
types = db.session.query(Item).order_by(Item.description).all()
|
|
sections = db.session.query(Area).order_by(Area.name).all()
|
|
functions = db.session.query(RoomFunction).order_by(RoomFunction.description).all()
|
|
rooms = eager_load_room_relationships(db.session.query(Room).order_by(Room.name)).all()
|
|
|
|
return render_template('settings.html',
|
|
title="Settings",
|
|
brands=[b.serialize() for b in brands],
|
|
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]
|
|
)
|
|
|
|
@main.route("/api/settings", methods=["POST"])
|
|
def api_settings():
|
|
try:
|
|
payload = request.get_json(force=True)
|
|
except Exception as e:
|
|
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
|