Files
ksef_app/app/services/settings_service.py
Mateusz Gruszczyński 35571df778 push
2026-03-13 11:03:13 +01:00

116 lines
5.0 KiB
Python

from __future__ import annotations
from pathlib import Path
from flask import current_app
from app.extensions import db
from app.models.setting import AppSetting
from app.services.company_service import CompanyService
class SettingsService:
@staticmethod
def _user_scope_key(key: str, user_id=None):
from flask_login import current_user
if user_id is None and getattr(current_user, 'is_authenticated', False):
user_id = current_user.id
return f'user.{user_id}.{key}' if user_id else key
@staticmethod
def _scope_key(key: str, company_id=None):
if company_id is None:
company = CompanyService.get_current_company()
company_id = company.id if company else None
return f'company.{company_id}.{key}' if company_id else key
@staticmethod
def get(key, default=None, company_id=None):
scoped = AppSetting.get(SettingsService._scope_key(key, company_id), default=None)
if scoped is not None:
return scoped
return AppSetting.get(key, default=default)
@staticmethod
def get_secret(key, default=None, company_id=None):
scoped = AppSetting.get(SettingsService._scope_key(key, company_id), default=None, decrypt=True)
if scoped is not None:
return scoped
return AppSetting.get(key, default=default, decrypt=True)
@staticmethod
def set_many(mapping: dict[str, tuple[object, bool] | object], company_id=None):
for key, value in mapping.items():
if isinstance(value, tuple):
raw, encrypt = value
else:
raw, encrypt = value, False
AppSetting.set(SettingsService._scope_key(key, company_id), raw, encrypt=encrypt)
db.session.commit()
@staticmethod
def storage_path(key: str, fallback: Path):
value = SettingsService.get(key)
if value:
path = Path(value)
if not path.is_absolute():
path = Path(current_app.root_path).parent / path
path.mkdir(parents=True, exist_ok=True)
return path
fallback.mkdir(parents=True, exist_ok=True)
return fallback
@staticmethod
def read_only_enabled(company_id=None) -> bool:
from flask_login import current_user
company = CompanyService.get_current_company()
cid = company_id or (company.id if company else None)
truly_global_ro = AppSetting.get('app.read_only_mode', 'false') == 'true'
company_ro = AppSetting.get(f'company.{cid}.app.read_only_mode', 'false') == 'true' if cid else False
user_ro = getattr(current_user, 'is_authenticated', False) and cid and current_user.is_company_readonly(cid)
return truly_global_ro or company_ro or bool(user_ro)
@staticmethod
def get_user(key, default=None, user_id=None):
return AppSetting.get(SettingsService._user_scope_key(key, user_id), default=default)
@staticmethod
def get_user_secret(key, default=None, user_id=None):
return AppSetting.get(SettingsService._user_scope_key(key, user_id), default=default, decrypt=True)
@staticmethod
def set_many_user(mapping: dict[str, tuple[object, bool] | object], user_id=None):
for key, value in mapping.items():
if isinstance(value, tuple):
raw, encrypt = value
else:
raw, encrypt = value, False
AppSetting.set(SettingsService._user_scope_key(key, user_id), raw, encrypt=encrypt)
db.session.commit()
@staticmethod
def get_preference(scope_name: str, default='global', user_id=None):
return AppSetting.get(SettingsService._user_scope_key(f'pref.{scope_name}.mode', user_id), default=default)
@staticmethod
def set_preference(scope_name: str, mode: str, user_id=None):
AppSetting.set(SettingsService._user_scope_key(f'pref.{scope_name}.mode', user_id), mode)
db.session.commit()
@staticmethod
def get_effective(key, default=None, company_id=None, user_id=None, scope_name=None, user_default='global'):
scope_name = scope_name or key.split('.', 1)[0]
mode = SettingsService.get_preference(scope_name, default=user_default, user_id=user_id)
if mode == 'user':
value = SettingsService.get_user(key, default=None, user_id=user_id)
if value not in [None, '']:
return value
return SettingsService.get(key, default=default, company_id=company_id)
@staticmethod
def get_effective_secret(key, default=None, company_id=None, user_id=None, scope_name=None, user_default='global'):
scope_name = scope_name or key.split('.', 1)[0]
mode = SettingsService.get_preference(scope_name, default=user_default, user_id=user_id)
if mode == 'user':
value = SettingsService.get_user_secret(key, default=None, user_id=user_id)
if value not in [None, '']:
return value
return SettingsService.get_secret(key, default=default, company_id=company_id)