)>}]
شركة التطبيقات المتكاملة لتصميم وبرمجة البرمجيات الخاصة ش.ش.و.
Integrated Applications Programming Company
Home » Code Library » Default (Ia.Ftn.Cl.Model.Business.Mdaa)

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 Fixed Telecommunications Network business model

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