Files
ACORE/apps/locations/dislocation_columns.py
T
lokses 897ffc99c9 locations: право редактирования аптеки, формы и дислокация
Отдельное право на редактирование карточки аптеки, формы, пресеты колонок
дислокации и правки видимости карточки.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-09 18:03:32 +03:00

113 lines
4.0 KiB
Python

"""Каталог колонок таблицы дислокации аптек (whitelist).
Секреты (пароль Carbonio и т.п.) сюда не входят.
Колонка ``pharmacy`` всегда обязательна, но порядок среди колонок свободный.
"""
from __future__ import annotations
from dataclasses import dataclass
from django.utils.translation import gettext_lazy as _
LOCKED_KEY = 'pharmacy'
STANDARD_COLUMNS = [
'pharmacy', 'organization', 'head', 'staff', 'phone', 'hours', 'status',
'generator', 'inverter', 'mikrotik',
'provider', 'contract', 'gpon',
]
HR_COLUMNS = [
'pharmacy', 'organization', 'head', 'staff', 'curator', 'manager',
]
OPS_COLUMNS = [
'pharmacy', 'region', 'phone', 'hours', 'status', 'category',
'generator', 'inverter', 'mikrotik',
'provider', 'contract', 'gpon',
]
@dataclass(frozen=True)
class ColumnDef:
key: str
label: str
sort_type: str # 'string' | 'number'
locked: bool = False
COLUMN_DEFS: dict[str, ColumnDef] = {
'pharmacy': ColumnDef('pharmacy', _('Аптека'), 'number', locked=True),
'organization': ColumnDef('organization', _('Организация'), 'string'),
'head': ColumnDef('head', _('Заведующий'), 'string'),
'staff': ColumnDef('staff', _('Персонал'), 'number'),
'phone': ColumnDef('phone', _('Телефон'), 'string'),
'hours': ColumnDef('hours', _('Режим работы'), 'string'),
'status': ColumnDef('status', _('Статус'), 'number'),
'region': ColumnDef('region', _('Регион'), 'string'),
'category': ColumnDef('category', _('Категория'), 'string'),
'curator': ColumnDef('curator', _('Куратор'), 'string'),
'manager': ColumnDef('manager', _('Ответственный менеджер'), 'string'),
'license': ColumnDef('license', _('Лицензия'), 'string'),
'vat': ColumnDef('vat', _('ПДВ'), 'string'),
'email': ColumnDef('email', _('Email'), 'string'),
'generator': ColumnDef('generator', _('Генератор'), 'string'),
'inverter': ColumnDef('inverter', _('Инвертор'), 'string'),
'mikrotik': ColumnDef('mikrotik', _('MikroTik'), 'string'),
'provider': ColumnDef('provider', _('Провайдер'), 'string'),
'contract': ColumnDef('contract', _('Договор'), 'string'),
'gpon': ColumnDef('gpon', _('GPON'), 'string'),
}
ALLOWED_KEYS = frozenset(COLUMN_DEFS)
def normalize_columns(keys) -> list[str]:
"""Оставляет только известные ключи без дублей; ``pharmacy`` всегда в наборе."""
seen = set()
result = []
for key in keys or []:
if key not in ALLOWED_KEYS or key in seen:
continue
seen.add(key)
result.append(key)
if LOCKED_KEY not in result:
result.insert(0, LOCKED_KEY)
return result
def column_defs_for(keys: list[str]) -> list[ColumnDef]:
return [COLUMN_DEFS[k] for k in keys if k in COLUMN_DEFS]
def all_column_defs() -> list[ColumnDef]:
# pharmacy first in the registry list, then the rest in declaration order
rest = [d for k, d in COLUMN_DEFS.items() if k != LOCKED_KEY]
return [COLUMN_DEFS[LOCKED_KEY], *rest]
def resolve_columns_for_user(user) -> list[str]:
"""Персональный override → пресет отдела → is_default → STANDARD."""
custom = getattr(user, 'dislocation_columns', None)
if custom:
return normalize_columns(custom)
from apps.locations.models import DislocationColumnPreset
dept_id = getattr(user, 'department_id', None)
if dept_id:
preset = (
DislocationColumnPreset.objects
.filter(department_id=dept_id)
.order_by('id')
.first()
)
if preset and preset.columns:
return normalize_columns(preset.columns)
preset = DislocationColumnPreset.objects.filter(is_default=True).first()
if preset and preset.columns:
return normalize_columns(preset.columns)
return list(STANDARD_COLUMNS)