示例#1
0
        // returns the last outstanding request; status in (processing, vending) and within a timeout interval
        public static VendingRequest LastOutstandingRequest()
        {
            using (klick_vending_machineEntities context = new klick_vending_machineEntities())
            {
                int processingTimeoutSeconds = 30;
                int vendingTimeoutSeconds    = 60;

                // request in status 'processing'
                VendingRequest request = (
                    from r in context.VendingRequests
                    where r.Status == "processing" && SqlFunctions.DateDiff("second", r.RequestDate, DateTime.Now) < processingTimeoutSeconds
                    orderby r.RequestDate descending
                    select r).FirstOrDefault();

                if (request != null)
                {
                    return(request);
                }

                request = (
                    from r in context.VendingRequests
                    where r.Status == "vending" && SqlFunctions.DateDiff("second", r.VendStartDate, DateTime.Now) < vendingTimeoutSeconds
                    orderby r.VendStartDate descending
                    select r).FirstOrDefault();

                return(request);
            }
        }
        // returns the last outstanding request; status in (processing, vending) and within a timeout interval
        public static VendingRequest LastOutstandingRequest()
        {
            using (klick_vending_machineEntities context = new klick_vending_machineEntities())
            {
                int processingTimeoutSeconds = 30;
                int vendingTimeoutSeconds = 60;

                // request in status 'processing'
                VendingRequest request = (
                    from r in context.VendingRequests
                    where r.Status == "processing" && SqlFunctions.DateDiff("second", r.RequestDate, DateTime.Now) < processingTimeoutSeconds
                    orderby r.RequestDate descending
                    select r).FirstOrDefault();

                if (request != null)
                {
                    return request;
                }

                request = (
                    from r in context.VendingRequests
                    where r.Status == "vending" && SqlFunctions.DateDiff("second", r.VendStartDate, DateTime.Now) < vendingTimeoutSeconds
                    orderby r.VendStartDate descending
                    select r).FirstOrDefault();

                return request;
            }
        }
示例#3
0
 // returns the most recent card scan
 public static CardScan LastCardScan()
 {
     using (klick_vending_machineEntities context = new klick_vending_machineEntities())
     {
         CardScan cs = (
             from c in context.CardScans orderby c.ScanDate descending
             select c).FirstOrDefault();
         return(cs);
     }
 }
 // returns the most recent card scan
 public static CardScan LastCardScan()
 {
     using (klick_vending_machineEntities context = new klick_vending_machineEntities())
     {
         CardScan cs = (
             from c in context.CardScans orderby c.ScanDate descending
             select c).FirstOrDefault();
         return cs;
     }
 }
示例#5
0
 public static Error CreateError(Exception e)
 {
     using (klick_vending_machineEntities context = new klick_vending_machineEntities())
     {
         Error error = new Error(e);
         context.Errors.Add(error);
         context.SaveChanges();
         return error;
     }
 }
示例#6
0
 public static Error CreateError(Exception e)
 {
     using (klick_vending_machineEntities context = new klick_vending_machineEntities())
     {
         Error error = new Error(e);
         context.Errors.Add(error);
         context.SaveChanges();
         return(error);
     }
 }
示例#7
0
 // returns true if a successful vend request is associated with this card scan
 // OTHER than the current request that we've started
 public bool HasVended(long currentVendingRequestID)
 {
     using (klick_vending_machineEntities context = new klick_vending_machineEntities())
     {
         int count = (
             from r in context.VendingRequests
             join c in context.CardScanResults on r.CardScanResultID equals c.CardScanResultID
             where r.Status != "failed" &&
             c.CardScanID == CardScanID &&
             r.VendingRequestID != currentVendingRequestID
             select r).Count();
         return(count > 0);
     }
 }
 // returns true if a successful vend request is associated with this card scan
 // OTHER than the current request that we've started
 public bool HasVended(long currentVendingRequestID)
 {
     using (klick_vending_machineEntities context = new klick_vending_machineEntities())
     {
         int count = (
             from r in context.VendingRequests
             join c in context.CardScanResults on r.CardScanResultID equals c.CardScanResultID
             where r.Status != "failed"
             && c.CardScanID == CardScanID
             && r.VendingRequestID != currentVendingRequestID
             select r).Count();
         return count > 0;
     }
 }
        private static CardScanResult GetCardScanResult(CardScan cardScan)
        {
            // now we have to create a result, and validate against the keyscan database
            using(klick_vending_machineEntities context = new klick_vending_machineEntities()) {
                CardScanResult result = new CardScanResult()
                {
                    CardScanID = cardScan.CardScanID,
                    ResultDate = DateTime.Now,
                    Status = "invalid"
                };

                context.CardScanResults.Add(result);

                try {
                    string hexID = cardScan.CardID.Replace(" ", ""); // strip out extra spaces

                    // assert correct length
                    if (hexID.Length == 16)
                    {
                        // take the last 4 octets only (this is a 16-digit string)
                        hexID = hexID.Substring(8);

                        string binaryID = String.Join(String.Empty,
                          hexID.Select(
                            c => Convert.ToString(Convert.ToInt32(c.ToString(), 16), 2).PadLeft(4, '0')
                          )
                        );

                        // card batch = 8 digits, starting at digit 7
                        // card id = 15 digits, starting at digit 16
                        string binaryCardBatch = binaryID.Substring(7, 8);
                        string binaryCardNumber = binaryID.Substring(16, 15);

                        // convert to decimal, then padded string (3-digit batch, 5-digit number)
                        result.CardBatch = Convert.ToInt64(binaryCardBatch, 2).ToString().PadLeft(3, '0');
                        result.CardNumber = Convert.ToInt64(binaryCardNumber, 2).ToString().PadLeft(5, '0');

                        // lookup card in keyscan database and validate, and grab first and lastname

                        SqlConnection o_sqlConnection = new SqlConnection();
                        o_sqlConnection.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["keyscandb"].ConnectionString;
                        o_sqlConnection.Open();
                        SqlCommand o_sqlCommand = new SqlCommand();
                        o_sqlCommand.CommandText = "Select * from CARD where CARD_BATCH = " + result.CardBatch + " and CARD_NUMBER = " + result.CardNumber + " and isnull([CARD_VALIDFROM], getdate()-1) < Getdate() and isnull([CARD_VALIDTO], getdate() + 1) > getdate() and isnull([CARD_ARCHIVED],0) = 0 and isnull([CARD_LIMITED],0) = 0 and [CARD_DELETED] = 0";
                        o_sqlCommand.Connection = o_sqlConnection;
                        SqlDataReader o_sqlDataReader;
                        o_sqlDataReader = o_sqlCommand.ExecuteReader();
                        if (o_sqlDataReader.Read())
                        {
                            result.CardFirstName = o_sqlDataReader["CARD_FIRSTNAME"].ToString();
                            result.CardLastName = o_sqlDataReader["CARD_LASTNAME"].ToString();
                            result.Status = "valid";
                        }
                        else {
                            result.Status = "invalid";
                        }
                        o_sqlDataReader.Close();
                        o_sqlConnection.Close();

                    }
                }
                catch(Exception e)
                {
                    Logger.WriteException(e);
                    result.Status = "failed";
                   // Error.CreateError(e);
                }

                context.SaveChanges();

                return result;
            }
        }
        // Called after the machine has successfully vended the item
        private static string VendComplete(string coordinateString)
        {
            // look up previous request with status='vending' in database
            using (klick_vending_machineEntities context = new klick_vending_machineEntities()) {
                VendingRequest request = (
                     from r in context.VendingRequests
                     where (
                        r.Status == STATUS_VENDING_ITEM ||
                        r.Status == STATUS_TAKING_PHOTO ||
                        r.Status == STATUS_PLAYING_SOUND
                     )
                     orderby r.RequestDate descending
                     select r).FirstOrDefault();

                // TODO: consider timeout, confirm coordinates, etc
                if (request != null)
                {
                    if (request.Status == STATUS_TAKING_PHOTO)
                    {
                        //TakePhoto();
                    }
                    else if (request.Status == STATUS_PLAYING_SOUND)
                    {
                        string DefaultSongPath = "song.mp3";
                        PlaySound(GetConfigPath("song", DefaultSongPath));
                    }
                    request.VendEndDate = DateTime.Now;
                    request.Status = STATUS_COMPLETE;
                }

                context.SaveChanges();
            }
            return null;
        }
        // Called when the user has pushed some coordinates
        private static string RequestItem(string coordinateString)
        {
            // Get the last card scan
            CardScan scan = CardScan.LastCardScan();
            if (scan == null)
            {
                return MSG_ERROR_NO_CARD;
            }

            VendingRequest lastRequest = VendingRequest.LastOutstandingRequest();

            string error = null;
            string successMessage = MSG_VEND_ITEM;
            int x = -1;
            int y = -1;
            string requestStatus = null;

            using (klick_vending_machineEntities context = new klick_vending_machineEntities())
            {
                CardScanResult scanResult = scan.CardScanResult;

                // create a new vending request
                VendingRequest request = new VendingRequest()
                {
                    CardScanResultID = scanResult.CardScanResultID,
                    Status = STATUS_PROCESSING,
                    RequestDate = DateTime.Now,
                    Coordinates = coordinateString
                };

                context.VendingRequests.Add(request);
                context.SaveChanges();

                try
                {
                    // Error checking block
                    if (lastRequest != null)
                    {
                        // We found a vending request with that is either processing or vending within a timeout interval
                        // Cannot vend again at this point
                        error = MSG_ERROR_VENDING_IN_PROGRESS;
                    }
                    else if (scan.HasTimedOut)
                    {
                        // We've timed out
                        if (DateTime.Now.Subtract(scan.ScanDate).TotalMinutes > 5)
                        {
                            // Last scan was a while ago - just tell the user to scan first, so they don't get confused
                            error = MSG_ERROR_NO_CARD;
                        }
                        else
                        {
                            // Display timeout error message
                            error = MSG_ERROR_CARD_TIMEOUT;
                        }
                    }
                    else if (scanResult.Status != "valid")
                    {
                        // Invalid card!
                        error = MSG_ERROR_INVALID_CARD;
                    }
                    else if (scan.HasVended(request.VendingRequestID))
                    {
                        // We've already vended an item for this card scan. Sneaky!
                        error = MSG_ERROR_ALREADY_VENDED;
                    }
                    else if (coordinateString == "TIMEOUT")
                    {
                        // Timed out before anything was vended
                        string DefaultTimeoutPath = "smb_warning.wav";
                        PlaySound(GetConfigPath("timeout", DefaultTimeoutPath));
                        error = MSG_ERROR_CARD_TIMEOUT;
                    }
                    else if (!GetCoordinates(coordinateString, out x, out y))
                    {
                        // Unable to parse coordinates
                        error = MSG_ERROR_INVALID_COORDS;
                    }
                    else
                    {
                        requestStatus = GetItemStatusType(x, y);
                        if (requestStatus == null)
                        {
                            error = MSG_ERROR_INVALID_ITEM;
                        }
                    }

                    request.X = x;
                    request.Y = y;
                }
                catch (Exception e)
                {
                    error = MSG_ERROR_SYSTEM_FAIL;
                    Error.CreateError(e);
                }

                if (error == null)
                {
                    // TODO: consider what happens if the message to the Arduino fails?
                    request.Status = requestStatus;
                    request.VendStartDate = DateTime.Now;

                    // Adjust the success message if necessary
                    if (requestStatus == STATUS_TAKING_PHOTO)
                    {
                        successMessage = MSG_TAKING_PHOTO;
                    }
                    else if (requestStatus == STATUS_PLAYING_SOUND)
                    {
                        successMessage = MSG_PLAYING_SOUND;
                    }
                }
                else
                {
                    request.Status = "failed";
                    request.ErrorMessage = error;
                }

                context.SaveChanges();
            }

            Logger.WriteLine("Returning! " + (error == null ? MSG_VEND_ITEM : error));

            // Finally, success! Vend it. Or display the error instead if there is one.
            return (error == null ? successMessage : error);
        }
        // Changed this to instead return the config value in the db
        private static string GetConfigPath(string configName, string defaultValue)
        {
            string value = null;

            using (klick_vending_machineEntities context = new klick_vending_machineEntities())
            {
                Config config = (from c in context.Configs where c.Name == configName select c).FirstOrDefault();

                if (config != null)
                {
                    value = config.Value;
                }
            }

            if (value == null || value == "")
            {
                value = defaultValue;
            }

            return (value);
        }