1+ namespace TransactionProcessing . SchedulerService . Jobs ;
2+
3+ using System ;
4+ using System . Collections . Generic ;
5+ using System . Data ;
6+ using System . Linq ;
7+ using System . Net . Http ;
8+ using System . Text ;
9+ using System . Threading ;
10+ using System . Threading . Tasks ;
11+ using DataGeneration ;
12+ using EstateManagement . DataTransferObjects . Responses ;
13+ using EventStore . Client ;
14+ using MessagingService . Client ;
15+ using MessagingService . DataTransferObjects ;
16+ using Microsoft . Data . SqlClient ;
17+ using Newtonsoft . Json ;
18+
19+ public static class Jobs {
20+ public static async Task GenerateMerchantStatements ( ITransactionDataGenerator t , Guid estateId , CancellationToken cancellationToken ) {
21+ List < MerchantResponse > merchants = await t . GetMerchants ( estateId , cancellationToken ) ;
22+ foreach ( MerchantResponse merchantResponse in merchants )
23+ {
24+ await t . GenerateMerchantStatement ( merchantResponse . EstateId , merchantResponse . MerchantId , DateTime . Now , cancellationToken ) ;
25+ }
26+ }
27+
28+ public static async Task GenerateFileUploads ( ITransactionDataGenerator t , Guid estateId , Guid merchantId , CancellationToken cancellationToken )
29+ {
30+ MerchantResponse merchant = await t . GetMerchant ( estateId , merchantId , cancellationToken ) ;
31+
32+ List < ContractResponse > contracts = await t . GetMerchantContracts ( merchant , cancellationToken ) ;
33+ DateTime fileDate = DateTime . Now ;
34+ foreach ( ContractResponse contract in contracts )
35+ {
36+ // Generate a file and upload
37+ await t . SendUploadFile ( fileDate , contract , merchant , cancellationToken ) ;
38+ }
39+ }
40+
41+ public static async Task GenerateTransactions ( ITransactionDataGenerator t , Guid estateId , Guid merchantId , Boolean requireLogon , CancellationToken cancellationToken )
42+ {
43+ // get the merchant
44+ MerchantResponse merchant = await t . GetMerchant ( estateId , merchantId , cancellationToken ) ;
45+
46+ DateTime transactionDate = DateTime . Now ;
47+
48+ if ( requireLogon )
49+ {
50+ // Do a logon transaction for the merchant
51+ await t . PerformMerchantLogon ( transactionDate , merchant , cancellationToken ) ;
52+ }
53+
54+ // Get the merchants contracts
55+ List < ContractResponse > contracts = await t . GetMerchantContracts ( merchant , cancellationToken ) ;
56+
57+ foreach ( ContractResponse contract in contracts )
58+ {
59+ // Generate and send some sales
60+ await t . SendSales ( transactionDate , merchant , contract , cancellationToken ) ;
61+
62+ // Generate a file and upload
63+ await t . SendUploadFile ( transactionDate , contract , merchant , cancellationToken ) ;
64+ }
65+ }
66+
67+ public static async Task PerformSettlement ( ITransactionDataGenerator t , DateTime dateTime , Guid estateId , CancellationToken cancellationToken )
68+ {
69+ await t . PerformSettlement ( dateTime , estateId , cancellationToken ) ;
70+ }
71+
72+ public static async Task < List < ( String groupName , String streamName , Int64 parkedMessageCount ) > > GetParkedQueueInformation ( String eventStoreConnectionString , CancellationToken cancellationToken ) {
73+ EventStoreClientSettings clientSettings = EventStoreClientSettings . Create ( eventStoreConnectionString ) ;
74+ EventStore . Client . EventStorePersistentSubscriptionsClient client = new EventStorePersistentSubscriptionsClient ( clientSettings ) ;
75+ List < ( String groupName , String streamName , Int64 parkedMessageCount ) > result = new List < ( String groupName , String streamName , Int64 parkedMessageCount ) > ( ) ;
76+ IEnumerable < PersistentSubscriptionInfo > x = await client . ListAllAsync ( cancellationToken : cancellationToken ) ;
77+ foreach ( PersistentSubscriptionInfo persistentSubscriptionInfo in x ) {
78+ if ( persistentSubscriptionInfo . Stats . ParkedMessageCount > 0 ) {
79+ // Add to replay list
80+ result . Add ( ( persistentSubscriptionInfo . GroupName , persistentSubscriptionInfo . EventSource , persistentSubscriptionInfo . Stats . ParkedMessageCount ) ) ;
81+ }
82+ }
83+
84+ return result ;
85+ }
86+
87+ public static async Task < List < ( Guid , String , DateTime , String ) > > GetIncompleteFileList ( String databaseConnectionString , CancellationToken cancellationToken ) {
88+ List < ( Guid , String , DateTime , String ) > result = new List < ( Guid , String , DateTime , String ) > ( ) ;
89+
90+ using ( SqlConnection connection = new SqlConnection ( databaseConnectionString ) ) {
91+ await connection . OpenAsync ( cancellationToken ) ;
92+
93+ SqlCommand command = connection . CreateCommand ( ) ;
94+ command . CommandText = "select FileId, FileLocation, FileReceivedDateTime, merchant.Name from [file] f inner join merchant on merchant.MerchantId = f.MerchantId where IsCompleted= 0" ;
95+ command . CommandType = CommandType . Text ;
96+
97+ var reader = await command . ExecuteReaderAsync ( cancellationToken ) ;
98+
99+ while ( await reader . ReadAsync ( cancellationToken ) ) {
100+
101+ var fileId = reader . GetGuid ( 0 ) ;
102+ var fileLocation = reader . GetString ( 1 ) ;
103+ var fileReceivedDateTime = reader . GetDateTime ( 2 ) ;
104+ var merchantName = reader . GetString ( 3 ) ;
105+
106+ result . Add ( ( fileId , fileLocation , fileReceivedDateTime , merchantName ) ) ;
107+ }
108+ }
109+
110+ return result ;
111+ }
112+
113+ public static SendEmailRequest BuildSupportEmail ( DateTime dateTime ,
114+ List < ( Guid fileId , String fileLocation , DateTime fileReceivedDateTime , String merchantName ) > incompleteFiles ,
115+ List < ( String groupName , String streamName , Int64 parkedMessageCount ) > parkedQueueInformation )
116+ {
117+ // Build uo the HTML String
118+ StringBuilder htmlBuilder = new StringBuilder ( ) ;
119+
120+ htmlBuilder . AppendLine ( "<html>" ) ;
121+ htmlBuilder . AppendLine ( "<head>" ) ;
122+ htmlBuilder . AppendLine ( "<style>" ) ;
123+ htmlBuilder . AppendLine ( "table, th, td { border: 1px solid black; }" ) ;
124+ htmlBuilder . AppendLine ( "</style>" ) ;
125+ htmlBuilder . AppendLine ( "</head>" ) ;
126+
127+ htmlBuilder . AppendLine ( "<body>" ) ;
128+
129+ htmlBuilder . AppendLine ( $ "<h1>Daily Support Report for { dateTime . ToString ( "dd-MM-yyyy" ) } </h1>") ;
130+
131+ htmlBuilder . AppendLine ( "<h2>Parked Messages Stats</h2>" ) ;
132+
133+ if ( parkedQueueInformation . Any ( ) == false ) {
134+ htmlBuilder . AppendLine ( "<p>No Data</p>" ) ;
135+ }
136+ else {
137+ htmlBuilder . AppendLine ( "<table>" ) ;
138+ htmlBuilder . Append ( "<tr><th>Group</th><th>Stream</th><th>Parked Messages</th></tr>" ) ;
139+
140+ foreach ( ( String groupName , String streamName , Int64 parkedMessageCount ) info in parkedQueueInformation ) {
141+ htmlBuilder . Append ( $ "<tr><td>{ info . groupName } </td><td>{ info . streamName } </td><td>{ info . parkedMessageCount } </td></tr>") ;
142+ }
143+
144+ htmlBuilder . AppendLine ( "</table>" ) ;
145+ }
146+
147+ htmlBuilder . AppendLine ( "<h2>Incomplete Bulk Files</h2>" ) ;
148+
149+ if ( incompleteFiles . Any ( ) == false )
150+ {
151+ htmlBuilder . AppendLine ( "<p>No Data</p>" ) ;
152+ }
153+ else
154+ {
155+ htmlBuilder . AppendLine ( "<table>" ) ;
156+ htmlBuilder . Append ( "<tr><th>Id</th><th>Location</th><th>File Received</th><th>Merchant Name</th></tr>" ) ;
157+
158+ foreach ( ( Guid fileId , String fileLocation , DateTime fileReceivedDateTime , String merchantName ) incompleteFile in incompleteFiles ) {
159+
160+ htmlBuilder . Append ( $ "<tr><td>{ incompleteFile . fileId } </td><td>{ incompleteFile . fileLocation } </td><td>{ incompleteFile . fileReceivedDateTime } </td><td>{ incompleteFile . merchantName } </td></tr>") ;
161+ }
162+
163+ htmlBuilder . AppendLine ( "</table>" ) ;
164+ }
165+
166+ htmlBuilder . AppendLine ( "</body>" ) ;
167+ htmlBuilder . AppendLine ( "</html>" ) ;
168+
169+ SendEmailRequest request = new SendEmailRequest {
170+ Body = htmlBuilder . ToString ( ) ,
171+ ConnectionIdentifier = Guid . NewGuid ( ) ,
172+ FromAddress = "support@transactionprocessing.com" ,
173+ IsHtml = true ,
174+ MessageId = Guid . NewGuid ( ) ,
175+ Subject = $ "Daily Support Report for { dateTime : dd-MM-yyyy} ",
176+ ToAddresses = new List < String > {
177+ "stuart_ferguson1development@outlook.com"
178+ }
179+ } ;
180+ return request ;
181+ }
182+
183+ public static async Task SendSupportEmail ( DateTime dateTime ,
184+ String accessToken ,
185+ String eventStoreConnectionString , String databaseConnectionString , List < String > estateIds ,
186+ IMessagingServiceClient messagingServiceClient ,
187+ CancellationToken cancellationToken )
188+ {
189+ List < ( String groupName , String streamName , Int64 parkedMessageCount ) > parkedQueueInfo = await Jobs . GetParkedQueueInformation ( eventStoreConnectionString , cancellationToken ) ;
190+ List < ( Guid , String , DateTime , String ) > incompleteFiles = new List < ( Guid , String , DateTime , String ) > ( ) ;
191+ foreach ( String estateId in estateIds ) {
192+ String connectionString = databaseConnectionString . Replace ( "<estateid>" , estateId . ToString ( ) ) ;
193+ incompleteFiles . AddRange ( await GetIncompleteFileList ( connectionString , cancellationToken ) ) ;
194+ }
195+
196+ SendEmailRequest emailRequest = BuildSupportEmail ( dateTime , incompleteFiles , parkedQueueInfo ) ;
197+ emailRequest . ConnectionIdentifier = Guid . Parse ( estateIds . First ( ) ) ;
198+ await messagingServiceClient . SendEmail ( accessToken , emailRequest , CancellationToken . None ) ;
199+ }
200+ }
0 commit comments