@@ -98,7 +98,7 @@ public async Task<ProcessLogonTransactionResponse> ProcessLogonTransaction(Guid
9898 transactionAggregate . StartTransaction ( transactionDateTime , transactionNumber , transactionType , estateId , merchantId , deviceIdentifier ) ;
9999 await transactionAggregateRepository . SaveChanges ( transactionAggregate , cancellationToken ) ;
100100
101- ( String responseMessage , TransactionResponseCode responseCode ) validationResult = await this . ValidateTransaction ( estateId , merchantId , deviceIdentifier , transactionType , cancellationToken ) ;
101+ ( String responseMessage , TransactionResponseCode responseCode ) validationResult = await this . ValidateLogonTransaction ( estateId , merchantId , deviceIdentifier , cancellationToken ) ;
102102
103103 if ( validationResult . responseCode == TransactionResponseCode . Success )
104104 {
@@ -138,7 +138,7 @@ public async Task<ProcessLogonTransactionResponse> ProcessLogonTransaction(Guid
138138 /// <param name="transactionDateTime">The transaction date time.</param>
139139 /// <param name="transactionNumber">The transaction number.</param>
140140 /// <param name="deviceIdentifier">The device identifier.</param>
141- /// <param name="operatorId ">The operator identifier.</param>
141+ /// <param name="operatorIdentifier ">The operator identifier.</param>
142142 /// <param name="additionalTransactionMetadata">The additional transaction metadata.</param>
143143 /// <param name="cancellationToken">The cancellation token.</param>
144144 /// <returns></returns>
@@ -148,7 +148,7 @@ public async Task<ProcessSaleTransactionResponse> ProcessSaleTransaction(Guid tr
148148 DateTime transactionDateTime ,
149149 String transactionNumber ,
150150 String deviceIdentifier ,
151- String operatorId ,
151+ String operatorIdentifier ,
152152 Dictionary < String , String > additionalTransactionMetadata ,
153153 CancellationToken cancellationToken )
154154 {
@@ -161,13 +161,13 @@ public async Task<ProcessSaleTransactionResponse> ProcessSaleTransaction(Guid tr
161161 transactionAggregate . StartTransaction ( transactionDateTime , transactionNumber , transactionType , estateId , merchantId , deviceIdentifier ) ;
162162 await transactionAggregateRepository . SaveChanges ( transactionAggregate , cancellationToken ) ;
163163
164- ( String responseMessage , TransactionResponseCode responseCode ) validationResult = await this . ValidateTransaction ( estateId , merchantId , deviceIdentifier , transactionType , cancellationToken ) ;
164+ ( String responseMessage , TransactionResponseCode responseCode ) validationResult = await this . ValidateSaleTransaction ( estateId , merchantId , deviceIdentifier , operatorIdentifier , cancellationToken ) ;
165165
166166 if ( validationResult . responseCode == TransactionResponseCode . Success )
167167 {
168168 // TODO: Do the online processing with the operator here
169169 MerchantResponse merchant = await this . GetMerchant ( estateId , merchantId , cancellationToken ) ;
170- IOperatorProxy operatorProxy = OperatorProxyResolver ( operatorId ) ;
170+ IOperatorProxy operatorProxy = OperatorProxyResolver ( operatorIdentifier ) ;
171171 await operatorProxy . ProcessSaleMessage ( transactionId , merchant , transactionDateTime , additionalTransactionMetadata , cancellationToken ) ;
172172
173173 // Record the successful validation
@@ -198,57 +198,131 @@ public async Task<ProcessSaleTransactionResponse> ProcessSaleTransaction(Guid tr
198198 } ;
199199 }
200200
201+ /// <summary>
202+ /// Validates the transaction.
203+ /// </summary>
204+ /// <param name="estateId">The estate identifier.</param>
205+ /// <param name="merchantId">The merchant identifier.</param>
206+ /// <param name="cancellationToken">The cancellation token.</param>
207+ /// <returns></returns>
208+ /// <exception cref="TransactionValidationException">
209+ /// Estate Id [{estateId}] is not a valid estate
210+ /// or
211+ /// Merchant Id [{merchantId}] is not a valid merchant for estate [{estate.EstateName}]
212+ /// </exception>
213+ private async Task < ( EstateResponse estate , MerchantResponse merchant ) > ValidateTransaction ( Guid estateId ,
214+ Guid merchantId , CancellationToken cancellationToken )
215+ {
216+ EstateResponse estate = null ;
217+ // Validate the Estate Record is a valid estate
218+ try
219+ {
220+ estate = await this . GetEstate ( estateId , cancellationToken ) ;
221+ }
222+ catch ( Exception ex ) when ( ex . InnerException != null && ex . InnerException . GetType ( ) == typeof ( KeyNotFoundException ) )
223+ {
224+ throw new TransactionValidationException ( $ "Estate Id [{ estateId } ] is not a valid estate", TransactionResponseCode . InvalidEstateId ) ;
225+ }
226+
227+ // get the merchant record and validate the device
228+ // TODO: Token
229+ MerchantResponse merchant = await this . GetMerchant ( estateId , merchantId , cancellationToken ) ;
230+
231+ // TODO: Remove this once GetMerchant returns correct response when merchant not found
232+ if ( merchant . MerchantName == null )
233+ {
234+ throw new TransactionValidationException ( $ "Merchant Id [{ merchantId } ] is not a valid merchant for estate [{ estate . EstateName } ]",
235+ TransactionResponseCode . InvalidMerchantId ) ;
236+ }
237+
238+ return ( estate , merchant ) ;
239+ }
240+
201241 /// <summary>
202242 /// Validates the transaction.
203243 /// </summary>
204244 /// <param name="estateId">The estate identifier.</param>
205245 /// <param name="merchantId">The merchant identifier.</param>
206246 /// <param name="deviceIdentifier">The device identifier.</param>
207- /// <param name="transactionType">Type of the transaction.</param>
208247 /// <param name="cancellationToken">The cancellation token.</param>
209248 /// <returns></returns>
210249 /// <exception cref="TransactionProcessor.BusinessLogic.Services.TransactionValidationException">Device Identifier {deviceIdentifier} not valid for Merchant {merchant.MerchantName}</exception>
211- private async Task < ( String responseMessage , TransactionResponseCode responseCode ) > ValidateTransaction ( Guid estateId ,
250+ private async Task < ( String responseMessage , TransactionResponseCode responseCode ) > ValidateLogonTransaction ( Guid estateId ,
212251 Guid merchantId ,
213252 String deviceIdentifier ,
214- TransactionType transactionType ,
215253 CancellationToken cancellationToken )
216254 {
217255 try
218256 {
219- EstateResponse estate = null ;
220- // Validate the Estate Record is a valid estate
221- try
257+ ( EstateResponse estate , MerchantResponse merchant ) validateTransactionResponse = await this . ValidateTransaction ( estateId , merchantId , cancellationToken ) ;
258+ MerchantResponse merchant = validateTransactionResponse . merchant ;
259+
260+ // Device Validation
261+ if ( merchant . Devices == null || merchant . Devices . Any ( ) == false )
222262 {
223- estate = await this . GetEstate ( estateId , cancellationToken ) ;
263+ await this . AddDeviceToMerchant ( estateId , merchantId , deviceIdentifier , cancellationToken ) ;
224264 }
225- catch ( Exception ex ) when ( ex . InnerException != null && ex . InnerException . GetType ( ) == typeof ( KeyNotFoundException ) )
265+ else
226266 {
227- throw new TransactionValidationException ( $ "Estate Id [{ estateId } ] is not a valid estate", TransactionResponseCode . InvalidEstateId ) ;
228- }
229-
230- // get the merchant record and validate the device
231- // TODO: Token
232- MerchantResponse merchant = await this . GetMerchant ( estateId , merchantId , cancellationToken ) ;
267+ // Validate the device
268+ KeyValuePair < Guid , String > device = merchant . Devices . SingleOrDefault ( d => d . Value == deviceIdentifier ) ;
233269
234- // TODO: Remove this once GetMerchant returns correct response when merchant not found
235- if ( merchant . MerchantName == null )
236- {
237- throw new TransactionValidationException ( $ "Merchant Id [{ merchantId } ] is not a valid merchant for estate [{ estate . EstateName } ]",
238- TransactionResponseCode . InvalidMerchantId ) ;
270+ if ( device . Key == Guid . Empty )
271+ {
272+ // Device not found,throw error
273+ throw new TransactionValidationException ( $ "Device Identifier { deviceIdentifier } not valid for Merchant { merchant . MerchantName } ",
274+ TransactionResponseCode . InvalidDeviceIdentifier ) ;
275+ }
239276 }
277+
278+ // If we get here everything is good
279+ return ( "SUCCESS" , TransactionResponseCode . Success ) ;
280+ }
281+ catch ( TransactionValidationException tvex )
282+ {
283+ return ( tvex . Message , tvex . ResponseCode ) ;
284+ }
285+ }
240286
287+ /// <summary>
288+ /// Validates the sale transaction.
289+ /// </summary>
290+ /// <param name="estateId">The estate identifier.</param>
291+ /// <param name="merchantId">The merchant identifier.</param>
292+ /// <param name="deviceIdentifier">The device identifier.</param>
293+ /// <param name="operatorIdentifier">The operator identifier.</param>
294+ /// <param name="cancellationToken">The cancellation token.</param>
295+ /// <returns></returns>
296+ /// <exception cref="TransactionValidationException">
297+ /// Merchant {merchant.MerchantName} has no valid Devices for this transaction.
298+ /// or
299+ /// Device Identifier {deviceIdentifier} not valid for Merchant {merchant.MerchantName}
300+ /// or
301+ /// Estate {estate.EstateName} has no operators defined
302+ /// or
303+ /// Operator {operatorIdentifier} not configured for Estate [{estate.EstateName}]
304+ /// or
305+ /// Merchant {merchant.MerchantName} has no operators defined
306+ /// or
307+ /// Operator {operatorIdentifier} not configured for Merchant [{merchant.MerchantName}]
308+ /// </exception>
309+ private async Task < ( String responseMessage , TransactionResponseCode responseCode ) > ValidateSaleTransaction ( Guid estateId ,
310+ Guid merchantId ,
311+ String deviceIdentifier ,
312+ String operatorIdentifier ,
313+ CancellationToken cancellationToken )
314+ {
315+ try
316+ {
317+ ( EstateResponse estate , MerchantResponse merchant ) validateTransactionResponse = await this . ValidateTransaction ( estateId , merchantId , cancellationToken ) ;
318+ EstateResponse estate = validateTransactionResponse . estate ;
319+ MerchantResponse merchant = validateTransactionResponse . merchant ;
320+
321+ // Device Validation
241322 if ( merchant . Devices == null || merchant . Devices . Any ( ) == false )
242323 {
243- if ( transactionType == TransactionType . Logon )
244- {
245- await this . AddDeviceToMerchant ( estateId , merchantId , deviceIdentifier , cancellationToken ) ;
246- }
247- else
248- {
249- throw new TransactionValidationException ( $ "Merchant { merchant . MerchantName } has no valid Devices for this transaction.",
250- TransactionResponseCode . NoValidDevices ) ;
251- }
324+ throw new TransactionValidationException ( $ "Merchant { merchant . MerchantName } has no valid Devices for this transaction.",
325+ TransactionResponseCode . NoValidDevices ) ;
252326 }
253327 else
254328 {
@@ -263,19 +337,46 @@ public async Task<ProcessSaleTransactionResponse> ProcessSaleTransaction(Guid tr
263337 }
264338 }
265339
340+ // Operator Validation (Estate)
341+ if ( estate . Operators == null || estate . Operators . Any ( ) == false )
342+ {
343+ throw new TransactionValidationException ( $ "Estate { estate . EstateName } has no operators defined",
344+ TransactionResponseCode . NoEstateOperators ) ;
345+ }
346+ else
347+ {
348+ // Operators have been configured for the estate
349+ EstateOperatorResponse operatorRecord = estate . Operators . SingleOrDefault ( o => o . Name == operatorIdentifier ) ;
350+ if ( operatorRecord == null )
351+ {
352+ throw new TransactionValidationException ( $ "Operator { operatorIdentifier } not configured for Estate [{ estate . EstateName } ]", TransactionResponseCode . OperatorNotValidForEstate ) ;
353+ }
354+ }
355+
356+ // Operator Validation (Merchant)
357+ if ( merchant . Operators == null || merchant . Operators . Any ( ) == false )
358+ {
359+ throw new TransactionValidationException ( $ "Merchant { merchant . MerchantName } has no operators defined",
360+ TransactionResponseCode . NoEstateOperators ) ;
361+ }
362+ else
363+ {
364+ // Operators have been configured for the estate
365+ MerchantOperatorResponse operatorRecord = merchant . Operators . SingleOrDefault ( o => o . Name == operatorIdentifier ) ;
366+ if ( operatorRecord == null )
367+ {
368+ throw new TransactionValidationException ( $ "Operator { operatorIdentifier } not configured for Merchant [{ merchant . MerchantName } ]", TransactionResponseCode . OperatorNotValidForMerchant ) ;
369+ }
370+ }
371+
372+
266373 // If we get here everything is good
267374 return ( "SUCCESS" , TransactionResponseCode . Success ) ;
268375 }
269376 catch ( TransactionValidationException tvex )
270377 {
271378 return ( tvex . Message , tvex . ResponseCode ) ;
272379 }
273- catch ( Exception ex )
274- {
275- Logger . LogError ( ex ) ;
276- return ( "Unspecified Processing Error" , TransactionResponseCode . UnknownFailure ) ;
277- }
278-
279380 }
280381
281382 private TokenResponse TokenResponse ;
0 commit comments