// 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); }
public HttpResponseMessage BuyProduct([FromBody] VendingRequest VendingReq) { try { string data = string.Empty; HttpResponseMessage response = new HttpResponseMessage(); ApiResponse valRes = new ApiResponse(); using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conStr"].ConnectionString)) { using (SqlCommand cmd = new SqlCommand("usp_buyProduct", conn)) { SqlDataAdapter adapt = new SqlDataAdapter(cmd); adapt.SelectCommand.CommandType = CommandType.StoredProcedure; adapt.SelectCommand.Parameters.Add(new SqlParameter("@productNm", SqlDbType.VarChar, 100)); adapt.SelectCommand.Parameters["@productNm"].Value = VendingReq.ProductName; adapt.SelectCommand.Parameters.Add(new SqlParameter("@actualAmt", SqlDbType.VarChar, 50)); adapt.SelectCommand.Parameters["@actualAmt"].Value = VendingReq.ActualAmount; conn.Open(); using (SqlDataReader dr = cmd.ExecuteReader()) { while (dr.Read()) { if (dr["STATUS"].Equals("1")) { valRes.ProductName = dr["ProductName"].ToString(); valRes.Change = Math.Round(Convert.ToDouble(dr["CHANGE"]), 2).ToString(); valRes.IsValidTransaction = true; valRes.IsAvailable = true; valRes.Message = "TRANSACTION SUCCESSFUL, PLEASE TAKE YOUR PRODUCT"; data = Newtonsoft.Json.JsonConvert.SerializeObject(valRes); response = Request.CreateResponse <ApiResponse>(HttpStatusCode.OK, valRes, "application/json"); } else { valRes.Message = dr["Message"].ToString(); valRes.ProductName = string.Empty; valRes.IsValidTransaction = false; valRes.Change = Math.Round(Convert.ToDouble(dr["CHANGE"]), 2).ToString(); data = Newtonsoft.Json.JsonConvert.SerializeObject(valRes); response = Request.CreateResponse <ApiResponse>(HttpStatusCode.OK, valRes, "application/json"); } } } conn.Close(); return(response); } } } catch (Exception ex) { return(Request.CreateResponse(HttpStatusCode.InternalServerError, new ApiResponse { Change = "-1", Message = ex.Message, IsAvailable = false, IsValidTransaction = false, ProductName = string.Empty }, "application/json")); } }
// 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); }