/// <summary> /// Handles printing labels for the given parameters using the /// label data stored on the AttendanceData model. /// </summary> /// <param name="fileGuids">The file guids of the label types to print.</param> /// <param name="personId">The person whose labels to print.</param> /// <param name="selectedAttendanceIds">The attendance Ids that have the labels to be reprinted.</param> /// <param name="control">The control to register/inject the client side printing into. This should be /// a control that is inside an UpdatePanel control so that the ScriptManager can register the needed client script block.</param> /// <param name="request">The HTTP Request so that the request's URL can be used when needed for client printing.</param> /// <param name="printerAddress">The IP Address of a printer to send the print job to, overriding what is in the label.</param> /// <returns> /// A list of any messages that occur during printing. /// </returns> public static List <string> ReprintZebraLabels(List <Guid> fileGuids, int personId, List <int> selectedAttendanceIds, Control control, System.Web.HttpRequest request, string printerAddress = null) { // Fetch the actual labels and print them var rockContext = new RockContext(); var attendanceService = new Rock.Model.AttendanceService(rockContext); // Get the selected attendance records var attendanceRecords = attendanceService.GetByIds(selectedAttendanceIds); var printFromClient = new List <CheckInLabel>(); var printFromServer = new List <CheckInLabel>(); // Now grab only the selected label types (matching fileGuids) from those record's AttendanceData // for the selected person foreach (var attendance in attendanceRecords) { var attendanceData = attendance.AttendanceData; var json = attendanceData.LabelData.Trim(); // skip if the return type is not an array if (json.Substring(0, 1) != "[") { continue; } // De-serialize the JSON into a list of objects var checkinLabels = JsonConvert.DeserializeObject <List <CheckInLabel> >(json); // skip if no labels were found if (checkinLabels == null) { continue; } // Take only the labels that match the selected person (or if they are Family type labels) and file guids). checkinLabels = checkinLabels.Where(l => (l.PersonId == personId || l.LabelType == KioskLabelType.Family) && fileGuids.Contains(l.FileGuid)).ToList(); // Override the printer by printing to the given printerAddress? if (!string.IsNullOrEmpty(printerAddress)) { checkinLabels.ToList().ForEach(l => l.PrinterAddress = printerAddress); printFromServer.AddRange(checkinLabels); } else { printFromClient.AddRange(checkinLabels.Where(l => l.PrintFrom == Rock.Model.PrintFrom.Client)); printFromServer.AddRange(checkinLabels.Where(l => l.PrintFrom == Rock.Model.PrintFrom.Server)); } } // Print client labels if (printFromClient.Any()) { var urlRoot = string.Format("{0}://{1}", request.Url.Scheme, request.Url.Authority); printFromClient .OrderBy(l => l.PersonId) .ThenBy(l => l.Order) .ToList() .ForEach(l => l.LabelFile = urlRoot + l.LabelFile); AddLabelScript(printFromClient.ToJson(), control); } var messages = new List <string>(); // Print server labels if (printFromServer.Any()) { messages = ZebraPrint.PrintLabels(printFromServer); } // No messages is "good news". if (messages.Count == 0) { messages.Add("The labels have been printed."); } return(messages); }
/// <summary> /// Prints the labels. /// </summary> /// <param name="labels">The labels.</param> /// <returns></returns> public static List <string> PrintLabels(List <CheckInLabel> labels) { var messages = new List <string>(); Socket socket = null; string currentIp = string.Empty; bool hasPrinterCutter = PrinterHasCutter(labels); int labelCount = 0; foreach (var label in labels.OrderBy(l => l.PersonId).ThenBy(l => l.Order)) { labelCount++; var labelCache = KioskLabel.Get(label.FileGuid); if (labelCache != null) { if (!string.IsNullOrWhiteSpace(label.PrinterAddress)) { if (label.PrinterAddress != currentIp) { if (socket != null && socket.Connected) { socket.Shutdown(SocketShutdown.Both); socket.Close(); } socket = ZebraPrint.OpenSocket(label.PrinterAddress); } string printContent = ZebraPrint.MergeLabelFields(labelCache.FileContent, label.MergeFields).TrimEnd(); // If the "enable label cutting" feature is enabled, then we are going to // control which mode the printer is in. In this case, we will remove any // tear-mode (^MMT) commands from the content and add the cut-mode (^MMC). if (hasPrinterCutter) { printContent = printContent.Replace("^MMT", string.Empty); // Here we are forcing the printer into cut mode (because // we don't know if it has been put into cut-mode already) even // though we might be suppressing the cut below. This is correct. printContent = printContent.ReplaceIfEndsWith("^XZ", "^MMC^XZ"); // If it's not the last label or a "ROCK_CUT" label, then inject // a suppress back-feed (^XB) command which will also suppress the cut. if (!(labelCount == labels.Count() || printContent.Contains("ROCK_CUT"))) { printContent = printContent.ReplaceIfEndsWith("^XZ", "^XB^XZ"); } } if (socket.Connected) { ZebraPrint.Print(printContent, socket); } else { messages.Add("NOTE: Could not connect to printer!"); } } } } // Close the socket if (socket != null && socket.Connected) { socket.Shutdown(SocketShutdown.Both); socket.Close(); } return(messages); }
/// <summary> /// Handles printing labels for the given parameters using the /// label data stored on the AttendanceData model. /// </summary> /// <param name="fileGuids">The file guids.</param> /// <param name="personId">The person identifier.</param> /// <param name="selectedAttendanceIds">The selected attendance ids.</param> /// <param name="control">The control.</param> /// <param name="request">The request.</param> /// <param name="reprintLabelOptions">The reprint label options.</param> /// <returns></returns> public static List <string> ReprintZebraLabels(List <Guid> fileGuids, int personId, List <int> selectedAttendanceIds, Control control, System.Web.HttpRequest request, ReprintLabelOptions reprintLabelOptions) { // Fetch the actual labels and print them var rockContext = new RockContext(); var attendanceService = new Rock.Model.AttendanceService(rockContext); reprintLabelOptions = reprintLabelOptions ?? new ReprintLabelOptions(); // Get the selected attendance records (but only the ones that have label data) var labelDataList = attendanceService .GetByIds(selectedAttendanceIds) .Where(a => a.AttendanceData.LabelData != null) .Select(a => a.AttendanceData.LabelData); var printFromClient = new List <CheckInLabel>(); var printFromServer = new List <CheckInLabel>(); // Now grab only the selected label types (matching fileGuids) from those record's AttendanceData // for the selected person foreach (var labelData in labelDataList) { var json = labelData.Trim(); // skip if the return type is not an array if (json.Substring(0, 1) != "[") { continue; } // De-serialize the JSON into a list of objects var checkinLabels = JsonConvert.DeserializeObject <List <CheckInLabel> >(json); // skip if no labels were found if (checkinLabels == null) { continue; } // Take only the labels that match the selected person (or if they are Family type labels) and file guids). checkinLabels = checkinLabels.Where(l => (l.PersonId == personId || l.LabelType == KioskLabelType.Family) && fileGuids.Contains(l.FileGuid)).ToList(); if (reprintLabelOptions.PrintFrom == PrintFrom.Server && reprintLabelOptions.ServerPrinterIPAddress.IsNotNullOrWhiteSpace()) { // Override the printer by printing to the given printerAddress? checkinLabels.ToList().ForEach(l => l.PrinterAddress = reprintLabelOptions.ServerPrinterIPAddress); printFromServer.AddRange(checkinLabels); } else if (reprintLabelOptions.PrintFrom == PrintFrom.Client) { // Override the printer by printing to the client // send the checkin labels to ZebraPrint.js, which the ClientApp will use to print it // IP Address of the printer will stay the same IP Address as where the original label was, printFromClient.AddRange(checkinLabels); } else { // Print to label's printer printFromClient.AddRange(checkinLabels.Where(l => l.PrintFrom == Rock.Model.PrintFrom.Client)); printFromServer.AddRange(checkinLabels.Where(l => l.PrintFrom == Rock.Model.PrintFrom.Server)); } } // Print client labels if (printFromClient.Any()) { var urlRoot = string.Format("{0}://{1}", request.UrlProxySafe().Scheme, request.UrlProxySafe().Authority); /* * // This is extremely useful when debugging with ngrok and an iPad on the local network. * // X-Original-Host will contain the name of your ngrok hostname, therefore the labels will * // get a LabelFile url that will actually work with that iPad. * if ( request.Headers["X-Original-Host"] != null ) * { * var scheme = request.Headers["X-Forwarded-Proto"] ?? "http"; * urlRoot = string.Format( "{0}://{1}", scheme, request.Headers.GetValues( "X-Original-Host" ).First() ); * } */ printFromClient .OrderBy(l => l.PersonId) .ThenBy(l => l.Order) .ToList() .ForEach(l => l.LabelFile = urlRoot + l.LabelFile); AddLabelScript(printFromClient.ToJson(), control); } var messages = new List <string>(); // Print server labels if (printFromServer.Any()) { messages = ZebraPrint.PrintLabels(printFromServer); } // No messages is "good news". if (messages.Count == 0) { messages.Add("The labels have been printed."); } return(messages); }