· 6 years ago · Oct 16, 2019, 10:04 AM
1using AdminDatabaseLayer.Common;
2using AdminDatabaseLayer.Model;
3using log4net;
4using Skygd.AdminAPI.Data;
5using Skygd.AdminAPI.Enums;
6using Skygd.AdminAPI.Helpers;
7using Skygd.AdminAPI.Models;
8using Skygd.CommonLogicLayer.Enums;
9using Swashbuckle.Swagger.Annotations;
10using System;
11using System.Collections.Generic;
12using System.Linq;
13using System.Net;
14using System.Net.Http;
15using System.Security.Claims;
16using System.Web.Http;
17
18namespace Skygd.AdminAPI.Controllers
19{
20 public class AlarmsController : ApiController
21 {
22 private static readonly ILog log = LogManager.GetLogger(typeof(AlarmsController));
23
24 private int[] notAllwoedSingleFlagsForAlarmCodeRule = new int[] { 13 };
25
26 /// <summary>
27 /// Retrieve pagenated list of alarms (Entity Framework)
28 /// </summary>
29 /// <remarks>Returns pagenated list of alarms by search criteria (backed by Entity Framework)</remarks>
30 [Authorize(Roles = "Alarms")]
31 public List<AlarmMeta> Get([Swaggerify(typeof(GetAlarmsModel)), FromUri]GetAlarmsModel uriParams)
32 {
33 using (IUoW unitOfWork = new UoW(true))
34 {
35 uriParams = uriParams ?? new GetAlarmsModel();
36 uriParams.q = uriParams.q.PartialXss();
37 return AlarmManager.GetAlarms(unitOfWork, uriParams.page, uriParams.pageSize, uriParams.q, uriParams.o, uriParams.user, uriParams.customers, uriParams.start, uriParams.end);
38 }
39 }
40
41 /// <summary>
42 /// Retrieve list of available alarm query filter options.
43 /// </summary>
44 /// <returns>json list</returns>
45 [SwaggerExternalDoc]
46 [Route("api/alarms/filters"), Authorize(Roles = "Users"), HttpGet]
47 public HttpResponseMessage GetAlarmFilters()
48 {
49 //return APIResponse.Generate( Request, HttpStatusCode.OK, ElasticSearchModels.AlarmQueryFilters );
50
51 using (IUoW unitOfWork = new UoW(true))
52 {
53 Admin admin = AdminManager.GetCurrentAdmin(unitOfWork);
54 if (admin == null)
55 {
56 return APIResponse.Generate(Request, HttpStatusCode.Forbidden, "");
57 }
58
59 if (!ClaimsPrincipal.Current.IsInRole("SearchFilterSeller"))
60 {
61 List<ElasticSearchModels.QueryFilterMeta> alarmQueryFilterResults = new List<ElasticSearchModels.QueryFilterMeta>();
62
63 foreach (var filter in ElasticSearchModels.AlarmQueryFilters)
64 {
65 if (filter.Name == "Seller")
66 {
67 // do nothing
68 }
69 else
70 {
71 alarmQueryFilterResults.Add(filter);
72 }
73 }
74 return APIResponse.Generate(Request, HttpStatusCode.OK, alarmQueryFilterResults);
75 }
76
77 return APIResponse.Generate(Request, HttpStatusCode.OK, ElasticSearchModels.AlarmQueryFilters);
78 }
79 }
80
81 /// <summary>
82 /// Retrieve pagenated list of alarms
83 /// </summary>
84 /// <remarks>Returns pagenated list of alarms by search criteria.
85 /// This is used on the <a href="https://admin2.skygd.net/#alarms">https://admin2.skygd.net/#alarms</a>
86 /// </remarks>
87 [SwaggerExternalDoc]
88 [Route("api/alarms/search"), Authorize(Roles = "Alarms"), HttpGet]
89 public ElasticSearchModels.AlarmSearchResult Search([Swaggerify(typeof(GetAlarmsSearchModel)), FromUri]GetAlarmsSearchModel uriParams)
90 {
91 using (IUoW unitOfWork = new UoW(true))
92 {
93 uriParams = uriParams ?? new GetAlarmsSearchModel();
94 uriParams.q = uriParams.q.PartialXss();
95 uriParams.alarmtext = uriParams.alarmtext.PartialXss();
96 if (uriParams.q != null)
97 {
98 uriParams.q = uriParams.q.ToLowerInvariant();
99 }
100 if (uriParams.alarmtext != null)
101 {
102 uriParams.alarmtext = uriParams.alarmtext.ToLowerInvariant();
103 }
104
105 var userIds = uriParams.user.HasValue ? new List<int> { uriParams.user.Value } : new List<int>();
106 int pageSize = uriParams.pageSize > 500 ? 500 : uriParams.pageSize;
107 List<string> searchFilters = ElasticSearchHelper.CreateSearchFilters(uriParams);
108 return AlarmManager.AlarmSearch(unitOfWork, uriParams.page, pageSize, uriParams.q, uriParams.o, userIds, uriParams.customers, uriParams.alarmtext, uriParams.start.ToDateTimeUtc(), uriParams.end.ToDateTimeUtc(), uriParams.exact, uriParams.alarmcodes, null, uriParams.nameonly, uriParams.hideautodeactivated, null, null, searchFilters);
109 }
110 }
111
112
113 /// <summary>
114 /// Get an alarm event with details
115 /// </summary>
116 /// <param name="id">ID of alarm</param>
117 [SwaggerExternalDoc]
118 [Route("api/alarms/{id:int}/"), Authorize(Roles = "AlarmDetails")]
119 public AlarmDetails Get(int id)
120 {
121 using (IUoW unitOfWork = new UoW(true))
122 {
123 return AlarmManager.GetAlarm(unitOfWork, id);
124 }
125 }
126
127 /// <summary>
128 /// Get alarm classification
129 /// </summary>
130 /// <param name="id">alarm id</param>
131 [SwaggerResponseRemoveDefaults]
132 [SwaggerResponse(HttpStatusCode.OK, Type = typeof(AlarmClassification), Description = "{ data: {Model}, errors: [] }")]
133 [SwaggerResponse(HttpStatusCode.NotAcceptable, Description = SwaggerConfig.DESCRIPTION_ERROR_LIST)]
134 [Route("api/alarms/{id:int}/classification"), Authorize(Roles = "AlarmClassification"), HttpGet]
135 public HttpResponseMessage GetClassification(int id)
136 {
137 using (IUoW unitOfWork = new UoW())
138 {
139 var validationErrors = new List<dynamic>();
140
141 Alarm alarm = AlarmManager.GetAlarmEntry(unitOfWork, id);
142 if (alarm == null)
143 {
144 validationErrors.Add(ErrorsRepo.AlarmNotFound);
145 throw new HttpResponseException(HttpStatusCode.NotFound);
146 }
147 if (validationErrors.Any())
148 {
149 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, validationErrors);
150 }
151
152 // EXERCISE
153
154 if (alarm.CanHaveClassification())
155 {
156 var tf = unitOfWork.TriggerFlagRepo().Get(t => t.TriggerIdentifier == alarm.TriggerIdentifier).FirstOrDefault();
157
158 var ac = new AlarmClassification
159 {
160 PossibleToClassify = true,
161 TriggerIdentifier = alarm.TriggerIdentifier,
162 CurrentClassification = null,
163 Comment = "",
164 AvailableClassifications = new List<List<int>>()
165 };
166
167 int product = alarm.User.Product;
168
169 if (alarm.Transmitter != null && alarm.Transmitter.Product != null)
170 {
171 product = (int)alarm.Transmitter.Product;
172 }
173
174
175 ac.AvailableClassifications.Add(new List<int>() { }); //No classification = remove classification
176
177 switch (product)
178 {
179 case ProductTypeEnum.PRODUCT_DORO211:
180 //These refers to flags defined in AlarmLogicLayer.Enums.AlarmFlagEnum
181 ac.AvailableClassifications.Add(new List<int>() { 200, 13 }); //Door + No voice
182 ac.AvailableClassifications.Add(new List<int>() { 200 }); //Door
183 ac.AvailableClassifications.Add(new List<int>() { 201, 13 }); //Carpet + No voice
184 ac.AvailableClassifications.Add(new List<int>() { 200 }); //Carpet
185
186 break;
187
188 case ProductTypeEnum.PRODUCT_VISER:
189 case ProductTypeEnum.PRODUCT_VISER_POE:
190 ac.AvailableClassifications.Add(new List<int>() { 206 }); //Bed
191 ac.AvailableClassifications.Add(new List<int>() { 208 }); //Toilett
192 ac.AvailableClassifications.Add(new List<int>() { 209 }); //Elevator
193 ac.AvailableClassifications.Add(new List<int>() { 211 }); //Entrance door
194 ac.AvailableClassifications.Add(new List<int>() { 212 }); //Aparment door
195 ac.AvailableClassifications.Add(new List<int>() { 213 }); //Ward door
196 ac.AvailableClassifications.Add(new List<int>() { 214 }); //Basement door
197 ac.AvailableClassifications.Add(new List<int>() { 217 }); //Balcony door
198 ac.AvailableClassifications.Add(new List<int>() { 215 }); //Emergency exit
199 ac.AvailableClassifications.Add(new List<int>() { 216 }); //Door bell
200 ac.AvailableClassifications.Add(new List<int>() { 218 }); //Gate
201 ac.AvailableClassifications.Add(new List<int>() { 33 }); //Carer present
202 ac.AvailableClassifications.Add(new List<int>() { 34 }); //Carer emergency
203 ac.AvailableClassifications.Add(new List<int>() { 35 }); //Carer request assistans
204 ac.AvailableClassifications.Add(new List<int>() { 207 }); //Movement
205 ac.AvailableClassifications.Add(new List<int>() { 40 }); //Firealarm
206 ac.AvailableClassifications.Add(new List<int>() { 37 }); //Personal alarm
207 break;
208 }
209
210
211 if (tf != null)
212 {
213 //There are currently a TriggerFlag (classification configured)
214 ac.CurrentClassification = string.IsNullOrEmpty(tf.Flags) ? null : tf.Flags.Split(',').Select(int.Parse).ToList();
215 ac.Comment = tf.Comment;
216
217 //Todo
218 //Make sure that ac.AvailableClassifications contains the currentClassification (if modified in database and are not among the ones above)
219 }
220 return APIResponse.Success(Request, ac);
221 }
222
223 return APIResponse.Success(Request, new AlarmClassification { PossibleToClassify = false });
224 }
225 }
226
227
228 /// <summary>
229 /// Create/change/delete alarm classification
230 /// </summary>
231 /// <remarks>
232 /// Creates and stores classification data if the alarm has no trigger flag.
233 /// Changes classification data if trigger flag of the alarm exists and non empty Classification array provided.
234 /// Deletes trigger flag if an empty Classification array provided.
235 /// </remarks>
236 /// <param name="model"></param>
237 /// <param name="id">alarm id</param>
238 [SwaggerResponseRemoveDefaults]
239 [SwaggerResponse(HttpStatusCode.Accepted, Description = "{ data: null, errors: null }")]
240 [SwaggerResponse(HttpStatusCode.NotAcceptable, Description = SwaggerConfig.DESCRIPTION_ERROR_LIST)]
241 [Route("api/alarms/{id:int}/classification"), Authorize(Roles = "AlarmClassification"), HttpPut]
242 public HttpResponseMessage PutClassification([FromBody]AlarmClassificationSave model, int id)
243 {
244 using (IUoW unitOfWork = new UoW())
245 {
246 var validationErrors = new List<dynamic>();
247
248 // VALIDATION
249 Alarm alarm = AlarmManager.GetAlarmEntry(unitOfWork, id);
250 if (alarm == null)
251 {
252 validationErrors.Add(ErrorsRepo.AlarmNotFound);
253 }
254 if (!alarm.CanHaveClassification())
255 {
256 validationErrors.Add(ErrorsRepo.CannotHaveClassification);
257 }
258 if (validationErrors.Any())
259 {
260 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, validationErrors);
261 }
262
263 // EXERCISE
264 string deletedTriggerIdentifier = null;
265
266 var tf = unitOfWork.TriggerFlagRepo().Get(t => t.TriggerIdentifier == alarm.TriggerIdentifier).FirstOrDefault();
267
268 if (tf == null && model.Classification != null && model.Classification.Count > 0) //Create new
269 {
270 tf = new TriggerFlag()
271 {
272 Comment = model.Comment,
273 TriggerIdentifier = alarm.TriggerIdentifier,
274 Flags = string.Join(",", model.Classification)
275 };
276 unitOfWork.TriggerFlagRepo().Insert(tf);
277 }
278 else if (tf == null)
279 {
280 //There are no existing TriggerFlag entry
281 }
282 else if (model.Classification != null && model.Classification.Count == 0) //Delete existing
283 {
284 deletedTriggerIdentifier = tf.TriggerIdentifier;
285 unitOfWork.TriggerFlagRepo().Delete(tf);
286 }
287 else //Update existing
288 {
289 tf.Comment = model.Comment;
290 tf.Flags = string.Join(",", model.Classification);
291 }
292
293 //Todo error handling
294 unitOfWork.Save();
295
296 AlarmClusterManager acm = new AlarmClusterManager(unitOfWork);
297 if (deletedTriggerIdentifier == null)
298 {
299 acm.SendUpdateRequestBasedOnTriggerFlagChanged(tf);
300 }
301 else
302 {
303 acm.SendUpdateRequestBasedOnTriggerFlagDeleted(deletedTriggerIdentifier);
304 }
305
306 return APIResponse.Generate(Request, HttpStatusCode.Accepted, null);
307 }
308 }
309
310 /// <summary>
311 /// Get alarm code rule that are applicable for this alarm
312 /// </summary>
313 /// <param name="id">alarm id</param>
314 [SwaggerResponseRemoveDefaults]
315 [SwaggerResponse(HttpStatusCode.OK, Type = typeof(AlarmClassification), Description = "{ data: {Model}, errors: [] }")]
316 [SwaggerResponse(HttpStatusCode.NotAcceptable, Description = SwaggerConfig.DESCRIPTION_ERROR_LIST)]
317 [Route("api/alarms/{id:int}/alarmcoderule"), Authorize(Roles = "AlarmCodeRuleUser"), HttpGet]
318 public HttpResponseMessage GetAlarmCodeRule(int id)
319 {
320 using (IUoW unitOfWork = new UoW())
321 {
322 var validationErrors = new List<dynamic>();
323
324 Alarm alarm = AlarmManager.GetAlarmEntry(unitOfWork, id);
325
326 int[] flags = new int[] { };
327
328 if (alarm == null)
329 {
330 validationErrors.Add(ErrorsRepo.AlarmNotFound);
331 throw new HttpResponseException(HttpStatusCode.NotFound);
332 }
333 if (!string.IsNullOrEmpty(alarm.Flags))
334 {
335 flags = alarm.Flags.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(f => int.Parse(f)).ToArray();
336 }
337
338
339 if (validationErrors.Any())
340 {
341 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, validationErrors);
342 }
343
344 // EXERCISE
345
346 if (flags.Count() > 0 || (flags.Count() == 1 && !notAllwoedSingleFlagsForAlarmCodeRule.Contains(flags[0])))
347 {
348 var acr = GetUserAlarmCodeRule(unitOfWork, alarm, flags);
349
350 if (acr != null)
351 {
352 return APIResponse.Success(Request, new UserAlarmCodeRule() { Classifications = acr.Flags.Split(new char[] { ',' }).Select(f => int.Parse(f)).ToList(), CurrentAlarmCode = acr.AlarmCode, PossibleToHaveRule = true });
353 }
354 return APIResponse.Success(Request, new UserAlarmCodeRule() { Classifications = flags.ToList(), CurrentAlarmCode = null, PossibleToHaveRule = true });
355 }
356
357 return APIResponse.Success(Request, new UserAlarmCodeRule { PossibleToHaveRule = false });
358 }
359 }
360
361 /// <summary>
362 /// Create/change user alarm code rule
363 /// </summary>
364 /// <remarks>
365 /// Creates and stores alarmcoderule data if there are no trigger flag.
366 /// Changes classification data if trigger flag of the alarm exists and non empty Classification array provided.
367 /// </remarks>
368 /// <param name="model"></param>
369 /// <param name="id">alarm id</param>
370 [SwaggerResponseRemoveDefaults]
371 [SwaggerResponse(HttpStatusCode.Accepted, Description = "{ data: null, errors: null }")]
372 [SwaggerResponse(HttpStatusCode.NotAcceptable, Description = SwaggerConfig.DESCRIPTION_ERROR_LIST)]
373 [Route("api/alarms/{id:int}/alarmcoderule"), Authorize(Roles = "AlarmCodeRuleUser"), HttpPut]
374 public HttpResponseMessage PutUserAlarmCodeRule([FromBody]UserAlarmCodeRuleSave model, int id)
375 {
376 using (IUoW unitOfWork = new UoW())
377 {
378 var validationErrors = new List<dynamic>();
379
380 int[] flags = new int[] { };
381 // VALIDATION
382
383 Alarm alarm = AlarmManager.GetAlarmEntry(unitOfWork, id);
384 if (alarm == null)
385 {
386 validationErrors.Add(ErrorsRepo.AlarmNotFound);
387 }
388 if (alarm.User == null)
389 {
390 validationErrors.Add(ErrorsRepo.UserNotFound);
391 }
392
393 if (!string.IsNullOrEmpty(alarm.Flags))
394 {
395 flags = alarm.Flags.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(f => int.Parse(f)).ToArray();
396 }
397 if (flags.Count() == 0)
398 {
399 validationErrors.Add(ErrorsRepo.AttributeNotFound);
400 }
401
402 if (validationErrors.Any())
403 {
404 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, validationErrors);
405 }
406
407 // EXERCISE
408
409 log.InfoFormat("Create alarmcoderule for flags:{0} count:{1} userid:{2}", alarm.Flags, flags.Count(), alarm.UserId);
410
411 if (flags.Count() > 1 || (flags.Count() == 1 && !notAllwoedSingleFlagsForAlarmCodeRule.Contains(flags[0])))
412 {
413 var acr = GetUserAlarmCodeRule(unitOfWork, alarm, flags);
414
415 if (acr != null)
416 {
417 acr.AlarmCode = model.AlarmCode;
418 log.InfoFormat("There are already a rule with id:{0}", acr.Id);
419 }
420 else
421 {
422 unitOfWork.AlarmCodeRuleRepo().Insert(
423 new AlarmCodeRule()
424 {
425 UserId = alarm.UserId,
426 Flags = alarm.Flags,
427 Order = 1,
428 RequireAll = true,
429 Negate = false,
430 AlarmCode = model.AlarmCode,
431 EmergencyCenterId = null,
432 Protocol = null,
433 });
434 log.InfoFormat("New rule needs to be created");
435 //Todo error handling
436 }
437 unitOfWork.Save();
438 AlarmClusterManager acm = new AlarmClusterManager(unitOfWork);
439 acm.SendUpdateRequestBasedOnUserChanged(alarm.User, false, ObjectChangeLogEnum.EventType.Write, 0, false);
440
441 return APIResponse.Generate(Request, HttpStatusCode.Accepted, null);
442 }
443 else
444 {
445 //Not allowed to be updated should respond with error
446 log.ErrorFormat("Flags not set correctly: {0}, not allowed single flags:{1}", string.Join(",", flags), string.Join(",", notAllwoedSingleFlagsForAlarmCodeRule));
447 }
448
449 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, null);
450
451 }
452 }
453
454 /// <summary>
455 /// Delete user alarm code rule
456 /// </summary>
457 /// <remarks>
458 /// Delte an´user alarm code rule entry
459 /// </remarks>
460 /// <param name="id">alarm id</param>
461 [SwaggerResponseRemoveDefaults]
462 [SwaggerResponse(HttpStatusCode.Accepted, Description = "{ data: null, errors: null }")]
463 [SwaggerResponse(HttpStatusCode.NotAcceptable, Description = SwaggerConfig.DESCRIPTION_ERROR_LIST)]
464 [Route("api/alarms/{id:int}/alarmcoderule"), Authorize(Roles = "AlarmCodeRuleUser"), HttpDelete]
465 public HttpResponseMessage DeleteUserAlarmCodeRule(int id)
466 {
467 using (IUoW unitOfWork = new UoW())
468 {
469 var validationErrors = new List<dynamic>();
470
471 int[] flags = new int[] { };
472 // VALIDATION
473
474 Alarm alarm = AlarmManager.GetAlarmEntry(unitOfWork, id);
475 if (alarm == null)
476 {
477 validationErrors.Add(ErrorsRepo.AlarmNotFound);
478 }
479
480 if (!string.IsNullOrEmpty(alarm.Flags))
481 {
482 flags = alarm.Flags.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(f => int.Parse(f)).ToArray();
483 }
484 if (flags.Count() == 0)
485 {
486 validationErrors.Add(ErrorsRepo.AttributeNotFound);
487 }
488
489 if (validationErrors.Any())
490 {
491 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, validationErrors);
492 }
493
494 // EXERCISE
495
496 if (flags.Count() > 0 || (flags.Count() == 1 && !notAllwoedSingleFlagsForAlarmCodeRule.Contains(flags[0])))
497 {
498 var acr = GetUserAlarmCodeRule(unitOfWork, alarm, flags);
499
500 if (acr != null)
501 {
502 unitOfWork.AlarmCodeRuleRepo().Delete(acr);
503
504 unitOfWork.Save();
505
506 AlarmClusterManager acm = new AlarmClusterManager(unitOfWork);
507 acm.SendUpdateRequestBasedOnUserChanged(alarm.User, false, ObjectChangeLogEnum.EventType.Write, 5, false);
508
509 return APIResponse.Generate(Request, HttpStatusCode.Accepted, null);
510 }
511 }
512
513 return APIResponse.Generate(Request, HttpStatusCode.NotFound, null);
514 }
515 }
516
517 [Route("api/alarms/{globalalarmid}/nbssubscription"), AllowAnonymous, HttpGet]
518 public HttpResponseMessage GetSubsription(string globalalarmid, string code)
519 {
520 if (code != "h5QEzyUv01de7wZ6MrF4fO4SIFiTbS1Ue51uDh3QT87CG")
521 {
522 log.WarnFormat("Wrong code supplied: {0}", code);
523 return new HttpResponseMessage()
524 {
525 StatusCode = HttpStatusCode.NotFound
526 };
527 }
528
529 using (IUoW unitOfWork = new UoW())
530 {
531 Alarm alarm = unitOfWork.AlarmRepo().Get(a => a.GlobalAlarmId == globalalarmid).FirstOrDefault();
532
533 if (alarm == null || alarm.User == null)
534 {
535 return new HttpResponseMessage()
536 {
537 StatusCode = HttpStatusCode.NotFound
538 };
539 }
540
541 User u = alarm.User;
542
543 if (u == null || u.Deleted || string.IsNullOrWhiteSpace(u.NbsSubscriptionRefSourceKey))
544 {
545 return APIResponse.Success(Request, new { userId = -1, nbsSubscriptionRefSourceKey = "" });
546 }
547
548 return APIResponse.Success(Request, new { userId = u.Id, nbsSubscriptionRefSourceKey = u.NbsSubscriptionRefSourceKey });
549 }
550 }
551
552 /// <summary>
553 /// Retrieve pagenated list of alarms
554 /// </summary>
555 /// <remarks>Returns pagenated list of alarms</remarks>
556 [SwaggerExternalDoc]
557 [Route("api/alarms/tables"), Authorize(Roles = "Users"), HttpGet]
558 public HttpResponseMessage GetAlarmTables()
559 {
560 using (IUoW unitOfWork = new UoW(true))
561 {
562
563 List<TableDefine> tableDefines = TableManager.GetAccessableTables(TableModels.TableType.ALARM);
564
565 if (tableDefines != null)
566 {
567
568 List<TableModels.TableDefineMeta> tableDefineMetas = new List<TableModels.TableDefineMeta>();
569
570 foreach (var table in tableDefines)
571 {
572 //List<string> columns = TableManager.GetColumnsAsList( Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, dynamic>>( Convert.ToString( table.Columns ) ) );
573
574 TableModels.TableDefineMeta tableDefineMeta = new TableModels.TableDefineMeta()
575 {
576 id = table.Id,
577 name = table.TableName,
578 //columns = columns
579 };
580
581 tableDefineMetas.Add(tableDefineMeta);
582 }
583
584 return APIResponse.Generate(Request, HttpStatusCode.OK, tableDefineMetas);
585 }
586 }
587
588 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, new Dictionary<string, string> { { "Error", "nothing" } });
589 }
590
591
592 [SwaggerExternalDoc]
593 [Route("api/alarms/table"), Authorize(Roles = "Users"), HttpGet]
594 public HttpResponseMessage GetAlarmsTable(bool selected = false, int id = 0)
595 {
596 using (IUoW unitOfWork = new UoW(true))
597 {
598 TableModels.TableDefineMeta table = TableManager.GetAccessableTable(TableModels.TableType.ALARM, selected, id);
599
600 if (table != null)
601 {
602 return APIResponse.Generate(Request, HttpStatusCode.OK, table);
603 }
604 }
605
606 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, new Dictionary<string, string> { { "Error", "nothing" } });
607 }
608
609 /// <summary>
610 /// Retrieve pagenated list of users
611 /// </summary>
612 /// <remarks>Returns pagenated list of users by search criteria (the method is a newest one and backed by Elasticsearch engine)</remarks>
613 [SwaggerExternalDoc]
614 [Route("api/alarms/table"), Authorize(Roles = "Users"), HttpPost]
615 public HttpResponseMessage SetAlarmTable([FromBody] TableModels.TableDefineMeta newTable, bool selectNewTable = false)
616 {
617 // validate
618 if (newTable == null)
619 {
620 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, new Dictionary<string, string> { { "Error", "nothing" } });
621 }
622
623 using (IUoW uow = new UoW(false))
624 {
625 Admin admin = AdminManager.GetCurrentAdmin(uow);
626 TableDefine table = TableManager.CreateTable(TableModels.TableType.ALARM, newTable, true);
627
628 if (admin != null && table != null)
629 {
630 uow.TableDefineRepo().Insert(table);
631 AdminTable adminTable = new AdminTable() { AdminId = admin.Id, TableDefineId = table.Id, Selected = false, TableType = (int)TableModels.TableType.ALARM };
632 admin.AdminTables.Add(adminTable);
633
634 // select the newly created table as the selection for this admin.
635 if (selectNewTable)
636 {
637 TableManager.SetSelectedTable(uow, TableModels.TableType.ALARM, table.Id);
638 }
639
640 uow.Save();
641 return APIResponse.Generate(Request, HttpStatusCode.OK, new Dictionary<string, int> { { "id", table.Id } });
642 }
643 }
644
645 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, new Dictionary<string, string> { { "Error", "nothing" } });
646 }
647
648
649 /// <summary>
650 /// Retrieve pagenated list of users
651 /// </summary>
652 /// <remarks>Returns pagenated list of users by search criteria (the method is a newest one and backed by Elasticsearch engine)</remarks>
653 [SwaggerExternalDoc]
654 [Route("api/alarms/table"), Authorize(Roles = "Users"), HttpDelete]
655 public HttpResponseMessage DeleteUserTable(int id)
656 {
657 // validate
658
659 using (IUoW unitOfWork = new UoW(false))
660 {
661
662 if (TableManager.DeleteTable(unitOfWork, TableModels.TableType.ALARM, id))
663 {
664 unitOfWork.Save();
665 return APIResponse.Generate(Request, HttpStatusCode.OK, new Dictionary<string, int> { { "id", id } });
666 }
667 }
668
669 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, new Dictionary<string, string> { { "Error", "nothing" } });
670 }
671
672
673 [SwaggerExternalDoc]
674 [Route("api/alarms/table/select"), Authorize(Roles = "Users"), HttpGet]
675 public HttpResponseMessage SelectAlarmsTable(int id = 0)
676 {
677 if (id == 0)
678 {
679 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, new Dictionary<string, string> { { "Error", "id can't be 0" } });
680 }
681
682 using (IUoW unitOfWork = new UoW(false))
683 {
684 if (!TableManager.SetSelectedTable(unitOfWork, TableModels.TableType.ALARM, id))
685 {
686 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, new Dictionary<string, string> { { "Error", "nothing" } });
687 }
688
689 unitOfWork.Save();
690
691 return APIResponse.Generate(Request, HttpStatusCode.OK, new Dictionary<string, int> { { "id", id } });
692 }
693 }
694
695 /// <summary>
696 /// Retrieve pagenated list of users
697 /// </summary>
698 /// <remarks>Returns pagenated list of users by search criteria (the method is a newest one and backed by Elasticsearch engine)</remarks>
699 [SwaggerExternalDoc]
700 [Route("api/alarms/columns"), Authorize(Roles = "Users"), HttpGet]
701 public HttpResponseMessage GetAlarmsTableColumns(bool getSelected = false, bool getDefault = false, int id = 0)
702 {
703 string cols = TableManager.GetTableColumns(TableModels.TableType.ALARM, getSelected, getDefault, id);
704
705 if (cols == null)
706 {
707 return APIResponse.Generate(Request, HttpStatusCode.NotFound, new Dictionary<string, string> { { "Error", "table not found" } });
708 }
709
710 Dictionary<string, dynamic> columns = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(cols);
711
712 TableModels.TableColumnsMeta columnMeta = new TableModels.TableColumnsMeta()
713 {
714 columns = columns,
715 };
716
717 return APIResponse.Generate(Request, HttpStatusCode.OK, columnMeta);
718 }
719
720 [SwaggerExternalDoc]
721 [Route("api/alarms/columns"), Authorize(Roles = "Users"), HttpPost]
722 public HttpResponseMessage SetUserTableColumns([FromBody]TableModels.TableColumnsMeta columnsMeta, int id = 0)
723 {
724
725 if (id == 0 || columnsMeta == null)
726 {
727 return APIResponse.Generate(Request, HttpStatusCode.OK, new Dictionary<string, string> { { "Error", "id is zero or no changes to make" } });
728 }
729
730 //Dictionary<string, dynamic> columns = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, dynamic>>( columnSpecification );
731
732 using (IUoW unitOfWork = new UoW(false))
733 {
734 TableManager.SetTableColumns(unitOfWork, TableModels.TableType.ALARM, Newtonsoft.Json.JsonConvert.SerializeObject(columnsMeta.columns), false, id);
735
736 unitOfWork.Save();
737 }
738
739 return APIResponse.Generate(Request, HttpStatusCode.OK, new Dictionary<string, int> { { "id", id } });
740 }
741
742 /// <summary>
743 /// Retrieve pagenated list of users
744 /// </summary>
745 /// <remarks>Returns pagenated list of users by search criteria (the method is a newest one and backed by Elasticsearch engine)</remarks>
746 [SwaggerExternalDoc]
747 [Route("api/alarms/data"), Authorize(Roles = "Users"), HttpGet]
748 public HttpResponseMessage GetAlarmsDataTable([Swaggerify(typeof(GetAlarmsSearchModel)), FromUri]GetAlarmsSearchModel uriParams) // this need to be changed
749 {
750 using (IUoW unitOfWork = new UoW(true))
751 {
752 uriParams = uriParams ?? new GetAlarmsSearchModel();
753 //uriParams.RoundDefaults();
754 uriParams.q = uriParams.q.PartialXss();
755 int pageSize = uriParams.pageSize > 500 ? 500 : uriParams.pageSize;
756
757 List<ElasticSearchModels.Alarm> alarms = AlarmManager.AlarmSearch(
758 unitOfWork,
759 uriParams.page,
760 pageSize,
761 uriParams.q,
762 uriParams.o,
763 null,
764 uriParams.customers,
765 uriParams.alarmtext,
766 uriParams.start.ToDateTimeUtc(),
767 uriParams.end.ToDateTimeUtc(),
768 uriParams.exact,
769 uriParams.alarmcodes,
770 null,
771 uriParams.nameonly,
772 uriParams.hideautodeactivated,
773 null,
774 null
775 ).Result;
776
777 TableModels.DataTableMeta table = TableManager.GetAlarmsTable(alarms, TableModels.TableType.ALARM, true);
778
779 if (table != null)
780 {
781 return APIResponse.Generate(Request, HttpStatusCode.OK, table);
782 }
783 }
784
785 return APIResponse.Generate(Request, HttpStatusCode.NotAcceptable, new Dictionary<string, string> { { "Error", "nothing" } });
786 }
787
788 private AlarmCodeRule GetUserAlarmCodeRule(IUoW unitOfWork, Alarm alarm, int[] flags)
789 {
790 foreach (AlarmCodeRule acr in unitOfWork.AlarmCodeRuleRepo().Get(a => a.UserId == alarm.UserId && a.UserId != null && a.RequireAll == true))
791 {
792 int[] ruleFlags = acr.Flags.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(f => int.Parse(f)).ToArray();
793
794 if (flags.Union(ruleFlags).Count() == flags.Count()) //Check if all flags in the rule are present in the alarm
795 {
796 return acr;
797 }
798 }
799 return null;
800 }
801
802 }
803}