|  |  | 1 |  | using LGDXRobotCloud.API.Exceptions; | 
|  |  | 2 |  | using LGDXRobotCloud.API.Services.Administration; | 
|  |  | 3 |  | using LGDXRobotCloud.Data.DbContexts; | 
|  |  | 4 |  | using LGDXRobotCloud.Data.Entities; | 
|  |  | 5 |  | using LGDXRobotCloud.Data.Models.Business.Administration; | 
|  |  | 6 |  | using LGDXRobotCloud.Data.Models.Business.Navigation; | 
|  |  | 7 |  | using LGDXRobotCloud.Utilities.Enums; | 
|  |  | 8 |  | using LGDXRobotCloud.Utilities.Helpers; | 
|  |  | 9 |  | using Microsoft.EntityFrameworkCore; | 
|  |  | 10 |  |  | 
|  |  | 11 |  | namespace LGDXRobotCloud.API.Services.Navigation; | 
|  |  | 12 |  |  | 
|  |  | 13 |  | public interface IRealmService | 
|  |  | 14 |  | { | 
|  |  | 15 |  |   Task<(IEnumerable<RealmListBusinessModel>, PaginationHelper)> GetRealmsAsync(string? name, int pageNumber, int pageSiz | 
|  |  | 16 |  |   Task<RealmBusinessModel> GetRealmAsync(int id); | 
|  |  | 17 |  |   Task<RealmBusinessModel> GetDefaultRealmAsync(); | 
|  |  | 18 |  |   Task<RealmBusinessModel> CreateRealmAsync(RealmCreateBusinessModel createModel); | 
|  |  | 19 |  |   Task<bool> UpdateRealmAsync(int id, RealmUpdateBusinessModel updateModel); | 
|  |  | 20 |  |   Task<bool> UpdateRealmMapAsync(int id, RealmMapUpdateBusinessModel updateModel); | 
|  |  | 21 |  |   Task<bool> TestDeleteRealmAsync(int id); | 
|  |  | 22 |  |   Task<bool> DeleteRealmAsync(int id); | 
|  |  | 23 |  |  | 
|  |  | 24 |  |   Task<IEnumerable<RealmSearchBusinessModel>> SearchRealmsAsync(string? name); | 
|  |  | 25 |  | } | 
|  |  | 26 |  |  | 
|  | 16 | 27 |  | public class RealmService( | 
|  | 16 | 28 |  |     IActivityLogService activityLogService, | 
|  | 16 | 29 |  |     LgdxContext context | 
|  | 16 | 30 |  |   ) : IRealmService | 
|  |  | 31 |  | { | 
|  | 16 | 32 |  |   private readonly IActivityLogService _activityLogService = activityLogService ?? throw new ArgumentNullException(nameo | 
|  | 16 | 33 |  |   private readonly LgdxContext _context = context ?? throw new ArgumentNullException(nameof(context)); | 
|  |  | 34 |  |  | 
|  |  | 35 |  |   public async Task<(IEnumerable<RealmListBusinessModel>, PaginationHelper)> GetRealmsAsync(string? name, int pageNumber | 
|  | 4 | 36 |  |   { | 
|  | 4 | 37 |  |     var query = _context.Realms as IQueryable<Realm>; | 
|  | 4 | 38 |  |     if (!string.IsNullOrWhiteSpace(name)) | 
|  | 3 | 39 |  |     { | 
|  | 3 | 40 |  |       name = name.Trim(); | 
|  | 3 | 41 |  |       query = query.Where(m => m.Name.ToLower().Contains(name.ToLower())); | 
|  | 3 | 42 |  |     } | 
|  | 4 | 43 |  |     var itemCount = await query.CountAsync(); | 
|  | 4 | 44 |  |     var PaginationHelper = new PaginationHelper(itemCount, pageNumber, pageSize); | 
|  | 4 | 45 |  |     var realms = await query.AsNoTracking() | 
|  | 4 | 46 |  |       .OrderBy(m => m.Id) | 
|  | 4 | 47 |  |       .Skip(pageSize * (pageNumber - 1)) | 
|  | 4 | 48 |  |       .Take(pageSize) | 
|  | 4 | 49 |  |       .Select(m => new RealmListBusinessModel { | 
|  | 4 | 50 |  |         Id = m.Id, | 
|  | 4 | 51 |  |         Name = m.Name, | 
|  | 4 | 52 |  |         Description = m.Description, | 
|  | 4 | 53 |  |         Resolution = m.Resolution, | 
|  | 4 | 54 |  |       }) | 
|  | 4 | 55 |  |       .ToListAsync(); | 
|  | 4 | 56 |  |     return (realms, PaginationHelper); | 
|  | 4 | 57 |  |   } | 
|  |  | 58 |  |  | 
|  |  | 59 |  |   public async Task<RealmBusinessModel> GetRealmAsync(int id) | 
|  | 2 | 60 |  |   { | 
|  | 2 | 61 |  |     return await _context.Realms.AsNoTracking() | 
|  | 2 | 62 |  |       .Where(m => m.Id == id) | 
|  | 2 | 63 |  |       .Select(m => new RealmBusinessModel { | 
|  | 2 | 64 |  |         Id = m.Id, | 
|  | 2 | 65 |  |         Name = m.Name, | 
|  | 2 | 66 |  |         Description = m.Description, | 
|  | 2 | 67 |  |         HasWaypointsTrafficControl = m.HasWaypointsTrafficControl, | 
|  | 2 | 68 |  |         Image = Convert.ToBase64String(m.Image), | 
|  | 2 | 69 |  |         Resolution = m.Resolution, | 
|  | 2 | 70 |  |         OriginX = m.OriginX, | 
|  | 2 | 71 |  |         OriginY = m.OriginY, | 
|  | 2 | 72 |  |         OriginRotation = m.OriginRotation, | 
|  | 2 | 73 |  |       }) | 
|  | 2 | 74 |  |       .FirstOrDefaultAsync() | 
|  | 2 | 75 |  |         ?? throw new LgdxNotFound404Exception(); | 
|  | 1 | 76 |  |   } | 
|  |  | 77 |  |  | 
|  |  | 78 |  |   public async Task<RealmBusinessModel> GetDefaultRealmAsync() | 
|  | 1 | 79 |  |   { | 
|  | 1 | 80 |  |     return await _context.Realms.AsNoTracking() | 
|  | 1 | 81 |  |       .OrderBy(m => m.Id) | 
|  | 1 | 82 |  |       .Select(m => new RealmBusinessModel { | 
|  | 1 | 83 |  |         Id = m.Id, | 
|  | 1 | 84 |  |         Name = m.Name, | 
|  | 1 | 85 |  |         Description = m.Description, | 
|  | 1 | 86 |  |         HasWaypointsTrafficControl = m.HasWaypointsTrafficControl, | 
|  | 1 | 87 |  |         Image = Convert.ToBase64String(m.Image), | 
|  | 1 | 88 |  |         Resolution = m.Resolution, | 
|  | 1 | 89 |  |         OriginX = m.OriginX, | 
|  | 1 | 90 |  |         OriginY = m.OriginY, | 
|  | 1 | 91 |  |         OriginRotation = m.OriginRotation, | 
|  | 1 | 92 |  |       }) | 
|  | 1 | 93 |  |       .FirstOrDefaultAsync() | 
|  | 1 | 94 |  |         ?? throw new LgdxNotFound404Exception(); | 
|  | 1 | 95 |  |   } | 
|  |  | 96 |  |  | 
|  |  | 97 |  |   public async Task<RealmBusinessModel> CreateRealmAsync(RealmCreateBusinessModel createModel) | 
|  | 1 | 98 |  |   { | 
|  | 1 | 99 |  |     var realm = new Realm { | 
|  | 1 | 100 |  |       Name = createModel.Name, | 
|  | 1 | 101 |  |       Description = createModel.Description, | 
|  | 1 | 102 |  |       HasWaypointsTrafficControl = createModel.HasWaypointsTrafficControl, | 
|  | 1 | 103 |  |       Image = Convert.FromBase64String(createModel.Image ?? string.Empty), | 
|  | 1 | 104 |  |       Resolution = createModel.Resolution, | 
|  | 1 | 105 |  |       OriginX = createModel.OriginX, | 
|  | 1 | 106 |  |       OriginY = createModel.OriginY, | 
|  | 1 | 107 |  |       OriginRotation = createModel.OriginRotation, | 
|  | 1 | 108 |  |     }; | 
|  |  | 109 |  |  | 
|  | 1 | 110 |  |     await _context.Realms.AddAsync(realm); | 
|  | 1 | 111 |  |     await _context.SaveChangesAsync(); | 
|  |  | 112 |  |  | 
|  | 1 | 113 |  |     await _activityLogService.CreateActivityLogAsync(new ActivityLogCreateBusinessModel | 
|  | 1 | 114 |  |     { | 
|  | 1 | 115 |  |       EntityName = nameof(Realm), | 
|  | 1 | 116 |  |       EntityId = realm.Id.ToString(), | 
|  | 1 | 117 |  |       Action = ActivityAction.Create, | 
|  | 1 | 118 |  |     }); | 
|  |  | 119 |  |  | 
|  | 1 | 120 |  |     return new RealmBusinessModel | 
|  | 1 | 121 |  |     { | 
|  | 1 | 122 |  |       Id = realm.Id, | 
|  | 1 | 123 |  |       Name = realm.Name, | 
|  | 1 | 124 |  |       Description = realm.Description, | 
|  | 1 | 125 |  |       HasWaypointsTrafficControl = realm.HasWaypointsTrafficControl, | 
|  | 1 | 126 |  |       Image = createModel.Image ?? string.Empty, | 
|  | 1 | 127 |  |       Resolution = realm.Resolution, | 
|  | 1 | 128 |  |       OriginX = realm.OriginX, | 
|  | 1 | 129 |  |       OriginY = realm.OriginY, | 
|  | 1 | 130 |  |       OriginRotation = realm.OriginRotation, | 
|  | 1 | 131 |  |     }; | 
|  | 1 | 132 |  |   } | 
|  |  | 133 |  |  | 
|  |  | 134 |  |   public async Task<bool> UpdateRealmAsync(int id, RealmUpdateBusinessModel updateModel) | 
|  | 0 | 135 |  |   { | 
|  | 0 | 136 |  |     bool result = await _context.Realms | 
|  | 0 | 137 |  |       .Where(m => m.Id == id) | 
|  | 0 | 138 |  |       .ExecuteUpdateAsync(setters => setters | 
|  | 0 | 139 |  |         .SetProperty(m => m.Name, updateModel.Name) | 
|  | 0 | 140 |  |         .SetProperty(m => m.Description, updateModel.Description) | 
|  | 0 | 141 |  |         .SetProperty(m => m.HasWaypointsTrafficControl, updateModel.HasWaypointsTrafficControl) | 
|  | 0 | 142 |  |         .SetProperty(m => m.Image, Convert.FromBase64String(updateModel.Image ?? string.Empty)) | 
|  | 0 | 143 |  |         .SetProperty(m => m.Resolution, updateModel.Resolution) | 
|  | 0 | 144 |  |         .SetProperty(m => m.OriginX, updateModel.OriginX) | 
|  | 0 | 145 |  |         .SetProperty(m => m.OriginY, updateModel.OriginY) | 
|  | 0 | 146 |  |         .SetProperty(m => m.OriginRotation, updateModel.OriginRotation) | 
|  | 0 | 147 |  |       ) == 1; | 
|  |  | 148 |  |  | 
|  | 0 | 149 |  |     if (result) | 
|  | 0 | 150 |  |     { | 
|  | 0 | 151 |  |       await _activityLogService.CreateActivityLogAsync(new ActivityLogCreateBusinessModel | 
|  | 0 | 152 |  |       { | 
|  | 0 | 153 |  |         EntityName = nameof(Realm), | 
|  | 0 | 154 |  |         EntityId = id.ToString(), | 
|  | 0 | 155 |  |         Action = ActivityAction.Update, | 
|  | 0 | 156 |  |       }); | 
|  | 0 | 157 |  |     } | 
|  | 0 | 158 |  |     return result; | 
|  | 0 | 159 |  |   } | 
|  |  | 160 |  |  | 
|  |  | 161 |  |   public async Task<bool> UpdateRealmMapAsync(int id, RealmMapUpdateBusinessModel updateModel) | 
|  | 0 | 162 |  |   { | 
|  | 0 | 163 |  |     bool result = await _context.Realms | 
|  | 0 | 164 |  |       .Where(m => m.Id == id) | 
|  | 0 | 165 |  |       .ExecuteUpdateAsync(setters => setters | 
|  | 0 | 166 |  |         .SetProperty(m => m.Image, Convert.FromBase64String(updateModel.Image)) | 
|  | 0 | 167 |  |         .SetProperty(m => m.Resolution, updateModel.Resolution) | 
|  | 0 | 168 |  |         .SetProperty(m => m.OriginX, updateModel.OriginX) | 
|  | 0 | 169 |  |         .SetProperty(m => m.OriginY, updateModel.OriginY) | 
|  | 0 | 170 |  |         .SetProperty(m => m.OriginRotation, updateModel.OriginRotation) | 
|  | 0 | 171 |  |       ) == 1; | 
|  |  | 172 |  |  | 
|  | 0 | 173 |  |     if (result) | 
|  | 0 | 174 |  |     { | 
|  | 0 | 175 |  |       await _activityLogService.CreateActivityLogAsync(new ActivityLogCreateBusinessModel | 
|  | 0 | 176 |  |       { | 
|  | 0 | 177 |  |         EntityName = nameof(Realm), | 
|  | 0 | 178 |  |         EntityId = id.ToString(), | 
|  | 0 | 179 |  |         Action = ActivityAction.Update, | 
|  | 0 | 180 |  |       }); | 
|  | 0 | 181 |  |     } | 
|  | 0 | 182 |  |     return result; | 
|  | 0 | 183 |  |   } | 
|  |  | 184 |  |  | 
|  |  | 185 |  |   public async Task<bool> TestDeleteRealmAsync(int id) | 
|  | 4 | 186 |  |   { | 
|  | 4 | 187 |  |     var dependencies = await _context.Robots.Where(m => m.RealmId == id).CountAsync(); | 
|  | 4 | 188 |  |     if (dependencies > 0) | 
|  | 1 | 189 |  |     { | 
|  | 1 | 190 |  |       throw new LgdxValidation400Expection(nameof(id), $"This realm has been used by {dependencies} robots."); | 
|  |  | 191 |  |     } | 
|  | 3 | 192 |  |     dependencies = await _context.Waypoints.Where(m => m.RealmId == id).CountAsync(); | 
|  | 3 | 193 |  |     if (dependencies > 0) | 
|  | 1 | 194 |  |     { | 
|  | 1 | 195 |  |       throw new LgdxValidation400Expection(nameof(id), $"This realm has been used by {dependencies} waypoints."); | 
|  |  | 196 |  |     } | 
|  | 2 | 197 |  |     dependencies = await _context.AutoTasks | 
|  | 2 | 198 |  |       .Where(m => m.RealmId == id) | 
|  | 2 | 199 |  |       .Where(m => m.CurrentProgressId != (int)ProgressState.Completed && m.CurrentProgressId != (int)ProgressState.Abort | 
|  | 2 | 200 |  |       .CountAsync(); | 
|  | 2 | 201 |  |     if (dependencies > 0) | 
|  | 1 | 202 |  |     { | 
|  | 1 | 203 |  |       throw new LgdxValidation400Expection(nameof(id), $"This realm has been used by {dependencies} running/waiting/temp | 
|  |  | 204 |  |     } | 
|  | 1 | 205 |  |     return true; | 
|  | 1 | 206 |  |   } | 
|  |  | 207 |  |  | 
|  |  | 208 |  |   public async Task<bool> DeleteRealmAsync(int id) | 
|  | 0 | 209 |  |   { | 
|  | 0 | 210 |  |     bool result = await _context.Realms.Where(m => m.Id == id) | 
|  | 0 | 211 |  |       .ExecuteDeleteAsync() == 1; | 
|  |  | 212 |  |  | 
|  | 0 | 213 |  |     if (result) | 
|  | 0 | 214 |  |     { | 
|  | 0 | 215 |  |       await _activityLogService.CreateActivityLogAsync(new ActivityLogCreateBusinessModel | 
|  | 0 | 216 |  |       { | 
|  | 0 | 217 |  |         EntityName = nameof(Realm), | 
|  | 0 | 218 |  |         EntityId = id.ToString(), | 
|  | 0 | 219 |  |         Action = ActivityAction.Delete, | 
|  | 0 | 220 |  |       }); | 
|  | 0 | 221 |  |     } | 
|  | 0 | 222 |  |     return result; | 
|  | 0 | 223 |  |   } | 
|  |  | 224 |  |  | 
|  |  | 225 |  |   public async Task<IEnumerable<RealmSearchBusinessModel>> SearchRealmsAsync(string? name) | 
|  | 4 | 226 |  |   { | 
|  | 4 | 227 |  |     var n = name ?? string.Empty; | 
|  | 4 | 228 |  |     return await _context.Realms.AsNoTracking() | 
|  | 4 | 229 |  |       .Where(w => w.Name.ToLower().Contains(n.ToLower())) | 
|  | 4 | 230 |  |       .Take(10) | 
|  | 4 | 231 |  |       .Select(m => new RealmSearchBusinessModel { | 
|  | 4 | 232 |  |         Id = m.Id, | 
|  | 4 | 233 |  |         Name = m.Name, | 
|  | 4 | 234 |  |       }) | 
|  | 4 | 235 |  |       .ToListAsync(); | 
|  | 4 | 236 |  |   } | 
|  |  | 237 |  | } |