1: using System;
2: using System.Linq;
3: using System.Text.RegularExpressions;
4:
5: namespace Ia.Ngn.Cl.Model.Business
6: {
7: ////////////////////////////////////////////////////////////////////////////
8:
9: /// <summary publish="true">
10: /// Access support class for Next Generation Network (NGN) business model.
11: /// </summary>
12: ///
13: /// <remarks>
14: /// Copyright © 2006-2017 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
15: ///
16: /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
17: /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
18: ///
19: /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
20: /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
21: ///
22: /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
23: ///
24: /// Copyright notice: This notice may not be removed or altered from any source distribution.
25: /// </remarks>
26: public partial class Access
27: {
28: private const int fixedLengthOfId = 16;
29:
30: ////////////////////////////////////////////////////////////////////////////
31:
32: /// <summary>
33: ///
34: /// </summary>
35: public static int FixedLengthOfId { get { return fixedLengthOfId; } }
36:
37: /// <summary/>
38: public Access() { }
39:
40: ////////////////////////////////////////////////////////////////////////////
41:
42: /// <summary>
43: ///
44: /// </summary>
45: public static string AccessId(int oltId, int ponNumber, int ontNumber)
46: {
47: string id;
48:
49: id = oltId.ToString() + ponNumber.ToString().PadLeft(4, '0') + ontNumber.ToString().PadLeft(3, '0');
50:
51: if (id.Length != fixedLengthOfId)
52: {
53: throw new ArgumentOutOfRangeException(@"AccessId(): Id length is not " + fixedLengthOfId);
54: }
55:
56: return id;
57: }
58:
59: ////////////////////////////////////////////////////////////////////////////
60:
61: /// <summary>
62: ///
63: /// </summary>
64: public static string AccessId(string ontId)
65: {
66: string id;
67: Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont ont;
68:
69: ont = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.ReadOnt(ontId);
70:
71: if (ont != null) id = AccessId(ont.Pon.PonGroup.Olt.Id, ont.Pon.Number, ont.Number);
72: else id = "0";
73:
74: return id;
75: }
76:
77: ////////////////////////////////////////////////////////////////////////////
78:
79: /// <summary>
80: ///
81: /// </summary>
82: public static string Name(Ia.Ngn.Cl.Model.Access access)
83: {
84: string name;
85:
86: name = Name(access.Id);
87:
88: return name;
89: }
90:
91: ////////////////////////////////////////////////////////////////////////////
92:
93: /// <summary>
94: ///
95: /// </summary>
96: public static string Name(string accessId)
97: {
98: string name;
99:
100: var dictionary = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessIdToOntAccessNameDictionary;
101:
102: if (!string.IsNullOrEmpty(accessId))
103: {
104: if (dictionary.ContainsKey(accessId))
105: {
106: name = dictionary[accessId];
107: }
108: else name = string.Empty;
109: }
110: else name = string.Empty;
111:
112: return name;
113: }
114:
115: /*
116: ////////////////////////////////////////////////////////////////////////////
117:
118: /// <summary>
119: ///
120: /// </summary>
121: public static string Name(string accessId)
122: {
123: string name;
124: int oltId, ponNumber, ontNumber;
125:
126: ExtractOltIdAndPonNumberAndOntNumberFromAccessId(accessId, out oltId, out ponNumber, out ontNumber);
127:
128: if (oltId > 0 && ponNumber > 0 && ontNumber > 0)
129: {
130: name = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList where o.Pon.PonGroup.Olt.Id == oltId && o.Pon.Number == ponNumber && o.Number == ontNumber select o.Access.Name).SingleOrDefault();
131: }
132: else name = string.Empty;
133:
134: return name;
135: }
136: */
137:
138: ////////////////////////////////////////////////////////////////////////////
139:
140: /// <summary>
141: ///
142: /// </summary>
143: public static string Name(string areaSymbol, int pon, int ont)
144: {
145: string name;
146:
147: name = areaSymbol + "." + pon + "." + ont;
148:
149: return name;
150: }
151:
152: ////////////////////////////////////////////////////////////////////////////
153:
154: /// <summary>
155: ///
156: /// </summary>
157: private static void ExtractOltIdAndPonNumberAndOntNumberFromAccessId(string accessId, out int oltId, out int ponNumber, out int ontNumber)
158: {
159: string s;
160:
161: if (!string.IsNullOrEmpty(accessId))
162: {
163: s = accessId.Substring(accessId.Length - 3, 3);
164:
165: if (int.TryParse(s, out ontNumber))
166: {
167: accessId = accessId.Remove(accessId.Length - 3, 3);
168:
169: s = accessId.Substring(accessId.Length - 4, 4);
170:
171: if (int.TryParse(s, out ponNumber))
172: {
173: s = accessId.Remove(accessId.Length - 4, 4);
174:
175: if (int.TryParse(s, out oltId))
176: {
177:
178: }
179: else oltId = ponNumber = ontNumber = 0;
180: }
181: else oltId = ponNumber = ontNumber = 0;
182: }
183: else oltId = ponNumber = ontNumber = 0;
184: }
185: else oltId = ponNumber = ontNumber = 0;
186: }
187:
188: ////////////////////////////////////////////////////////////////////////////
189:
190: /// <summary>
191: ///
192: /// </summary>
193: public static void ExtractOltIdAndPonNumberAndOntNumberFromOntName(string accessName, out int oltId, out int pon, out int ontInternalNumber)
194: {
195: // below: this expects accessName in exact format like SUR.12.3
196: int ponNumber;
197: string ponGroupSymbol;
198: string[] sp;
199:
200: sp = accessName.Split('.');
201:
202: ponGroupSymbol = sp[0];
203: pon = ponNumber = int.Parse(sp[1]);
204: ontInternalNumber = int.Parse(sp[2]);
205:
206: oltId = (from Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon p in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonList where p.PonGroup.Symbol == ponGroupSymbol && p.Number == ponNumber select p.PonGroup.Olt.Id).SingleOrDefault();
207: }
208:
209: ////////////////////////////////////////////////////////////////////////////
210:
211: /// <summary>
212: ///
213: /// </summary>
214: public static string SqlInsertCommand(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt, int areaId, string block, string street, string premisesOld, string premisesNew, string paci)
215: {
216: string id, sa, odf;
217: Guid userId;
218: DateTime dateTime;
219:
220: id = Ia.Ngn.Cl.Model.Business.Access.AccessId(nddOnt.Pon.PonGroup.Olt.Id, nddOnt.Pon.Number, nddOnt.Number);
221: odf = string.Empty;
222: userId = Guid.Empty;
223: dateTime = DateTime.UtcNow.AddHours(3);
224:
225: // Id Olt Pon Ont Odf AreaId Block Street PremisesOld PremisesNew Created Updated UserId
226: // 102010101001001 102010101 1 1 NULL 50502 8 17 271 22 2014 - 11 - 18 10:17:17.000 2015 - 03 - 12 12:25:45.680 4E42E245 - 2BAF - 4C11 - B4BF - 4D681123999F
227:
228: sa = @"insert into Accesses (Id,Olt,Pon,Ont,Odf,AreaId,Block,Street,PremisesOld,PremisesNew,Paci,Created,Updated,UserId) values ('" + id + "'," + nddOnt.Pon.PonGroup.Olt.Id + "," + nddOnt.Pon.Number + "," + nddOnt.Number + ",'" + odf + "'," + areaId + "," + block + ",'" + street + "','" + premisesOld + "','" + premisesNew + "','" + paci + "','" + dateTime + "','" + dateTime + "','" + userId.ToString() + "')";
229:
230: return sa;
231: }
232:
233: ////////////////////////////////////////////////////////////////////////////
234:
235: /// <summary>
236: ///
237: /// </summary>
238: public static Ia.Ngn.Cl.Model.Access Create(string input, string kuwaitNgnAreaSymbol, string block, string street, string premisesOld, string premisesNew, string odf, string paci, string note, Guid userId, out Ia.Cl.Model.Result result)
239: {
240: string accessName;
241: Ia.Ngn.Cl.Model.Access access;
242: Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt;
243: Ia.Ngn.Cl.Model.Business.Service.KuwaitNgnArea kuwaitNgnArea;
244:
245: result = new Ia.Cl.Model.Result();
246: access = null;
247:
248: if (Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.AccessNameIsWithinAllowedOntList(input, out accessName))
249: {
250: //nddOnt = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList where o.Access.Name == accessName select o).SingleOrDefault();
251: nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntDictionary.ContainsKey(accessName) ? Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntDictionary[accessName] : null;
252:
253: if (nddOnt != null)
254: {
255: kuwaitNgnArea = (from kna in Ia.Ngn.Cl.Model.Data.Service.KuwaitNgnAreaList where kna.Symbol == kuwaitNgnAreaSymbol select kna).SingleOrDefault();
256:
257: if (kuwaitNgnArea != null)
258: {
259: access = new Ia.Ngn.Cl.Model.Access
260: {
261: Id = Ia.Ngn.Cl.Model.Business.Access.AccessId(nddOnt.Pon.PonGroup.Olt.Id, nddOnt.Pon.Number, nddOnt.Number),
262: AreaId = kuwaitNgnArea.Id,
263: Block = block,
264: Street = street,
265: PremisesOld = premisesOld,
266: PremisesNew = premisesNew,
267: Paci = paci,
268: Note = note,
269: Olt = nddOnt.Pon.PonGroup.Olt.Id,
270: Odf = odf,
271: Pon = nddOnt.Pon.Number,
272: Ont = nddOnt.Number,
273: UserId = userId
274: };
275:
276: Ia.Ngn.Cl.Model.Data.Access.Create(access, out result);
277:
278: if (result.IsSuccessful)
279: {
280: Ia.Ngn.Cl.Model.Data.Msmq.AccessNameQueue.Enqueue(access.Name);
281: }
282: }
283: else
284: {
285: result.AddError("kuwaitNgnArea is null. ");
286: }
287: }
288: else
289: {
290: result.AddError("nddOnt is null. ");
291: }
292: }
293: else
294: {
295: result.AddError("The ONT \"" + accessName + "\" does not belong to the network. ");
296: }
297:
298: return access;
299: }
300:
301: ////////////////////////////////////////////////////////////////////////////
302:
303: /// <summary>
304: ///
305: /// </summary>
306: public static Ia.Ngn.Cl.Model.Access CreateObject(string input, string kuwaitNgnAreaSymbol, string block, string street, string premisesOld, string premisesNew, string odf, string paci, string note, Guid userId, out Ia.Cl.Model.Result result)
307: {
308: string accessName;
309: Ia.Ngn.Cl.Model.Access access;
310: Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt;
311: Ia.Ngn.Cl.Model.Business.Service.KuwaitNgnArea kuwaitNgnArea;
312:
313: result = new Ia.Cl.Model.Result();
314:
315: access = null;
316:
317: if (Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.AccessNameIsWithinAllowedOntList(input, out accessName))
318: {
319: //nddOnt = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList where o.Access.Name == accessName select o).SingleOrDefault();
320: nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntDictionary.ContainsKey(accessName) ? Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntDictionary[accessName] : null;
321:
322: if (nddOnt != null)
323: {
324: kuwaitNgnArea = (from kna in Ia.Ngn.Cl.Model.Data.Service.KuwaitNgnAreaList where kna.Symbol == kuwaitNgnAreaSymbol select kna).SingleOrDefault();
325:
326: if (kuwaitNgnArea != null)
327: {
328: access = new Ia.Ngn.Cl.Model.Access
329: {
330: Id = Ia.Ngn.Cl.Model.Business.Access.AccessId(nddOnt.Pon.PonGroup.Olt.Id, nddOnt.Pon.Number, nddOnt.Number),
331: AreaId = kuwaitNgnArea.Id,
332: Block = block,
333: Street = street,
334: PremisesOld = premisesOld,
335: PremisesNew = premisesNew,
336: Paci = paci,
337: Note = note,
338: Olt = nddOnt.Pon.PonGroup.Olt.Id,
339: Odf = odf,
340: Pon = nddOnt.Pon.Number,
341: Ont = nddOnt.Number,
342: Created = DateTime.UtcNow.AddHours(3),
343: Updated = DateTime.UtcNow.AddHours(3),
344: UserId = userId
345: };
346: }
347: else
348: {
349: result.AddError("kuwaitNgnArea is null. ");
350: }
351: }
352: else
353: {
354: result.AddError("nddOnt is null. ");
355: }
356: }
357: else
358: {
359: result.AddError("The ONT \"" + accessName + "\" does not belong to the network (الجهاز لا ينتمي للشبكة). ");
360: }
361:
362: return access;
363: }
364:
365: ////////////////////////////////////////////////////////////////////////////
366:
367: /// <summary>
368: ///
369: /// </summary>
370: public static void Delete(string inputAccessName, Guid userId, out Ia.Cl.Model.Result result)
371: {
372: string accessName, r;
373: Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt;
374:
375: result = new Ia.Cl.Model.Result();
376:
377: if (Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.AccessNameIsWithinAllowedOntList(inputAccessName, out accessName))
378: {
379: //nddOnt = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList where o.Access.Name == accessName select o).SingleOrDefault();
380: nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntDictionary.ContainsKey(accessName) ? Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntDictionary[accessName] : null;
381:
382: if (nddOnt != null)
383: {
384: try
385: {
386: /*
387: --update ServiceRequestServices set Access_Id = null where Access_Id = '1040101010009013'
388: --update EmsOnts set Access_Id = null where Access_Id = '1040101010009013'
389: --update EmsDevs set Access_Id = null where Access_Id = '1060205011321001'
390: --update Onts set Access_Id = null where Access_Id = '1040101010009013'
391: --delete from Events where Ont_Id = (select id from Onts where Access_Id = '1040101010009013')
392:
393: --delete from ServiceRequestOntDetails where ServiceRequestOnts _Id = (select id from ServiceRequestOnts where Access_Id = '1040101010009013')
394: --delete from ServiceRequestOnts where Access_Id = '1040101010009013'
395:
396: --delete from Accesses where id = '1040101010009013'
397: */
398: Ia.Ngn.Cl.Model.Data.ServiceRequestService.NullifyAccessIdByAccessId(nddOnt.Access.Id, out r);
399:
400: Ia.Ngn.Cl.Model.Data.Huawei.Ont.NullifyAccessIdByAccessId(nddOnt.Access.Id, out r);
401:
402: Ia.Ngn.Cl.Model.Data.Huawei.Dev.NullifyAccessIdByAccessId(nddOnt.Access.Id, out r); // for MDUs
403:
404: Ia.Ngn.Cl.Model.Data.Nokia.Ont.NullifyAccessIdByAccessId(nddOnt.Access.Id, out r);
405:
406: Ia.Ngn.Cl.Model.Data.Event.DeleteByAccessId(nddOnt.Access.Id, out r);
407:
408: Ia.Ngn.Cl.Model.Data.ServiceRequestOntDetail.DeleteByAccessId(nddOnt.Access.Id, out r);
409:
410: Ia.Ngn.Cl.Model.Data.ServiceRequestOnt.DeleteByAccessId(nddOnt.Access.Id, out r);
411:
412: Ia.Ngn.Cl.Model.Data.Access.Delete(nddOnt.Access.Id, out result);
413:
414: if (result.IsSuccessful)
415: {
416: Ia.Ngn.Cl.Model.Data.Msmq.AccessNameQueue.Enqueue(nddOnt.Access.Name);
417: }
418: else
419: {
420: result.AddError("Error in Ia.Ngn.Cl.Model.Data.Access.Delete(): " + result);
421: }
422: }
423: catch (Exception e)
424: {
425: result.AddError("Error in Ia.Ngn.Cl.Model.Business.Access.Delete(): inputAccessName: " + inputAccessName + ", exception string: " + e.ToString());
426: }
427: }
428: else
429: {
430: result.AddError("nddOnt is null. ");
431: }
432: }
433: else
434: {
435: result.AddError("The ONT \"" + accessName + "\" does not belong to the network (الجهاز لا ينتمي للشبكة). ");
436: }
437: }
438:
439: ////////////////////////////////////////////////////////////////////////////
440:
441: /// <summary>
442: ///
443: /// </summary>
444: public static void DeleteByAccessId(string accessId, Guid userId, out Ia.Cl.Model.Result result)
445: {
446: result = new Ia.Cl.Model.Result();
447:
448: Ia.Ngn.Cl.Model.Data.Access.Delete(accessId, out result);
449: }
450:
451: ////////////////////////////////////////////////////////////////////////////
452:
453: /// <summary>
454: ///
455: /// </summary>
456: public static string NormalizeBlockEntry(string input)
457: {
458: string s;
459:
460: if (!string.IsNullOrEmpty(input))
461: {
462: if (int.TryParse(input, out int i))
463: {
464: s = i.ToString();
465: }
466: else
467: {
468: s = input.TrimStart('0');
469: }
470: }
471: else
472: {
473: s = string.Empty;
474: }
475:
476: return s;
477: }
478:
479: ////////////////////////////////////////////////////////////////////////////
480:
481: /// <summary>
482: /// Remove and replace inappropriate strings in access street data
483: /// </summary>
484: public static string NormalizeStreetEntry(string input)
485: {
486: string s;
487:
488: s = input.ToLower();
489:
490: if (s == "na") s = string.Empty;
491: else if (s == "n/a") s = string.Empty;
492: else if (s == "0") s = string.Empty;
493: else if (s == "#") s = string.Empty;
494:
495: s = s.Replace("#", "");
496:
497: s = s.TrimStart('0');
498:
499: return s;
500: }
501:
502: ////////////////////////////////////////////////////////////////////////////
503:
504: /// <summary>
505: /// Remove and replace inappropriate strings in access premises data
506: /// </summary>
507: public static string NormalizePremisesEntry(string input)
508: {
509: string s;
510:
511: s = input.ToLower();
512:
513: if (s == "na") s = string.Empty;
514: else if (s == "n/a") s = string.Empty;
515: else if (s == "0") s = string.Empty;
516: else if (s == "#") s = string.Empty;
517:
518: s = s.Replace("#", "");
519:
520: s = s.TrimStart('0');
521:
522: return s;
523: }
524:
525: ////////////////////////////////////////////////////////////////////////////
526:
527: /// <summary>
528: /// Remove and replace inappropriate strings in access PACI data. PACI numbers be have 8 digits
529: /// </summary>
530: public static string NormalizePaciEntry(string input)
531: {
532: if (Regex.IsMatch(input, @"\d{8}")) { }
533: else input = string.Empty;
534:
535: return input;
536: }
537:
538: ////////////////////////////////////////////////////////////////////////////
539:
540: /// <summary>
541: /// Correct the ONT serial number field
542: /// </summary>
543: public static string NormalizeOntSerialNumberEntry(string input)
544: {
545: string serial;
546:
547: serial = input.ToUpper();
548:
549: return serial;
550: }
551:
552: ////////////////////////////////////////////////////////////////////////////
553:
554: /// <summary>
555: ///
556: /// </summary>
557: public static bool AccessNameIsInAValidFormat(string accessName)
558: {
559: bool isValid;
560:
561: isValid = Regex.IsMatch(accessName, @"^[a-zA-Z]{3}\s+\d{1,4}\s+\d{1,3}$") // SLA 1 1
562: || Regex.IsMatch(accessName, @"^[a-zA-Z]{3}\.\d{1,4}\.\d{1,3}$") // SLA.1.1
563: || Regex.IsMatch(accessName, @"^[a-zA-Z]{3}\/\d{1,4}\/\d{1,3}$") // SLA/1/1
564: || Regex.IsMatch(accessName, @"^[a-zA-Z]{3}-\d{1,4}-\d{1,3}$"); // SLA-1-1
565:
566: return isValid;
567: }
568:
569: ////////////////////////////////////////////////////////////////////////////
570:
571: /// <summary>
572: ///
573: /// </summary>
574: public static bool PonNameIsInValidFormat(string ponName)
575: {
576: bool isValid;
577:
578: isValid = Regex.IsMatch(ponName, @"^[a-zA-Z]{3}\s+\d{1,4}$") // SLA 1
579: || Regex.IsMatch(ponName, @"^[a-zA-Z]{3}\.\d{1,4}$") // SLA.1
580: || Regex.IsMatch(ponName, @"^[a-zA-Z]{3}\/\d{1,4}$") // SLA/1
581: || Regex.IsMatch(ponName, @"^[a-zA-Z]{3}-\d{1,4}$"); // SLA-1
582:
583: return isValid;
584: }
585:
586: ////////////////////////////////////////////////////////////////////////////
587: ////////////////////////////////////////////////////////////////////////////
588: }
589:
590: ////////////////////////////////////////////////////////////////////////////
591: ////////////////////////////////////////////////////////////////////////////
592: }