Files
aufmass-web/_aufmass_web/app/__init__.py
T

166 lines
6.9 KiB
Python

from flask import Flask, render_template, request, redirect, url_for
from config import Config
from app.extensions import db, login_manager, migrate
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
db.init_app(app)
login_manager.init_app(app)
migrate.init_app(app, db)
login_manager.login_view = 'auth.login'
login_manager.login_message = 'Bitte melden Sie sich an.'
from app.models.user import User
from app.models.company import Company
from app.models.license import License
from app.models.module import Module
from app.models.lv import LVPosition
from app.models.project import Project
from app.models.aufmass import Aufmass
from app.models.project_access import ProjectAccess
from app.models.position import Position
from app.models.contract import Contract
from app.models.view_profile import ViewProfile
from app.models.company_module import CompanyModule
from app.models.user_module import UserModulePermission
from app.models.aufmass_typ import AufmassTyp
from app.models.aufmass_history import AufmassHistory
@login_manager.user_loader
def load_user(user_id):
user = User.query.get(int(user_id))
if user:
from flask import session
session.setdefault('font_size', user.font_size or '1')
return user
from app.routes.auth import auth_bp
from app.routes.admin import admin_bp
from app.routes.lv import lv_bp
from app.routes.aufmass import aufmass_bp
from app.routes.export import export_bp
from app.routes.modules import modules_bp
from app.routes.contracts import contracts_bp
from app.routes.views import views_bp
from app.routes.superadmin import superadmin_bp
from app.routes.custom_modules import custom_modules_bp
app.register_blueprint(auth_bp, url_prefix='/auth')
app.register_blueprint(admin_bp, url_prefix='/admin')
app.register_blueprint(lv_bp, url_prefix='/lv')
app.register_blueprint(aufmass_bp, url_prefix='/projekt')
app.register_blueprint(export_bp, url_prefix='/export')
app.register_blueprint(modules_bp, url_prefix='/modules')
app.register_blueprint(contracts_bp, url_prefix='/contracts')
app.register_blueprint(views_bp)
app.register_blueprint(superadmin_bp, url_prefix='/superadmin')
app.register_blueprint(custom_modules_bp, url_prefix='/custom-modules')
@app.route('/aufmass/')
@app.route('/aufmass/<path:subpath>')
def _aufmass_redirect(subpath=''):
return redirect('/projekt/' + subpath), 301
@app.route('/')
def index():
from flask_login import current_user
if current_user.is_authenticated:
if current_user.is_superadmin():
return redirect(url_for('superadmin.dashboard'))
return redirect(url_for('admin.dashboard'))
return redirect(url_for('auth.login'))
@app.route('/font-size/<size>')
def set_font_size(size):
from flask import session
from flask_login import current_user
if size in ('0.8', '0.9', '1', '1.1', '1.25', '1.5'):
session['font_size'] = size
if current_user.is_authenticated:
current_user.font_size = size
try:
db.session.commit()
except:
db.session.rollback()
return redirect(request.referrer or url_for('admin.dashboard'))
@app.template_filter('german_number')
def german_number_filter(value, precision=2, zero_dash=False):
if value is None or (zero_dash and value == 0):
return '\u2013'
try:
s = f'{float(value):.{precision}f}'
parts = s.split('.')
int_part = parts[0]
dec_part = parts[1] if len(parts) > 1 else '0'*precision
int_part = '{:,}'.format(int(int_part)).replace(',', '.')
return f'{int_part},{dec_part}'
except (ValueError, TypeError):
return '\u2013' if zero_dash else '0,00'
@app.errorhandler(404)
def not_found(e):
return render_template('errors/404.html'), 404
@app.errorhandler(500)
def server_error(e):
return render_template('errors/500.html'), 500
with app.app_context():
db.create_all()
_seed_defaults()
return app
def _seed_defaults():
from app.extensions import db
from app.models.module import Module
def upsert(name, titel, kategorie, icon, standard, sortierung=0):
m = Module.query.filter_by(name=name).first()
if m:
m.titel = titel
m.kategorie = kategorie
m.icon = icon
m.standard = standard
m.sortierung = sortierung
else:
db.session.add(Module(name=name, titel=titel, kategorie=kategorie, icon=icon, standard=standard, sortierung=sortierung))
# 1. Tote Module entfernen (inkl. FK-Referenzen)
for dead_name in ('mfg', 'stoersammler'):
old = Module.query.filter_by(name=dead_name).first()
if old:
from app.models.license import LicenseModule
from app.models.company_module import CompanyModule
LicenseModule.query.filter_by(module_id=old.id).delete()
CompanyModule.query.filter_by(module_id=old.id).delete()
db.session.delete(old)
db.session.commit()
# 2. Alle Module upserten
upsert('graben', 'Graben', 'Tiefbau', '🔲', standard=True)
upsert('gruben', 'Gruben', 'Tiefbau', '🕳️', standard=True)
upsert('gf_montage', 'GF-Montage', 'Glasfaser', '🔗', standard=True)
upsert('ftth', 'FTTH', 'Glasfaser', '🏠', standard=True)
upsert('kabelzug', 'Kabelzug', 'Tiefbau', '🔌', standard=True)
upsert('absperrung', 'Absperrung', 'Tiefbau', '🚧', standard=True)
upsert('sas_mecka', 'SAS Meckenbeuren', 'Spezial', '📍', standard=False)
upsert('neff_achberg', 'Neff-Achberg', 'Spezial', '🏗️', standard=False)
upsert('cu', 'CU', 'Kupfer', '📞', standard=True)
upsert('stoerung', 'Störung', 'Service', '🔧', standard=True)
upsert('tvum', 'TV/UM', 'Glasfaser', '📺', standard=True)
upsert('planung', 'Planung', 'Planung', '📐', standard=True)
upsert('zw_rv', 'ZW/RV', 'Tiefbau', '🔩', standard=True)
upsert('doku', 'Dokumentation', 'Planung', '📄', standard=True)
upsert('sto_sammler', 'Störungs-Sammler', 'Service', '📋', standard=True)
db.session.commit()
from app.models.aufmass_typ import AufmassTyp
if AufmassTyp.query.count() == 0:
db.session.add(AufmassTyp(name='Teilaufmaß/AZ', sortierung=1))
db.session.add(AufmassTyp(name='Schlussaufmaß', sortierung=2))
db.session.commit()