using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Json; using System.Threading.Tasks; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Sozsoft.Notifications.Entities; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories; namespace Sozsoft.Platform.Data.Seeds; /// /// Bildirim tipleri ve varsayilan kurallari kiraci kapsamindadir: her kiraci kendi turunu ve /// kuralini duzenler. Seed dosyalari varsayilan kumeyi tanimlar; host ve kendi veritabani olan /// kiraci onu dosyadan alir, bu contributor da host veritabanini paylasan yeni kiraciya o kumenin /// bir kopyasini uretir. /// /// Kopya satirlar yeni kimliklerle yazilir; dosyadaki kimlik host kaydinindir ve tum kiracilarda /// tekrar edilemez. Eslesme ad uzerinden yapilir, bu yuzden ayni kiraci icin ikinci kez /// calistirildiginda hicbir sey eklenmez. /// /// public class NotificationTenantDefaultsSeedContributor( IRepository notificationTypeRepository, IRepository notificationRuleRepository, IConfiguration configuration, ILogger logger) : IDataSeedContributor, ITransientDependency { private const string TypesFile = "App.Notifications.NotificationTypes"; private const string RulesFile = "App.Notifications.NotificationRules"; public async Task SeedAsync(DataSeedContext context) { // Seed dosyalarinin uygulandigi veritabani (host ve kendi veritabani olan kiraci) bu satirlari // ListFormSeedDataApplier ile alir; burada yalnizca host veritabanini paylasan kiracinin kopyasi // uretilir. Iki yol birden calissaydi ayri veritabanli kiracida tipler iki kez yazilirdi. if (SeedFileScope.IsEnabled(context)) { return; } var types = ReadRows(TypesFile); if (types.Count == 0) { return; } var typeIdByFileId = new Dictionary(StringComparer.OrdinalIgnoreCase); var existingTypes = await notificationTypeRepository.GetListAsync(); foreach (var row in types) { var name = GetString(row, "Name"); if (name.IsNullOrWhiteSpace()) { continue; } var existing = existingTypes.Find(type => type.Name == name); if (existing == null) { existing = await notificationTypeRepository.InsertAsync( new NotificationType() { TenantId = context.TenantId, Name = name!, Description = GetString(row, "Description"), }, autoSave: true); } var fileId = GetString(row, "Id"); if (!fileId.IsNullOrWhiteSpace()) { typeIdByFileId[fileId!] = existing.Id; } } var existingRules = await notificationRuleRepository.GetListAsync(); foreach (var row in ReadRows(RulesFile)) { var fileTypeId = GetString(row, "NotificationTypeId"); if (fileTypeId == null || !typeIdByFileId.TryGetValue(fileTypeId, out var typeId)) { continue; } var recipientType = GetString(row, "RecipientType"); var recipientId = GetString(row, "RecipientId"); var channel = GetString(row, "Channel"); var duplicate = existingRules.Exists(rule => rule.NotificationTypeId == typeId && rule.RecipientType == recipientType && rule.RecipientId == recipientId && rule.Channel == channel); if (duplicate) { continue; } await notificationRuleRepository.InsertAsync( new NotificationRule() { TenantId = context.TenantId, NotificationTypeId = typeId, RecipientType = recipientType!, RecipientId = recipientId, Channel = channel!, IsActive = GetBool(row, "IsActive"), IsFixed = GetBool(row, "IsFixed"), IsCustomized = GetBool(row, "IsCustomized"), }, autoSave: true); } } /// /// Varsayilan kumeyi veri seed dosyasindan okur; ikinci bir varsayilan /// listesi kodda tutulmaz. Dosya yoksa kiraci bos baslar, bu bir hata degildir. /// private List ReadRows(string listFormCode) { var path = SeedPathResolver.GetPath( configuration, SeedPathResolver.GetDataFilePath(listFormCode).Split('/')); if (!File.Exists(path)) { logger.LogInformation("Notification defaults file not found, skipping: {Path}", path); return []; } using var document = JsonDocument.Parse(File.ReadAllText(path)); return document.RootElement.TryGetProperty("Rows", out var rows) && rows.ValueKind == JsonValueKind.Array ? [.. rows.EnumerateArray().Select(row => row.Clone())] : []; } private static string? GetString(JsonElement row, string propertyName) { return row.TryGetProperty(propertyName, out var value) && value.ValueKind == JsonValueKind.String ? value.GetString() : null; } private static bool GetBool(JsonElement row, string propertyName) { return row.TryGetProperty(propertyName, out var value) && value.ValueKind == JsonValueKind.True; } }