Example #1
0
        public Dictionary<Type, ISPNode> GetChildrenTypes(ISPNode parentNode)
        {
            IEnumerable<Lazy<SPNode>> importedNodes = CompositionProvider.GetExports<SPNode>(parentNode.Descriptor.ClassType);
            var types = new Dictionary<Type, ISPNode>();
            foreach (var lazyItem in importedNodes)
            {
                SPNode node = lazyItem.Value;
                node.NodeProvider = parentNode.NodeProvider;

                if (node.Descriptor.AdapterItemType != null)
                {
                    types.AddOrReplace(node.Descriptor.AdapterItemType, node);
                }
            }
            return types;
        }
        /// <summary>
        /// Creates the labels.
        /// </summary>
        /// <param name="dataKeyArray">The data key array.</param>
        /// <returns></returns>
        private void ProcessLabels( DataKeyArray checkinArray )
        {
            // Make sure we can save the attendance and get an attendance code
            if ( RunSaveAttendance )
            {
                var attendanceErrors = new List<string>();
                if ( ProcessActivity( "Save Attendance", out attendanceErrors ) )
                {
                    SaveState();
                }
                else
                {
                    string errorMsg = "<ul><li>" + attendanceErrors.AsDelimited( "</li><li>" ) + "</li></ul>";
                    maAlert.Show( errorMsg, Rock.Web.UI.Controls.ModalAlertType.Warning );
                    return;
                }

                RunSaveAttendance = false;
            }

            var printQueue = new Dictionary<string, StringBuilder>();
            bool printIndividually = GetAttributeValue( "PrintIndividualLabels" ).AsBoolean();
            var designatedLabelGuid = GetAttributeValue( "DesignatedSingleLabel" ).AsGuidOrNull();

            foreach ( var selectedFamily in CurrentCheckInState.CheckIn.Families.Where( p => p.Selected ) )
            {
                List<CheckInLabel> labels = new List<CheckInLabel>();
                List<CheckInPerson> selectedPeople = selectedFamily.People.Where( p => p.Selected ).ToList();
                List<CheckInGroupType> selectedGroupTypes = selectedPeople.SelectMany( gt => gt.GroupTypes )
                    .Where( gt => gt.Selected ).ToList();
                List<CheckInGroup> availableGroups = null;
                List<CheckInLocation> availableLocations = null;
                List<CheckInSchedule> availableSchedules = null;
                List<CheckInSchedule> personSchedules = null;

                foreach ( DataKey dataKey in checkinArray )
                {
                    var personId = Convert.ToInt32( dataKey["PersonId"] );
                    var groupId = Convert.ToInt32( dataKey["GroupId"] );
                    var locationId = Convert.ToInt32( dataKey["LocationId"] );
                    var scheduleId = Convert.ToInt32( dataKey["ScheduleId"] );

                    int groupTypeId = selectedGroupTypes.Where( gt => gt.Groups.Any( g => g.Group.Id == groupId ) )
                        .Select( gt => gt.GroupType.Id ).FirstOrDefault();
                    availableGroups = selectedGroupTypes.SelectMany( gt => gt.Groups ).ToList();
                    availableLocations = availableGroups.SelectMany( l => l.Locations ).ToList();
                    availableSchedules = availableLocations.SelectMany( s => s.Schedules ).ToList();
                    personSchedules = selectedPeople.SelectMany( p => p.PossibleSchedules ).ToList();

                    // Make sure only the current item is selected in the merge object
                    if ( printIndividually || checkinArray.Count == 1 )
                    {
                        // Note: This depends on PreSelected being set properly to undo changes later
                        selectedPeople.ForEach( p => p.Selected = ( p.Person.Id == personId ) );
                        selectedGroupTypes.ForEach( gt => gt.Selected = ( gt.GroupType.Id == groupTypeId ) );
                        availableGroups.ForEach( g => g.Selected = ( g.Group.Id == groupId ) );
                        availableLocations.ForEach( l => l.Selected = ( l.Location.Id == locationId ) );
                        availableSchedules.ForEach( s => s.Selected = ( s.Schedule.Id == scheduleId ) );
                        personSchedules.ForEach( s => s.Selected = ( s.Schedule.Id == scheduleId ) );
                    }

                    // Create labels for however many items are currently selected
                    // #TODO: Rewrite CreateLabels so it would accept a list of ID's
                    var labelErrors = new List<string>();
                    if ( ProcessActivity( "Create Labels", out labelErrors ) )
                    {
                        SaveState();
                    }

                    // mark the person as being checked in
                    var selectedSchedules = availableLocations.Where( l => l.Selected )
                        .SelectMany( s => s.Schedules ).Where( s => s.Selected ).ToList();
                    foreach ( var selectedSchedule in selectedSchedules )
                    {
                        var serviceStart = (DateTime)selectedSchedule.StartTime;
                        selectedSchedule.LastCheckIn = serviceStart.AddMinutes( (double)selectedSchedule.Schedule.CheckInEndOffsetMinutes );
                    }

                    // Add valid grouptype labels, excluding the one-time label (if set)
                    if ( printIndividually )
                    {
                        var selectedPerson = selectedPeople.FirstOrDefault( p => p.Person.Id == personId );
                        if ( selectedPerson != null )
                        {
                            labels.AddRange( selectedPerson.GroupTypes.Where( gt => gt.Labels != null )
                                .SelectMany( gt => gt.Labels )
                                .Where( l => ( !RemoveFromQueue || l.FileGuid != designatedLabelGuid ) )
                            );
                        }

                        RemoveFromQueue = RemoveFromQueue || labels.Any( l => l.FileGuid == designatedLabelGuid );
                    }
                    else
                    {
                        labels.AddRange( selectedGroupTypes.Where( gt => gt.Labels != null )
                            .SelectMany( gt => gt.Labels )
                            .Where( l => ( !RemoveFromQueue || l.FileGuid != designatedLabelGuid ) )
                        );

                        // don't continue processing if printing all info on one label
                        break;
                    }
                }

                // Print client labels
                if ( labels.Any( l => l.PrintFrom == PrintFrom.Client ) )
                {
                    var clientLabels = labels.Where( l => l.PrintFrom == PrintFrom.Client ).ToList();
                    var urlRoot = string.Format( "{0}://{1}", Request.Url.Scheme, Request.Url.Authority );
                    clientLabels.ForEach( l => l.LabelFile = urlRoot + l.LabelFile );
                    AddLabelScript( clientLabels.ToJson() );
                    pnlContent.Update();
                }

                // Print server labels
                if ( labels.Any( l => l.PrintFrom == PrintFrom.Server ) )
                {
                    string delayCut = @"^XB";
                    string endingTag = @"^XZ";
                    var printerIp = string.Empty;
                    var labelContent = new StringBuilder();

                    // make sure labels have a valid ip
                    var lastLabel = labels.Last();
                    foreach ( var label in labels.Where( l => l.PrintFrom == PrintFrom.Server && !string.IsNullOrEmpty( l.PrinterAddress ) ) )
                    {
                        var labelCache = KioskLabel.Read( label.FileGuid );
                        if ( labelCache != null )
                        {
                            if ( printerIp != label.PrinterAddress )
                            {
                                printQueue.AddOrReplace( label.PrinterAddress, labelContent );
                                printerIp = label.PrinterAddress;
                                labelContent = new StringBuilder();
                            }

                            var printContent = labelCache.FileContent;
                            foreach ( var mergeField in label.MergeFields )
                            {
                                if ( !string.IsNullOrWhiteSpace( mergeField.Value ) )
                                {
                                    printContent = Regex.Replace( printContent, string.Format( @"(?<=\^FD){0}(?=\^FS)", mergeField.Key ), ZebraFormatString( mergeField.Value ) );
                                }
                                else
                                {
                                    printContent = Regex.Replace( printContent, string.Format( @"\^FO.*\^FS\s*(?=\^FT.*\^FD{0}\^FS)", mergeField.Key ), string.Empty );
                                    printContent = Regex.Replace( printContent, string.Format( @"\^FD{0}\^FS", mergeField.Key ), "^FD^FS" );
                                }
                            }

                            // send a Delay Cut command at the end to prevent cutting intermediary labels
                            if ( label != lastLabel )
                            {
                                printContent = Regex.Replace( printContent.Trim(), @"\" + endingTag + @"$", delayCut + endingTag );
                            }

                            labelContent.Append( printContent );
                        }
                    }

                    printQueue.AddOrReplace( printerIp, labelContent );

                    if ( printQueue.Any() )
                    {
                        PrintLabels( printQueue );
                        printQueue.Clear();
                    }
                    else
                    {   // give the user feedback when no server labels are configured
                        phPrinterStatus.Controls.Add( new LiteralControl( "No labels were created.  Please verify that the grouptype is configured with labels and cache is reset." ) );
                    }
                }

                if ( printIndividually || checkinArray.Count == 1 )
                {
                    // reset selections to what they were before queue
                    selectedPeople.ForEach( p => p.Selected = p.PreSelected );
                    personSchedules.ForEach( s => s.Selected = s.PreSelected );
                    selectedGroupTypes.ForEach( gt => gt.Selected = gt.PreSelected );
                    availableGroups.ForEach( g => g.Selected = g.PreSelected );
                    availableLocations.ForEach( l => l.Selected = l.PreSelected );
                    availableSchedules.ForEach( s => s.Selected = s.PreSelected );
                }
            }

            // refresh the currently checked in flag
            BindGrid();
        }