)>}]
شركة التطبيقات المتكاملة لتصميم وبرمجة البرمجيات الخاصة ش.ش.و.
Integrated Applications Programming Company
Skip Navigation Links

Public general use code classes and xml files that we've compiled and used over the years:

Default mdaa network information support class for the Optical Fiber Network business model

    1: using Ia.Cl.Model.Db;
    2: using Ia.Mdaa.Cl.Model.Business;
    3: using System;
    4: using System.Collections.Generic;
    5: using System.Data;
    6: using System.IO;
    7: using System.Linq;
    8: using System.Text;
    9: using System.Text.Json;
   10: using System.Text.RegularExpressions;
   11: using System.Threading;
   12: using System.Threading.Tasks;
   13:  
   14: namespace Ia.Ngn.Cl.Model.Business.Mdaa
   15: {
   16:     ////////////////////////////////////////////////////////////////////////////
   17:  
   18:     /// <summary publish="true">
   19:     /// Default mdaa network information support class for the Optical Fiber Network business model
   20:     /// </summary>
   21:     /// 
   22:     /// <remarks> 
   23:     /// Copyright © 2021-2022 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
   24:     ///
   25:     /// 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
   26:     /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
   27:     ///
   28:     /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   29:     /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   30:     /// 
   31:     /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
   32:     /// 
   33:     /// Copyright notice: This notice may not be removed or altered from any source distribution.
   34:     /// </remarks> 
   35:     public class Default
   36:     {
   37:         private static readonly string archive = @"\\172.25.221.32\Ia\Archive\Mdaa\";
   38:  
   39:         private static Ia.Mdaa.Cl.Model.Business.DatabaseInformation databaseInformation = new Ia.Mdaa.Cl.Model.Business.DatabaseInformation();
   40:  
   41:         private static Ia.Cl.Model.Db.Oracle oracle;
   42:  
   43:         private static readonly object objectLock = new object();
   44:  
   45:         public const bool ApplicationIsDisconnectedFromMinistryNetworkForDebugging = true;
   46:  
   47:         ////////////////////////////////////////////////////////////////////////////
   48:  
   49:         /// <summary>
   50:         ///
   51:         /// </summary>
   52:         public Default() { }
   53:  
   54:         ////////////////////////////////////////////////////////////////////////////
   55:  
   56:         /// <summary>
   57:         ///
   58:         /// </summary>
   59:         public static Ia.Cl.Model.Result InitializeOracleConnection()
   60:         {
   61:             var result = new Ia.Cl.Model.Result();
   62:  
   63:             if (!ApplicationIsDisconnectedFromMinistryNetworkForDebugging)
   64:             {
   65:                 //var oracleConnectionString = ConfigurationManager.ConnectionStrings["OracleConnection"].ToString();
   66:                 var oracleConnectionString = "DATA SOURCE = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.139)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.36)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = MOCDB))) IBM1 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.139)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = MOCDB) (INSTANCE_NAME=MOCDB1))) IBM2 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.36)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = MOCDB) (INSTANCE_NAME=MOCDB2)));PERSIST SECURITY INFO=True;USER ID=NGNUSER;PASSWORD=NGN;ENLIST=True";
   67:  
   68:                 try
   69:                 {
   70:                     oracle = new Ia.Cl.Model.Db.Oracle(oracleConnectionString);
   71:  
   72:                     oracle.Sql(Ia.Ngn.Cl.Model.Business.Mdaa.MinistryDatabase.AlterSessionOfCustomerDepartmentOracleDatabase);
   73:  
   74:                     result.AddSuccess("Initialize Oracle Connection: Success");
   75:                 }
   76:                 catch (Exception ex)
   77:                 {
   78:                     result.AddError("Initialize Oracle Connection: Error: Exception: " + ex.Message);
   79:                 }
   80:             }
   81:  
   82:             return result;
   83:         }
   84:  
   85:         ////////////////////////////////////////////////////////////////////////////
   86:  
   87:         /// <summary>
   88:         ///
   89:         /// </summary>
   90:         public static Ia.Cl.Model.Result Collect()
   91:         {
   92:             var result = new Ia.Cl.Model.Result();
   93:  
   94:             databaseInformation.Read();
   95:  
   96:             var tableList = databaseInformation.TableInformationList;
   97:  
   98:             var i = 0;
   99:             foreach (var table in tableList)
  100:             {
  101:                 var tableInformation = CollectTableInformationFromMocdbOracleDatabase(table.Name, table.Schema);
  102:  
  103:                 databaseInformation.Update(tableInformation);
  104:  
  105:                 result.AddSuccess("Collect: table name: " + table.Name + ", number: " + i++);
  106:  
  107:                 Thread.Sleep(2000);
  108:  
  109:                 //if (i == 4) break;
  110:             }
  111:  
  112:             return result;
  113:         }
  114:  
  115:         ////////////////////////////////////////////////////////////////////////////
  116:  
  117:         /// <summary>
  118:         ///
  119:         /// </summary>
  120:         public static Ia.Cl.Model.Result Analisys()
  121:         {
  122:             var result = new Ia.Cl.Model.Result();
  123:  
  124:             var stringBuilder = new StringBuilder();
  125:  
  126:             string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\analysis.html";
  127:  
  128:             databaseInformation.Read();
  129:  
  130:             stringBuilder.AppendLine(@"<html><head><style>
  131:   span {color:red;}
  132: </style></head><body><pre>");
  133:  
  134:             stringBuilder.AppendLine("Number of tables: " + databaseInformation.TableInformationList.Count);
  135:  
  136:             var i = 1000;
  137:             var c = (from ti in databaseInformation.TableInformationList where ti.Count > i select ti).Count();
  138:  
  139:             stringBuilder.AppendLine("Number of tables with over " + i + " records: " + c);
  140:  
  141:             stringBuilder.AppendLine("<hr/>");
  142:  
  143:             var distinctSchemaList = (from ti in databaseInformation.TableInformationList
  144:                                       where ti.Count > 0
  145:                                       select ti.Schema).Distinct();
  146:  
  147:             stringBuilder.AppendLine("Distinct Schema: " + string.Join(", ", distinctSchemaList));
  148:  
  149:             stringBuilder.AppendLine("<hr/>");
  150:  
  151:             stringBuilder.AppendLine("<dl>");
  152:  
  153:             foreach (var schema in distinctSchemaList)
  154:             {
  155:                 var tableList = (from ti in databaseInformation.TableInformationList
  156:                                  where ti.Schema == schema && ti.Count > 0
  157:                                  select ti).ToList();
  158:  
  159:                 //stringBuilder.AppendLine("Schema: " + schema); // tables: " + string.Join(", ", tableList.));
  160:                 //stringBuilder.AppendLine();
  161:  
  162:                 foreach (var table in tableList)
  163:                 {
  164:                     stringBuilder.AppendLine("<dt>Table: " + table.Name + ", Schema: " + table.Schema + ", Record count: <span>" + table.Count + "</span></dt>");
  165:  
  166:                     // "Desc": "COLUMN_NAME\tDATATYPE_LENGTH\t\r\nFEEDER_ID\tNUMBER(22)\t\r\nFEEDER_NAME\tVARCHAR2(300)\t\r\nMDF_PAIR\tNUMBER(22)\t\r\nREMARKS\tVARCHAR2(500)\t\r\nFEEDER_BOX_ID\tNUMBER(22)\t\r\nE_DATE\tDATE(7)\t\r\nE_USER\tVARCHAR2(30)\t\r\nL_DATE\tDATE(7)\t\r\nL_USER\tVARCHAR2(30)\t\r\n",
  167:                     //      "TopRecordText": "\r\n"
  168:  
  169:                     stringBuilder.AppendLine("<dd>");
  170:                     var desc = table.Desc;
  171:  
  172:                     stringBuilder.AppendLine("Database fields: ");
  173:                     stringBuilder.AppendLine(table.Desc);
  174:                     stringBuilder.AppendLine();
  175:                     stringBuilder.AppendLine("TopRecordText: ");
  176:                     stringBuilder.AppendLine(table.TopRecordText);
  177:                     stringBuilder.AppendLine("</dd>");
  178:  
  179:                     stringBuilder.AppendLine("<hr/>");
  180:                 }
  181:  
  182:                 stringBuilder.AppendLine("<hr/>");
  183:             }
  184:  
  185:             stringBuilder.AppendLine("</dl>");
  186:  
  187:             stringBuilder.AppendLine("</pre></body></html>");
  188:  
  189:             File.WriteAllText(filePath, stringBuilder.ToString());
  190:  
  191:             return result;
  192:         }
  193:  
  194:         ////////////////////////////////////////////////////////////////////////////
  195:  
  196:         /// <summary>
  197:         ///
  198:         /// </summary>
  199:         private static Ia.Mdaa.Cl.Model.Business.TableInformation CollectTableInformationFromMocdbOracleDatabase(string tableName, string tableSchema)
  200:         {
  201:             int count;
  202:  
  203:             var countSql = "select count(*) from " + tableName;
  204:             var sql = "select * from " + tableName + " where rownum <= 10";
  205:  
  206:             var tableInformation = new Ia.Mdaa.Cl.Model.Business.TableInformation();
  207:  
  208:             try
  209:             {
  210:                 var countString = oracle.Scalar(countSql);
  211:                 var descDt = oracle.Desc(tableName, tableSchema);
  212:                 var dt = oracle.Select(sql);
  213:  
  214:                 if (int.TryParse(countString, out count)) { }
  215:                 else count = 0;
  216:  
  217:                 tableInformation.Schema = tableSchema;
  218:                 tableInformation.Name = tableName;
  219:                 tableInformation.Count = count;
  220:                 tableInformation.Desc = Ia.Cl.Model.Default.GenerateTabSeparatedTextFromDataTable(descDt);
  221:                 tableInformation.TopRecordText = Ia.Cl.Model.Default.GenerateTabSeparatedTextFromDataTable(dt);
  222:             }
  223:             catch (Exception ex)
  224:             {
  225:  
  226:             }
  227:  
  228:             return tableInformation;
  229:         }
  230:  
  231:         ////////////////////////////////////////////////////////////////////////////
  232:  
  233:         /// <summary>
  234:         ///
  235:         /// </summary>
  236:         public static Ia.Cl.Model.Result ManageProperly(ref int properlySelectedHundredsSubdomainListIndex)
  237:         {
  238:             List<string> addedServiceList, removedServiceList;
  239:  
  240:             var result = new Ia.Cl.Model.Result();
  241:  
  242:             var hundredsSubdomain = Ia.Ngn.Cl.Model.Business.Mdaa.MinistryDatabase.ProperlySelectedHundredsSubdomainListItem(ref properlySelectedHundredsSubdomainListIndex, out int itemIndex, out int listCount);
  243:  
  244:             var dataTable = ReadHundredsSubdomainBalanceListItemDataTable(hundredsSubdomain);
  245:  
  246:             var serviceStateThatCrossedThresholdList = UpdateServiceStateThatCrossedThresholdList(hundredsSubdomain, dataTable, out addedServiceList, out removedServiceList);
  247:  
  248:             var s = string.Empty;
  249:  
  250:             if (hundredsSubdomain.PstnId != 0) s += "Legacy: " + hundredsSubdomain.Pstn.Name + ": ";
  251:             if (hundredsSubdomain.RouterId != 0) s += "Ofn: " + hundredsSubdomain.Router.Name + ": ";
  252:  
  253:             var r = s
  254:                 + hundredsSubdomain.FirstServiceNumber + "-" + hundredsSubdomain.LastServiceNumber + " "
  255:                 + "(" + itemIndex + "/" + listCount + "): "
  256:                 + "list (total): " + serviceStateThatCrossedThresholdList.Count + " (" + Ia.Ngn.Cl.Model.Data.MinistryDatabase.ServiceStateThatCrossedThresholdList.Count + "), "
  257:                 + "added (total): " + addedServiceList.Count + " (" + Ia.Ngn.Cl.Model.Data.MinistryDatabase.AddedServiceList.Count + "), "
  258:                 + "removed (total): " + removedServiceList.Count + " (" + Ia.Ngn.Cl.Model.Data.MinistryDatabase.RemovedServiceList.Count + ")";
  259:  
  260:             result.AddSuccess(r);
  261:  
  262:             return result;
  263:         }
  264:  
  265:         ////////////////////////////////////////////////////////////////////////////
  266:  
  267:         /// <summary>
  268:         ///
  269:         /// </summary>4
  270:         public static Ia.Cl.Model.Result ManageTransaction()
  271:         {
  272:             var result = new Ia.Cl.Model.Result();
  273:  
  274:             var serviceTransactionList = Ia.Ngn.Cl.Model.Data.MinistryDatabase.ServiceTransactionList;
  275:  
  276:             var latestTransactionId = serviceTransactionList.Count > 0 ? serviceTransactionList.Max(u => u.TransactionId) : 0;
  277:  
  278:             var dataTable = ReadPaymentTransactionOfThePreviousNDaysServiceDataTable(latestTransactionId, 2);
  279:  
  280:             serviceTransactionList = Ia.Ngn.Cl.Model.Data.MinistryDatabase.ServiceSerialTransactionIdDateTimeListFromTransactionListDataTable(dataTable);
  281:  
  282:             Ia.Ngn.Cl.Model.Data.MinistryDatabase.Update(serviceTransactionList, out List<string> addedServiceTransactionList);
  283:  
  284:             var r =
  285:                 "list (total): " + serviceTransactionList.Count + " (" + Ia.Ngn.Cl.Model.Data.MinistryDatabase.ServiceTransactionList.Count + "), "
  286:                 + "added: " + addedServiceTransactionList.Count;
  287:  
  288:             result.AddSuccess(r);
  289:  
  290:             return result;
  291:         }
  292:  
  293:         ////////////////////////////////////////////////////////////////////////////
  294:  
  295:         /// <summary>
  296:         ///
  297:         /// </summary>
  298:         public static Ia.Cl.Model.Result ManageAnalyzeTransaction()
  299:         {
  300:             List<string> addedServiceList, removedServiceList;
  301:  
  302:             var result = new Ia.Cl.Model.Result();
  303:  
  304:             var examinedServiceTransactionIdList = Ia.Ngn.Cl.Model.Data.MinistryDatabase.ExaminedServiceTransactionIdList;
  305:  
  306:             var serviceTransactionList = Ia.Ngn.Cl.Model.Data.MinistryDatabase.ServiceTransactionList; // note that ServiceTransactionList is not sorted here, it will be sorted just below
  307:  
  308:             var serviceTransaction = (from st in serviceTransactionList
  309:                                       where !examinedServiceTransactionIdList.Contains(st.TransactionId)
  310:                                       select st).OrderBy(u => u.TransactionId).LastOrDefault();
  311:  
  312:             var r = string.Empty;
  313:  
  314:             if (!string.IsNullOrEmpty(serviceTransaction.Service))
  315:             {
  316:                 r = "reading: " + serviceTransaction.Service;
  317:  
  318:                 var dataTable = ReadASingleServiceNumberBalanceDataTable(int.Parse(serviceTransaction.Service));
  319:  
  320:                 if (dataTable != null)
  321:                 {
  322:                     var hundredsSubdomain = new Ia.Ngn.Cl.Model.Business.Service.HundredsSubdomain(serviceTransaction.Service);
  323:  
  324:                     if (hundredsSubdomain.Subdomain != 0)
  325:                     {
  326:                         var serviceStateThatCrossedThresholdList = UpdateServiceStateThatCrossedThresholdList(hundredsSubdomain, dataTable, out addedServiceList, out removedServiceList);
  327:  
  328:                         Ia.Ngn.Cl.Model.Data.MinistryDatabase.ExaminedServiceTransactionIdList.Add(serviceTransaction.TransactionId);
  329:                     }
  330:                     else
  331:                     {
  332:                         Ia.Ngn.Cl.Model.Data.MinistryDatabase.ExaminedServiceTransactionIdList.Add(serviceTransaction.TransactionId);
  333:                     }
  334:                 }
  335:                 else
  336:                 {
  337:                 }
  338:             }
  339:             else r = "reading: no pending services to read";
  340:  
  341:             result.AddSuccess(r);
  342:  
  343:             return result;
  344:         }
  345:  
  346:         ////////////////////////////////////////////////////////////////////////////
  347:  
  348:         /// <summary>
  349:         ///
  350:         /// </summary>
  351:         public static Ia.Cl.Model.Result ManageMsmqQueue()
  352:         {
  353:             var result = new Ia.Cl.Model.Result();
  354:  
  355:             var queueCount = Ia.Ngn.Cl.Model.Data.Msmq.MdaaApplication.Count;
  356:  
  357:             if (queueCount > 0)
  358:             {
  359:                 var message = Ia.Ngn.Cl.Model.Data.Msmq.MdaaApplication.Dequeue;
  360:  
  361:                 if (message.Process == Ia.Ngn.Cl.Model.Business.Msmq.Process.ReadService)
  362:                 {
  363:  
  364:                     result.AddSuccess(message.Service);
  365:                 }
  366:                 else if (message.Process == Ia.Ngn.Cl.Model.Business.Msmq.Process.Synchronize)
  367:                 {
  368:                     //var r = ManageSynchronization();
  369:  
  370:                     //result.AddResult(r);
  371:                 }
  372:                 else if (message.Process == Ia.Ngn.Cl.Model.Business.Msmq.Process.ActiveApplicationRunningPermissionState)
  373:                 {
  374:                     Ia.Ngn.Cl.Model.Business.Default.PermitActiveApplicationsToRun = message.State;
  375:  
  376:                     result.AddSuccess("PermitActiveApplicationsToRun: " + message.State);
  377:                 }
  378:                 else
  379:                 {
  380:                     throw new ArgumentOutOfRangeException("MSMQ process " + message.Process.ToString() + " is undefined");
  381:                 }
  382:             }
  383:             else
  384:             {
  385:             }
  386:  
  387:             return result;
  388:         }
  389:  
  390:         ////////////////////////////////////////////////////////////////////////////
  391:  
  392:         /// <summary>
  393:         ///
  394:         /// </summary>
  395:         private static List<Ia.Ngn.Cl.Model.Business.Mdaa.MinistryDatabase.ServiceState> UpdateServiceStateThatCrossedThresholdList(Ia.Ngn.Cl.Model.Business.Service.HundredsSubdomain hundredsSubdomain, DataTable dataTable, out List<string> addedServiceList, out List<string> removedServiceList)
  396:         {
  397:             var serviceStateList = Ia.Ngn.Cl.Model.Data.MinistryDatabase.ServiceStateListFromHundredsSubdomainListDataTable(hundredsSubdomain, dataTable);
  398:  
  399:             var serviceStateWithLatestSerialList = Ia.Ngn.Cl.Model.Data.MinistryDatabase.FilterServiceStateListByServicesWithLatestSerial(serviceStateList);
  400:  
  401:             var serviceStateThatCrossedThresholdList = Ia.Ngn.Cl.Model.Data.MinistryDatabase.FilterServiceStateListByServicesThatCrossedAdministrativeDisconnectionBalanceThresholdList(serviceStateWithLatestSerialList);
  402:  
  403:             Ia.Ngn.Cl.Model.Data.MinistryDatabase.Update(hundredsSubdomain, serviceStateThatCrossedThresholdList, out addedServiceList, out removedServiceList);
  404:  
  405:             return serviceStateThatCrossedThresholdList;
  406:         }
  407:  
  408:         ////////////////////////////////////////////////////////////////////////////
  409:  
  410:         /// <summary>
  411:         ///
  412:         /// </summary>
  413:         public static Ia.Cl.Model.Result ManageSynchronization()
  414:         {
  415:             var result = new Ia.Cl.Model.Result();
  416:  
  417:             var addedList = new List<string>();
  418:             var removedList = new List<string>();
  419:  
  420:             foreach (var service in Ia.Ngn.Cl.Model.Data.MinistryDatabase.AddedServiceList)
  421:             {
  422:                 var task = Ia.Cl.Model.Http.PostAsync("http://ofn", "api/v2/service-request-administrative-issues/" + service);
  423:                 task.Wait();
  424:                 var v = task.Result;
  425:  
  426:                 if (v.Contains(@"""IsSuccessful"":true")) addedList.Add(service);
  427:             }
  428:  
  429:             foreach (var service in Ia.Ngn.Cl.Model.Data.MinistryDatabase.RemovedServiceList)
  430:             {
  431:                 var task = Ia.Cl.Model.Http.DeleteAsync("http://ofn", "api/v2/service-request-administrative-issues/" + service);
  432:                 task.Wait();
  433:                 var v = task.Result;
  434:  
  435:                 if (v.Contains(@"""IsSuccessful"":true")) removedList.Add(service);
  436:             }
  437:  
  438:             foreach (var v in addedList)
  439:             {
  440:                 Ia.Ngn.Cl.Model.Data.MinistryDatabase.AddedServiceList.Remove(v);
  441:             }
  442:  
  443:             foreach (var v in removedList)
  444:             {
  445:                 Ia.Ngn.Cl.Model.Data.MinistryDatabase.RemovedServiceList.Remove(v);
  446:             }
  447:  
  448:             var r = " added service list: [" + string.Join(" ", addedList) + "], removed service list: [" + string.Join(" ", removedList) + "] ";
  449:  
  450:             result.AddSuccess(r);
  451:  
  452:             return result;
  453:         }
  454:  
  455:         ////////////////////////////////////////////////////////////////////////////
  456:  
  457:         /// <summary>
  458:         ///
  459:         /// </summary>
  460:         public static Ia.Cl.Model.Result Information()
  461:         {
  462:             var result = new Ia.Cl.Model.Result();
  463:  
  464:             var r = "ExaminedServiceTransactionIdList count: " + Ia.Ngn.Cl.Model.Data.MinistryDatabase.ExaminedServiceTransactionIdList.Count + "\r\n"
  465:         + "AddedServiceList count: " + Ia.Ngn.Cl.Model.Data.MinistryDatabase.AddedServiceList.Count + "\r\n"
  466:         + "RemovedServiceList count: " + Ia.Ngn.Cl.Model.Data.MinistryDatabase.RemovedServiceList.Count + "\r\n"
  467:         + "ServiceStateThatCrossedThresholdList count: " + Ia.Ngn.Cl.Model.Data.MinistryDatabase.ServiceStateThatCrossedThresholdList.Count + "\r\n"
  468:         + "ServiceStateThatCrossedThresholdList: " + string.Join(", ", Ia.Ngn.Cl.Model.Data.MinistryDatabase.ServiceStateThatCrossedThresholdList.Select(u => u.Service)) + "\r\n"
  469:         + "ServiceTransactionList count: " + Ia.Ngn.Cl.Model.Data.MinistryDatabase.ServiceTransactionList.Count + "\r\n";
  470:  
  471:             result.AddSuccess(r);
  472:  
  473:             return result;
  474:         }
  475:  
  476:         ////////////////////////////////////////////////////////////////////////////
  477:  
  478:         /// <summary>
  479:         ///
  480:         /// </summary>
  481:         public static DataTable ReadHundredsSubdomainBalanceListItemDataTable(Ia.Ngn.Cl.Model.Business.Service.HundredsSubdomain hundredsSubdomain)
  482:         {
  483:             DataTable dateTable;
  484:  
  485:             var sql = Ia.Ngn.Cl.Model.Data.MinistryDatabase.OracleSqlCommandToReadBalanceForRangeOfAHundredsSubdomain(hundredsSubdomain);
  486:  
  487:             try
  488:             {
  489:                 dateTable = oracle.Select(sql);
  490:             }
  491:             catch (Exception)
  492:             {
  493:                 InitializeOracleConnection();
  494:  
  495:                 dateTable = oracle.Select(sql);
  496:             }
  497:  
  498:             if (dateTable != null) dateTable.TableName = sql;
  499:  
  500:             return dateTable;
  501:         }
  502:  
  503:         ////////////////////////////////////////////////////////////////////////////
  504:  
  505:         /// <summary>
  506:         ///
  507:         /// </summary>
  508:         public static DataTable ReadASingleServiceNumberBalanceDataTable(int serviceNumber)
  509:         {
  510:             DataTable dateTable;
  511:  
  512:             var sql = Ia.Ngn.Cl.Model.Data.MinistryDatabase.OracleSqlCommandToReadBalanceOfASingleServiceNumber(serviceNumber);
  513:  
  514:             try
  515:             {
  516:                 dateTable = oracle.Select(sql);
  517:             }
  518:             catch (Exception)
  519:             {
  520:                 InitializeOracleConnection();
  521:  
  522:                 dateTable = oracle.Select(sql);
  523:             }
  524:  
  525:             if (dateTable != null) dateTable.TableName = sql;
  526:  
  527:             return dateTable;
  528:         }
  529:  
  530:         ////////////////////////////////////////////////////////////////////////////
  531:  
  532:         /// <summary>
  533:         ///
  534:         /// </summary>
  535:         public static void SaveServiceStateThatCrossedThresholdListToFile()
  536:         {
  537:             var list = Ia.Ngn.Cl.Model.Data.MinistryDatabase.ServiceStateThatCrossedThresholdList;
  538:  
  539:             var jsonSerializerOptions = new JsonSerializerOptions
  540:             {
  541:                 WriteIndented = true
  542:             };
  543:  
  544:             var text = JsonSerializer.Serialize(list, jsonSerializerOptions);
  545:  
  546:             SaveContentInADateTimeNamedFileInArchive(text);
  547:         }
  548:  
  549:         ////////////////////////////////////////////////////////////////////////////
  550:  
  551:         /// <summary>
  552:         ///
  553:         /// </summary>
  554:         public static void ReadServiceStateThatCrossedThresholdListFromFile()
  555:         {
  556:             if (!ApplicationIsDisconnectedFromMinistryNetworkForDebugging)
  557:             {
  558:                 var text = ReadContentOfLatestFileInArchive();
  559:  
  560:                 if (!string.IsNullOrEmpty(text))
  561:                 {
  562:                     var list = JsonSerializer.Deserialize<List<Ia.Ngn.Cl.Model.Business.Mdaa.MinistryDatabase.ServiceState>>(text);
  563:  
  564:                     Ia.Ngn.Cl.Model.Data.MinistryDatabase.ServiceStateThatCrossedThresholdList = list.ToList();
  565:                 }
  566:             }
  567:         }
  568:  
  569:         ////////////////////////////////////////////////////////////////////////////
  570:  
  571:         /// <summary>
  572:         ///
  573:         /// </summary>
  574:         private static void SaveContentInADateTimeNamedFileInArchive(string content)
  575:         {
  576:             var now = DateTime.UtcNow.AddHours(3);
  577:  
  578:             var archiveDirectory = archive + now.ToString("yyyy-MM-dd") + @"\";
  579:             var archiveFileName = archiveDirectory + now.ToString("HH-mm-ss-fff") + @".txt";
  580:  
  581:             lock (objectLock)
  582:             {
  583:                 Directory.CreateDirectory(archiveDirectory);
  584:  
  585:                 File.WriteAllText(archiveFileName, content);
  586:             }
  587:         }
  588:  
  589:         ////////////////////////////////////////////////////////////////////////////
  590:  
  591:         /// <summary>
  592:         ///
  593:         /// </summary>
  594:         private static string ReadContentOfLatestFileInArchive()
  595:         {
  596:             string content;
  597:  
  598:             var now = DateTime.UtcNow.AddHours(3);
  599:  
  600:             var archiveDirectory = archive + now.ToString("yyyy-MM-dd") + @"\";
  601:  
  602:             lock (objectLock)
  603:             {
  604:                 var directoryInfo = Directory.CreateDirectory(archiveDirectory);
  605:  
  606:                 var file = (from f in directoryInfo.GetFiles()
  607:                             orderby f.LastWriteTime descending
  608:                             select f).FirstOrDefault();
  609:  
  610:                 if (file != null) content = File.ReadAllText(file.FullName);
  611:                 else content = string.Empty;
  612:             }
  613:  
  614:             return content;
  615:         }
  616:  
  617:         ////////////////////////////////////////////////////////////////////////////
  618:  
  619:         /// <summary>
  620:         ///
  621:         /// </summary>
  622:         private static DataTable ReadPaymentTransactionOfThePreviousNDaysServiceDataTable(long latestTransactionId, int previousNDays)
  623:         {
  624:             DataTable dateTable;
  625:  
  626:             var sql = Ia.Ngn.Cl.Model.Data.MinistryDatabase.OracleSqlCommandToReturnPaymentTransactionOfThePreviousNDays(latestTransactionId, previousNDays);
  627:  
  628:             try
  629:             {
  630:                 dateTable = oracle.Select(sql);
  631:             }
  632:             catch (Exception)
  633:             {
  634:                 InitializeOracleConnection();
  635:  
  636:                 dateTable = oracle.Select(sql);
  637:             }
  638:  
  639:             if (dateTable != null) dateTable.TableName = sql;
  640:  
  641:             return dateTable;
  642:         }
  643:  
  644:         ////////////////////////////////////////////////////////////////////////////
  645:         ////////////////////////////////////////////////////////////////////////////   
  646:     }
  647:  
  648:     ////////////////////////////////////////////////////////////////////////////
  649:     ////////////////////////////////////////////////////////////////////////////   
  650: }