namespace foodmarket.Domain.Organizations; /// Набор флагов разрешений роли. Хранится JSON-колонкой /// (owned by EmployeeRole). Семантика: false = доступ запрещён. public class RolePermissions { // Каталог public bool ProductsView { get; set; } public bool ProductsEdit { get; set; } public bool ProductsDelete { get; set; } public bool ProductGroupsManage { get; set; } public bool PriceTypesManage { get; set; } public bool UnitsManage { get; set; } // Закупки public bool SuppliesView { get; set; } public bool SuppliesEdit { get; set; } public bool SuppliesPost { get; set; } public bool SuppliesDelete { get; set; } // Продажи (отгрузка контрагенту + POS) public bool DemandsView { get; set; } public bool DemandsEdit { get; set; } public bool DemandsPost { get; set; } public bool RetailSalesOperate { get; set; } public bool RetailSalesRefund { get; set; } // Контрагенты public bool CounterpartiesView { get; set; } public bool CounterpartiesEdit { get; set; } public bool CounterpartiesDelete { get; set; } // Склад / Остатки public bool StocksView { get; set; } public bool InventoryEdit { get; set; } public bool LossEdit { get; set; } public bool EnterEdit { get; set; } public bool TransferEdit { get; set; } // Отчёты public bool ReportsView { get; set; } public bool ReportsFinanceView { get; set; } public bool ReportsStockView { get; set; } // Настройки организации public bool OrgSettingsManage { get; set; } public bool EmployeesManage { get; set; } public bool RolesManage { get; set; } public bool StoresManage { get; set; } public bool RetailPointsManage { get; set; } public bool CashRegistersManage { get; set; } public bool IntegrationsManage { get; set; } // Sprint 9: лояльность и акции (Admin-only по умолчанию). public bool LoyaltyManage { get; set; } public bool PromotionsManage { get; set; } // Sprint 33 (модуль «Деньги»): // MoneyView — видеть счета, движения, отчёт «Деньги», долги. // Кассир — да (видит выручку своей смены); Кладовщик — только через SuppliesView, // увидит оплаченность приёмки, но не остатки по счетам. // MoneyEdit — создавать/редактировать платежи, ордера, переводы, // счета, статьи расходов, корректировки взаиморасчётов. // Admin-only по умолчанию. // CashShiftOperate — открыть/закрыть смену, вносить/выплачивать деньги // в своей смене. Кассир — да. public bool MoneyView { get; set; } public bool MoneyEdit { get; set; } public bool CashShiftOperate { get; set; } /// Права, доступные только в расширенном режиме организации /// (в простом режиме скрыты и на сервере, и в UI). Единый источник правды, /// зеркалит контроллеры с [RequiresAdvancedMode]: Оптовые отгрузки, /// Перемещения, Лояльность, Акции, Типы цен. public static readonly IReadOnlySet AdvancedOnly = new HashSet(StringComparer.Ordinal) { nameof(DemandsView), nameof(DemandsEdit), nameof(DemandsPost), nameof(TransferEdit), nameof(LoyaltyManage), nameof(PromotionsManage), nameof(PriceTypesManage), }; /// Все bool-флаги прав в виде словаря имя→значение (через рефлексию). public Dictionary ToDictionary() { var dict = new Dictionary(StringComparer.Ordinal); foreach (var p in typeof(RolePermissions).GetProperties()) if (p.PropertyType == typeof(bool) && p.CanRead) dict[p.Name] = (bool)p.GetValue(this)!; return dict; } /// Эффективные права текущего пользователя для клиента (моб./веб): /// SuperAdmin — всё без ограничений; Admin — всё, но в простом режиме /// advanced-only скрыты; обычная роль — её флаги, в простом режиме с /// обнулением advanced-only. Единый источник, чтобы клиенты скрывали одно и то же. public static Dictionary Effective(RolePermissions? role, bool isSuperAdmin, bool isAdmin, bool advancedMode) { var basePerms = (isSuperAdmin || isAdmin) ? All() : (role ?? new RolePermissions()); var dict = basePerms.ToDictionary(); // SuperAdmin обходит гейт расширенного режима; остальным в простом режиме // advanced-only права выключаем. if (!isSuperAdmin && !advancedMode) foreach (var name in AdvancedOnly) dict[name] = false; return dict; } /// Полный набор всех true — для системной роли «Администратор». public static RolePermissions All() => new() { ProductsView = true, ProductsEdit = true, ProductsDelete = true, ProductGroupsManage = true, PriceTypesManage = true, UnitsManage = true, SuppliesView = true, SuppliesEdit = true, SuppliesPost = true, SuppliesDelete = true, DemandsView = true, DemandsEdit = true, DemandsPost = true, RetailSalesOperate = true, RetailSalesRefund = true, CounterpartiesView = true, CounterpartiesEdit = true, CounterpartiesDelete = true, StocksView = true, InventoryEdit = true, LossEdit = true, EnterEdit = true, TransferEdit = true, ReportsView = true, ReportsFinanceView = true, ReportsStockView = true, OrgSettingsManage = true, EmployeesManage = true, RolesManage = true, StoresManage = true, RetailPointsManage = true, CashRegistersManage = true, IntegrationsManage = true, LoyaltyManage = true, PromotionsManage = true, MoneyView = true, MoneyEdit = true, CashShiftOperate = true, }; }