/// <summary> /// Process Linked InfoCodes for TenderLineItem /// </summary> /// <param name="posTransaction"></param> /// <param name="tenderLineItem"></param> /// <param name="storeId"></param> /// <param name="tableRefId"></param> /// <param name="infoCodeType"></param> public void ProcessLinkedInfoCodes(IPosTransaction posTransaction, ITenderLineItem tenderLineItem, string storeId, InfoCodeTableRefType tableRefId, InfoCodeType infoCodeType) { TenderLineItem lineItem = tenderLineItem as TenderLineItem; if (lineItem == null) { NetTracer.Warning("tenderLineItem parameter is null"); throw new ArgumentNullException("tenderLineItem"); } //Loop while a linkedInfoCode is found int i = 0; //Set as a stop for a infinite loop LinkedListNode <InfoCodeLineItem> infoCodeItem = lineItem.InfoCodeLines.Last; if (infoCodeItem != null) { while (!string.IsNullOrEmpty(infoCodeItem.Value.LinkedInfoCodeId) && (i < 10)) { ProcessInfoCode(posTransaction, 0, lineItem.Amount, storeId, lineItem.TenderTypeId, lineItem.CurrencyCode, tableRefId, infoCodeItem.Value.LinkedInfoCodeId, infoCodeItem.Value, infoCodeType); // This is to prevent an infinite loop when infocodes link to themselves.. if (infoCodeItem.Value.LinkedInfoCodeId == lineItem.InfoCodeLines.Last.Value.LinkedInfoCodeId) { break; } infoCodeItem = lineItem.InfoCodeLines.Last; i++; } } }
static void RespondToCardRedemptionRequest(SerialBeacon beacon, Dictionary <string, object> requestInfo) { var barcode = (string)requestInfo[Constants.WALLET_CARD_BARCODE_TINY_KEY]; var merchantID = (string)requestInfo[Constants.WALLET_MERCHANT_ID_TINY_KEY]; var transactionID = (string)requestInfo[Constants.WALLET_TRANSACTION_ID_TINY_KEY]; var deviceID = (string)requestInfo[Constants.WALLET_DEVICE_ID_TINY_KEY]; decimal?amount = null; if (requestInfo.ContainsKey(Constants.WALLET_AMOUNT_TINY_KEY)) { var amountString = (string)requestInfo[Constants.WALLET_AMOUNT_TINY_KEY]; if (!String.IsNullOrEmpty(amountString)) { amount = decimal.Parse(amountString); } } var errors = new List <byte>(); if (string.IsNullOrEmpty(barcode)) { Console.WriteLine("Barcode missing."); errors.Add((byte)eWalletErrors.CardBarcodeMissing); } if (string.IsNullOrEmpty(merchantID)) { Console.WriteLine("Merchant ID missing."); errors.Add((byte)eWalletErrors.MerchantIDMissing); } if (string.IsNullOrEmpty(transactionID)) { Console.WriteLine("Transaction ID missing."); errors.Add((byte)eWalletErrors.TransactionIDMissing); } if (errors.Count > 0) { RespondToBleDataRequestWithErrors(beacon, requestInfo, errors); return; } var transaction = _demoDataSource.GetTransaction(transactionID); if (transaction == null) { Console.WriteLine("Transaction {0} not found.", transactionID); errors.Add((byte)eWalletErrors.TransactionNotFound); } else if (transaction.IsCanceled) { Console.WriteLine("Transaction {0} was previously canceled at {1}.", transactionID, transaction.CanceledAt); errors.Add((byte)eWalletErrors.TransactionCanceled); } else if (transaction.IsComplete) { Console.WriteLine("Transaction {0} completed.", transactionID); errors.Add((byte)eWalletErrors.TransactionCompleted); } else if (amount.HasValue && Decimal.Compare(amount.Value, transaction.RemainingAmount) > 0) { Console.WriteLine("Amount {0:0.00} exceeds remaining amount {1:0.00} on transaction {2}.", amount.Value, transaction.RemainingAmount, transactionID); errors.Add((byte)eWalletErrors.SpecifiedAmountExceedsRemainingAmount); } var card = _demoDataSource.GetCard(merchantID, barcode); if (card == null) { Console.WriteLine("Card {0} for merchant {1} not found.", barcode, merchantID); errors.Add((byte)eWalletErrors.CardNotFound); } else if (amount.HasValue && Decimal.Compare(amount.Value, card.CurrentBalance) > 0) { Console.WriteLine("Card {0} balance {1:0.00} less than amount {2:0.00} specified.", barcode, card.CurrentBalance, amount.Value); errors.Add((byte)eWalletErrors.CardBalanceInsufficient); } if (errors.Count > 0) { RespondToBleDataRequestWithErrors(beacon, requestInfo, errors); return; } var item = new TenderLineItem { Card = card, DeviceID = deviceID, }; transaction.AddTenderLineItem(item); if (amount.HasValue) { item.Amount = amount.Value; card.CurrentBalance = card.CurrentBalance - amount.Value; transaction.RemainingAmount = transaction.RemainingAmount - amount.Value; } else if (Decimal.Compare(transaction.RemainingAmount, card.CurrentBalance) >= 0) { item.Amount = card.CurrentBalance; transaction.RemainingAmount = transaction.RemainingAmount - card.CurrentBalance; card.CurrentBalance = 0.00M; } else { item.Amount = transaction.RemainingAmount; card.CurrentBalance = card.CurrentBalance - transaction.RemainingAmount; transaction.RemainingAmount = 0.00M; } var responseInfo = new Dictionary <string, object>(requestInfo); responseInfo[Constants.WALLET_CARD_CURRENT_BALANCE_TINY_KEY] = card.CurrentBalance.ToString("0.00"); responseInfo[Constants.WALLET_TRANSACTION_REMAINING_AMOUNT_TINY_KEY] = transaction.RemainingAmount.ToString("0.00"); var responseData = DictionarySerializer.SerializeToByteArray(responseInfo); if (responseData != null) { try { Console.WriteLine("Canceling data blocks."); beacon.CancelDataBlocks(); Console.WriteLine("Data request response: {0}.", JsonConvert.SerializeObject(responseInfo)); beacon.RespondToBleDataRequest(responseData); if (Decimal.Compare(transaction.RemainingAmount, 0.0M) > 0) { TenderCard(transaction); } } catch { } } else { Console.WriteLine("Serialization failed for card redemption request response."); RespondToBleDataRequestWithErrors(beacon, requestInfo, new List <byte> { (byte)eWalletErrors.SerializationFailed }); } }