Several people have asked for an update on Hannah…
My last post mentioned a drop in the number of seizures she was having and for most of June, Hannah didn’t have any seizures (during the daytime at least). It was a nice relief for her (and for us). Recently though she has started having more again, and she continues to experience negative side-effects of the medication.
We’ve decided to move forward with surgery which is scheduled for July 28th. In preparation for this, we’ve had several more visits to Phoenix Children’s Hospital.
Hannah had a comprehensive neuro-psychiatric exam to test things like IQ, behavior, motor skills, etc. This test is done as a baseline so that when the same testing is administered a few months after surgery, we can tell what (if anything) has changed.
We also met with the surgeon who will be doing the surgery. Talked a lot about the risks. Several (like death and injury) are actually higher with uncontrolled seizures than they are with surgery. Surgery does have a higher risk of infection and stroke though. The stroke risk surprised me, but evidently, when they place the electrodes directly on the surface of the brain, there is the possibility that they could restrict necessary blood flow. One of the most encouraging things I heard from the surgeon was that personality is not really affected when resecting only one side of the frontal lobe. So… Hannah should still be “Hannah” after the surgery :).
It’s obviously a scary time for us. Please keep Hannah in your prayers. Thanks.
If your curious to learn more about the type of surgery that will be done, this video is very informative both about surgery and about epilepsy (with uncontrolled seizures). I also described the procedure a bit in a previous post.
Earlier today, I received an email asking what functionality Arena provides when used to drive a church’s public website. I thought I’d share my response…
Content Management System (CMS)
Arena is a CMS. It may not be the fanciest and easiest to use CMS out there, but it provides all the functionality for configuring portals, templates, pages, modules, security, content, etc. And by using templates, you can create an Arena driven site to look anyway you’d like. The look and functionality of your site is only limited by the creativity of your designer. You can be as “Web 2.0” and as you’d like using Arena templates.
The biggest advantage of using Arena as your CMS, however, is it’s integration with all the information you already have in the Arena membership system and the modules that have been created to take advantage of that information.
Promotions
The most powerful area of integration with Arena is promotions. Church staff can add promotions in Arena that are categorized, prioritized and approved and will then automatically be displayed on your public website.
For example Canyon Ridge has configured a promotion display module to display the top three “All Church” promotions at the bottom of their home page…
There are several types of promotion display modules, each of which display your promotions in different ways. A Flash module is even provided for animating Arena promotions. An example of the Flash module can be seen on this CCV Stars page.
With promotions, the “web guy” doesn’t have to worry about adding or removing content when appropriate. As soon as a promotion’s date has passed, it is automatically removed from the site. Promotions can also be configured for different ministry areas (Men’s, Women’s Singles, etc.) and the website would show just promotions specific to those areas on their respective web pages.
But There’s More…
In addition to promotions, Arena can also drive the following functionality on your public site:
- Small Group Leader Toolbox (lay leaders can manage groups)
- Group Finder (several options including geographically based, affinity based, etc.)
- Online Giving
- Event Calendar
- Event Registration
- Prayer Requests
- Personalized Subscriptions to promotions (through RSS or Email)
- Online Folder/File browser for securing and sharing digital content
- Podcasting/Blogging
- Classifieds (One of the most visited areas of CCV’s site)
- ECards
- Newsletters
- Polls
- Serving Opportunities
- Sports Team information (Team info, standings, etc)
- Photo Albums
- Staff Pages
- Employment Opportunities
So, if you’re using Arena as your ChMS and not as your CMS, your going to miss out on a lot of built-in integration.
For a long time, we’ve been putting our staff anniversaries on our Arena home page each month…
I’m ashamed to say that until now, our department admin has been doing this manually each month. I also noticed that she recently started changing the highlighting each day to indicate which anniversaries in the month had already passed. Obviously a lot of manual work for what can easily be automated.
Since we’re tracking all this information in Arena, this was a perfect scenario for the HTML from Stored Procedure module.
First a stored procedure is needed to generate the HTML…
CREATE PROC [dbo].[cust_ccv_sp_staff_anniversaries] @HireDateAttrID int, @PositionAttrID int AS DECLARE @MonthName varchar(12) DECLARE @HtmlMsgPtr binary(16) DECLARE @TempMessage varchar(8000) DECLARE @Today datetime SET @Today = GETDATE() CREATE TABLE ##StaffHtmlTable ([html] text) INSERT INTO ##StaffHtmlTable VALUES ('<hr/>') SELECT @HtmlMsgPtr = TEXTPTR([html]) FROM ##StaffHtmlTable SET @TempMessage = '<table style="width: 570px; height: 201px; " cellspacing="0" cellpadding="0"><tbody><tr>' + '<td class="highlightText" valign="top" align="left">' + '<img src="/Arena/Content/HtmlImages/Public/Images/General/icon_birthday.gif" />' + '<strong><font color="#808080" size="3">' + DATENAME(month, @Today) + ' Birthdays</font></strong></td>' + '<td class="highlightText" valign="top" align="left">' + '<img src="/Arena/Content/HtmlImages/Public/Images/General/award.jpg" />' + '<strong><font color="#808080" size="3">' + DATENAME(month, @Today) + ' Staff Years of Service</font></strong></td></tr><tr><td class="highlightText" valign="top">' UPDATETEXT ##StaffHtmlTable.[html] @HtmlMsgPtr null 0 @TempMessage DECLARE @StaffName varchar(100) DECLARE @AnnivDate datetime DECLARE @Position varchar(250) DECLARE BirthDateCursor CURSOR READ_ONLY FOR SELECT nick_name + ' ' + last_name, birth_date FROM core_person WHERE staff_member = 1 AND birth_date <> '1/1/1900' AND MONTH(birth_date) = MONTH(@Today) ORDER BY DAY(birth_Date), last_name, nick_name OPEN BirthDateCursor FETCH NEXT FROM BirthDateCursor INTO @StaffName, @AnnivDate WHILE (@@FETCH_STATUS <> -1) BEGIN IF (@@FETCH_STATUS = 0) BEGIN -- Date IF DAY(@AnnivDate) < DAY(@Today) SET @TempMessage = '<font color="#a9a9a9">' ELSE SET @TempMessage = '<font color="#000000">' SET @TempMessage = @TempMessage + CAST(MONTH(@AnnivDate) as varchar) + '/' + CAST(DAY(@AnnivDate) as varchar) IF DAY(@AnnivDate) < 10 SET @TempMessage = @TempMessage + ' ' ELSE SET @TempMessage = @TempMessage + ' ' SET @TempMessage = @TempMessage + '<strong>' + @StaffName + '</strong></font><br/>' UPDATETEXT ##StaffHtmlTable.[html] @HtmlMsgPtr null 0 @TempMessage END FETCH NEXT FROM BirthDateCursor INTO @StaffName, @AnnivDate END CLOSE BirthDateCursor DEALLOCATE BirthDateCursor SET @TempMessage = '</td><td class="highlightText" valign="top">' UPDATETEXT ##StaffHtmlTable.[html] @HtmlMsgPtr null 0 @TempMessage DECLARE HireDateCursor CURSOR READ_ONLY FOR SELECT nick_name + ' ' + last_name, HD.datetime_value, POS.varchar_value FROM core_person P INNER JOIN core_person_attribute HD ON HD.person_id = P.person_id AND HD.attribute_id = @HireDateAttrID LEFT OUTER JOIN core_person_attribute POS ON POS.person_id = P.person_id AND POS.attribute_id = @PositionAttrID WHERE P.staff_member = 1 AND ISNULL(MONTH(HD.datetime_value),0) = MONTH(@Today) AND ISNULL(YEAR(HD.datetime_value),0) < YEAR(@Today) ORDER BY ISNULL(DAY(HD.datetime_value),0), last_name, nick_name OPEN HireDateCursor FETCH NEXT FROM HireDateCursor INTO @StaffName, @AnnivDate, @Position WHILE (@@FETCH_STATUS <> -1) BEGIN IF (@@FETCH_STATUS = 0) BEGIN DECLARE @Years int SET @Years = YEAR(@Today) - YEAR(@AnnivDate) -- Date IF DAY(@AnnivDate) < DAY(@Today) SET @TempMessage = '<font color="#a9a9a9">' ELSE SET @TempMessage = '<font color="#000000">' SET @TempMessage = @TempMessage + CAST(MONTH(@AnnivDate) as varchar) + '/' + CAST(DAY(@AnnivDate) as varchar) IF DAY(@AnnivDate) < 10 SET @TempMessage = @TempMessage + ' ' ELSE SET @TempMessage = @TempMessage + ' ' SET @TempMessage = @TempMessage + '<strong>' + @StaffName + '</strong>, ' + @Position + ' - <strong>' + CAST(@Years as varchar) IF @Years > 1 BEGIN IF @Years >= 5 SET @TempMessage = @TempMessage + ' Years!' ELSE SET @TempMessage = @TempMessage + ' Years' END ELSE SET @TempMessage = @TempMessage + ' Year' SET @TempMessage = @TempMessage + '</strong></font><br/>' UPDATETEXT ##StaffHtmlTable.[html] @HtmlMsgPtr null 0 @TempMessage END FETCH NEXT FROM HireDateCursor INTO @StaffName, @AnnivDate, @Position END CLOSE HireDateCursor DEALLOCATE HireDateCursor SET @TempMessage = '</td></tr></table>' UPDATETEXT ##StaffHtmlTable.[html] @HtmlMsgPtr null 0 @TempMessage SELECT [html] FROM ##StaffHtmlTable DROP TABLE ##StaffHtmlTable
This stored procedure expects a couple person attribute IDs for the Hire Date and Position…
And then a new HTML From Stored Procedure module is added to our Arena homepage. Notice the two person attribute ID values that are passed to the stored procedure in the Parameters setting.
I love doing these quick little things that help someone save a lot of time.
(if you want to use the same stored procedure, here’s the two images we use…
It has this week!
A lot of people are praying for Hannah. Last Wednesday, even my team at work took time out of the morning to walk up the prayer hill and pray.
For the last several weeks Hannah has been averaging about 10 seizures a day. That changed this weekend. Here’s a chart that we use to track her seizures. Notice the last several days…
We haven’t changed anything else. No medication changes, no diet changes, nothing. Just prayer. After hours without seizures this weekend, My wife and I found ourselves looking at each other and wondering aloud ”What’s going on here?”
A lot of people are praying for Hannah, and what a powerful “coincidence” that is evident in that chart. Will the number of her seizures continue to drop? Will God heal her? I don’t know. I know that he can, but I also know that there so much more to God’s will than I’ll ever understand. For now I’ll just continue to pray for her healing, for a break from the barrage of seizures, and for wisdom to know what to do given the options we have available.
“Focal Cortical Resection” is a term we’re having to become a little more acquainted with these days. We met with Hannah’s neurologist on Thursday to discuss her test results and where we go from here. Looks like surgery is the "best" option available to us. Her tests indicate that the seizures are originating somewhere in the left frontal lobe.
The surgery would be a Focal Cortical Resection and would actually involve two different procedures. During the first procedure, the surgeon will make an incision, remove the bone, pull back the dura and then place a grid of electrodes directly on the surface of the brain. They will then put the bone back, or maybe just put it in the freezer (not kidding), and stitch her back up. Then for the next 5-7 days they monitor electrical activity from the grid of electrodes to try and pinpoint further the location of the seizures. They also send electrical impulses to these electrodes to see what parts of her body responds (moves).
The hope is that the electrodes that indicate where the seizure originates from are not the same electrodes that cause movement. If they are, the second phase of surgery cannot be done. The second procedure would be the actual resection to remove as much as possible (the more that is removed the higher the success rate of eliminating seizures).
All the docs (neurologists, surgeons, psychiatrists, etc) are meeting Monday June 1st, to discuss Hannah’s case and then we should be scheduling the surgery. Will probably be sometime in July, and she’ll be in the hospital for about two weeks.
As you can imagine we’re very conflicted about her treatment. She is having 10+ seizures a day (and more while she sleeps). As one medical paper puts it, she needs surgery "…before irreversible deterioration in cognitive or psychosocial functions ensues due to long-standing disabling seizures and chronic antiepileptic drug-related side effects." On the other hand, the success rate of surgery is 50-60% runs the risk of her losing movement, and more… The frontal lobe controls emotions, reasoning, planning, movement, and parts of speech. It is also involved in purposeful acts such as creativity, judgment, problem solving, and planning. That’s a lot of stuff!
If you’re praying for her, keep it up. Thanks.
Not sure anyone is going to see this post, since I moved and didn’t tell anyone.
Why?
I wanted a new blog. I wasn’t thrilled by how dated my old blog looked, and I think I’m also going to try and write more often (let’s say… oh… at least once a week). Figured I’d clean it up first, so I ditched my old BlogEngine.NET blog hosted at GoDaddy, and went with a WordPress blog hosted at Dreamhost (all my friends we’re doing it).
I did update the nameservers for my domain, but because of differences between the WordPress feed and the old feed, and because of some strange things happening in my FeedBurner account, I’m pretty sure I’m writing this post only for me. But… If I’m wrong, and you see me, say hello.
What’s Different?
I was challenged by my friend and fellow blogger Erik, to include more posts about me (you know real-world stuff) and not just stuff about Arena. So while I will keep posting things about Arena (and other work stuff), I’ll also try and add some things about what captivates me when I’m not at my day job.
And That Is?
So what captivates me when I’m not at work. Well… I have a 16 year old son who hasn’t quite got his license yet, but works a lot as a Lifeguard and is big into dirt bikes, so I spend a great deal of my time driving him around and hanging out with him at the dirt track. My 10 year old daughter has Refractory Epilepsy so we’re trying to manage her 10+ seizures a day and considering the alternatives for her treatment (surgery). She still is my best movie partner as we seem to be the only two in the family who really enjoy intense action movies. My 7 year old son is autistic (high functioning), and is my biggest helper. Him and I are the two morning people and are often long at work in the yard together before anyone else is even up. And of course my wife. She helps me to survive it all.
Wow… that kinda felt like I was filling out an online dating ad (good thing no one is reading it anyway). Next post is going to be about Arena.
In the interest of possibly helping anyone else set up their podcast, here’s how Arena podcasting is configured in our environment (You can click on any of these images to see them full size).
Feed Formats
Before setting up any channels, you’ll need to setup your available feed formats in the Arena Administration area.
XSLT
Arena uses an rss.aspx page to convert an XML version of your feed into a standardized RSS feed format. This gives you control over fine-tuning how the RSS content is generated (You can view both the XML and the XSLT from the Channel overview page). Here’s a copy of our xslt/rss/default.xslt file. This XSLT file creates an RSS feed that is also compliant with iTunes requirements…
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"> <xsl:output method="xml" version="1.0" encoding="utf-8"/> <xsl:template match="/"> <rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0"> <xsl:for-each select="/*"> <channel> <title> <xsl:value-of select="@author"/>: <xsl:value-of select="@title"/> (<xsl:value-of select="format/@title"/>) </title> <link> <xsl:value-of select="@link"/> </link> <language> <xsl:value-of select="@language"/> </language> <copyright> <xsl:value-of select="@copyright"/> </copyright> <description> <xsl:value-of select="description"/> </description> <itunes:subtitle> <xsl:value-of select="@subtitle"/> </itunes:subtitle> <itunes:author> <xsl:value-of select="@author"/> </itunes:author> <itunes:summary> <xsl:value-of select="description"/> </itunes:summary> <itunes:owner> <itunes:name> <xsl:value-of select="@contactname"/> </itunes:name> <itunes:email> <xsl:value-of select="@contactemail"/> </itunes:email> </itunes:owner> <itunes:image> <xsl:attribute name="href"> <xsl:value-of select="@imageurl"/> </xsl:attribute> </itunes:image> <xsl:for-each select="category"> <xsl:call-template name="categorynode"></xsl:call-template> </xsl:for-each> <xsl:for-each select="items/item"> <xsl:call-template name="itemnode"></xsl:call-template> </xsl:for-each> </channel> </xsl:for-each> </rss> </xsl:template> <xsl:template name="categorynode"> <itunes:category> <xsl:attribute name="text"> <xsl:value-of select="@text"/> </xsl:attribute> <xsl:for-each select="category"> <xsl:call-template name="categorynode"></xsl:call-template> </xsl:for-each> </itunes:category> </xsl:template> <xsl:template name="itemnode"> <item> <title> <xsl:choose> <xsl:when test="topic"> <xsl:choose> <xsl:when test="topic/@title = @title"> <xsl:value-of select="@title"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="topic/@title"/>: <xsl:value-of select="@title"/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="@title"/> </xsl:otherwise> </xsl:choose> </title> <pubDate> <xsl:value-of select="@publish"/> </pubDate> <itunes:author> <xsl:value-of select="/channel/@author"/> </itunes:author> <xsl:if test="@imageurl"> <itunes:image> <xsl:attribute name="href"> <xsl:value-of select="@imageurl"/> </xsl:attribute> </itunes:image> </xsl:if> <itunes:summary> <xsl:value-of select="description"/> </itunes:summary> <description> <xsl:value-of select="description"/> </description> <link> <xsl:value-of select="@link"/> </link> <enclosure> <xsl:attribute name="url"> <xsl:value-of select="enclosure/@url"/> </xsl:attribute> <xsl:attribute name="length"> <xsl:value-of select="enclosure/@duration"/> </xsl:attribute> <xsl:attribute name="type"> <xsl:value-of select="enclosure/@mimetype"/> </xsl:attribute> </enclosure> <itunes:keywords> <xsl:value-of select="keywords"/> </itunes:keywords> <xsl:if test="enclosure/@time"> <itunes:duration> <xsl:value-of select="enclosure/@time"/> </itunes:duration> </xsl:if> </item> </xsl:template> </xsl:stylesheet>
Arena Page Setup
Here’s how our Podcasting administrative pages are setup in Arena
The first “Podcast Channels” page simply redirects to the second (not sure why, but that’s how it is).
The second “Podcast Channels” page has the ChannelList module.
The “Channel Details” page has the ChannelDetail and ChannelTabs (Show Filter setting is set to True) modules.
The “Item Details” page has the ItemDetail module.
Note: I think there’s a bug with the smart page setting on this module. It’s looking for a page above this one with the ItemList module which does not exist. Our setting points to the Channel Detail page above it.
The “Topic Details” page has the TopicDetail module.
Note: Similar bug here. It has a smart page setting that looks for a page above this one with the TopicList module. Our setting again points to the Channel Detail page above it.
The “Topic Item Detail” page has the ItemDetail module.
Note: Same bug. Our Item List Page setting points to the Topic Details page above this page.
Public Pages
Here’s how the public pages on our website are configured…
The “Online Message” page in addition to several html modules has the ChannelView module.
Settings Used: Heading = blank, Image Size = 452, Item View Page = “Message” page below this one, SubHeading = blank, Topic View Page = “Series” page below this one, Use Topic View = True.
The “Series” page has the TopicView module.
Settings Used: Heading = blank, Image Size = 452, Item View Detail Page = “Message” page below this one, SubHeading = blank.
The “Message” page has the ItemFlashViewer module.
Settings Used: Email Message = blank, Flash Format = Flash Video, Image Size = blank, Object Height = 260, Object Width = 320.
Channel Overview…
Here’s an example of how our contemporary service podcast is setup.
You’ll notice that we use FeedBurner as our external feed so that when people subscribe to the feed they’ll see the FeedBurner url instead of our internal url. We’ve then configured the Feedburner acount to point back to the actual arena url(http://arena.ccvonline.com/Arena/rss.aspx?c=1&f=1).
Details…
Enclosure Types…
Topic…
Item Overview…
Item Details…
You’ll notice that we use various third-party hosting providers to store our actual video and audio content to cut down on bandwidth to our internal servers. podcasts.ccvonline.com actually points to an Amazon S3 server.
Hope that helps, comment for any questions.
You may have noticed that when creating an occurrence in Arena, you can associate it with an area….
This is useful if you are providing Area specific pages on your web site and you’d like people to see any events that are occurring for that area, or you’d like your area leaders be able to add and edit events specific to their area.
The occurrence list module will display all occurrences specific to an area as long as you have the Area Filter Parameter value set…
This value is what the module will look for on the Query string to determine if it should just display occurrences for a specific area. Because the public Area page has “area” in the query string, placing this module on the page will display all occurrences for the current area.
You can also add a link to an area specific list in the Arena application by using the Tool tab in the Area Detail page.
A cool feature on the Area Details page of Arena is the ability to customize the "Tools" tab to include any HTML that you’d like. When editing the settings of the Area Detail module, any HTML that you include in the Details section will be displayed in the Tools tab.
For example, this the HTML that we’ve entered for our Area Details module…
<div class="heading2">Tools</div> <div class="normalText" style="padding-left:15px"> <a href='default.aspx?page=1437&Area=<area_id>'><area_name> Events</a><br/> <a href='default.aspx?page=4065&Area=<area_id>'>View <area_name> Families</a><br/> </div> <div class="heading2" style="padding-top:20px">Reports</div> <div class="normalText" style="padding-left:20px"> <a href='default.aspx?page=3987&title=<area_name_encoded> Members, Attenders and Guest Book Signers&AreaID=<area_id>' target='_blank'><area_name> Members, Attenders and Guest Book Signers</a><br/> </div>
As you can see in this example there are some codes you can enter that will be replaced with data from the current Area that is being displayed..
<area_id> will be replaced with the area’s ID
<area_name> will be replaced with the area’s name
<area_name_encoded> will be replaced with a URLEncoded version of the area’s name.
We use this functionality to link to area specific occurrences (next post), an Area specific person search page (using the AreaPersonFilter module), and to area specific custom reports.
The Metric functionality in Arena is a very powerful tool for viewing changes in data over time (yes, I know, the UI could still use some improvements). Essentially it allows you to create any number of metrics by specifying a SQL statement that just returns one numeric value. Arena will then run that statement how ever often you decide, save the result, and chart the values over time.
You can also set up a metric that isn’t linked to Arena data but instead is hand-entered (i.e. Total Weekend Attendance)
Membership Status Metrics
Since you may not have gotten any sample metrics out of the box, here’s a SQL script that will add a few for you…
DECLARE @OrganizationID int SET @OrganizationID = (SELECT TOP 1 organization_id FROM orgn_organization) DECLARE @AllUsers int SET @AllUsers = (SELECT TOP 1 role_id FROM secu_role WHERE role_name = 'All Users') DECLARE @ParentMetricID int DECLARE @MetricID int -- Create Parent Metric INSERT INTO [Arena].[dbo].[mtrc_metric] ([date_created] ,[date_modified] ,[created_by] ,[modified_by] ,[parent_metric_id] ,[metric_order] ,[graph_type] ,[title] ,[series_caption] ,[description] ,[source_summary] ,[collection_frequency] ,[collection_last_date] ,[collection_sql_statement] ,[organization_id] ,[aggregate_type] ,[numeric_x_values]) VALUES (GETDATE() ,GETDATE() ,'' ,'' ,NULL ,1 ,-1 ,'Membership Status' ,'' ,'Metric to show the number of people of each Membership Status over time' ,'' ,0 ,'1/1/1900' ,'' ,@OrganizationID ,'MAX' ,0) SET @ParentMetricID = SCOPE_IDENTITY() INSERT INTO [Arena].[dbo].[secu_permission] ([date_created] ,[date_modified] ,[created_by] ,[modified_by] ,[object_type] ,[operation_type] ,[subject_type] ,[object_key] ,[subject_key]) VALUES (GETDATE() ,GETDATE() ,'' ,'' ,6 ,0 ,0 ,@ParentMetricID ,@AllUsers ) INSERT INTO [Arena].[dbo].[secu_permission] ([date_created] ,[date_modified] ,[created_by] ,[modified_by] ,[object_type] ,[operation_type] ,[subject_type] ,[object_key] ,[subject_key]) VALUES (GETDATE() ,GETDATE() ,'' ,'' ,6 ,1 ,0 ,@ParentMetricID ,@AllUsers ) DECLARE @LookupID int DECLARE @LookupValue varchar(50) DECLARE @LookupOrder int DECLARE MemberStatusCursor CURSOR LOCAL FOR SELECT lookup_id, lookup_value, lookup_order FROM core_lookup L INNER JOIN core_lookup_type LT ON LT.lookup_type_id = L.lookup_type_id WHERE LT.guid = '0B4532DB-3188-40F5-B188-E7E6E4448C85' OPEN MemberStatusCursor FETCH NEXT FROM MemberStatusCursor INTO @LookupID, @LookupValue, @LookupOrder WHILE @@FETCH_STATUS = 0 BEGIN INSERT INTO [Arena].[dbo].[mtrc_metric] ([date_created] ,[date_modified] ,[created_by] ,[modified_by] ,[parent_metric_id] ,[metric_order] ,[graph_type] ,[title] ,[series_caption] ,[description] ,[source_summary] ,[collection_frequency] ,[collection_last_date] ,[collection_sql_statement] ,[organization_id] ,[aggregate_type] ,[numeric_x_values]) VALUES (GETDATE() ,GETDATE() ,'' ,'' ,@ParentMetricID ,@LookupOrder ,0 ,'Number of ' + @LookupValue + 's' ,@LookupValue + 's' ,'Number of people classifed as "' + @LookupValue + '"' ,'' ,2 ,GETDATE() ,'SELECT COUNT(*) AS people_count FROM Arena.dbo.core_person WHERE record_status = 0 AND member_status = ' + CAST(@LookupID as varchar) ,@OrganizationID ,'MAX' ,0) SET @MetricID = SCOPE_IDENTITY() INSERT INTO [Arena].[dbo].[secu_permission] ([date_created] ,[date_modified] ,[created_by] ,[modified_by] ,[object_type] ,[operation_type] ,[subject_type] ,[object_key] ,[subject_key]) VALUES (GETDATE() ,GETDATE() ,'' ,'' ,6 ,0 ,0 ,@MetricID ,@AllUsers ) INSERT INTO [Arena].[dbo].[secu_permission] ([date_created] ,[date_modified] ,[created_by] ,[modified_by] ,[object_type] ,[operation_type] ,[subject_type] ,[object_key] ,[subject_key]) VALUES (GETDATE() ,GETDATE() ,'' ,'' ,6 ,1 ,0 ,@MetricID ,@AllUsers ) FETCH NEXT FROM MemberStatusCursor INTO @LookupID, @LookupValue, @LookupOrder END CLOSE MemberStatusCursor DEALLOCATE MemberStatusCursor
Running this script will create a parent “Membership Status” metric and then a child metric for each Member Status you’ve defined (and grants the “All Users” role view and edit permissions).
Each of the child metrics will chart the number of people of that member status over time. As long as the ArenaProcessMetrics agent is running, you will see a chart after it’s collected the metrics data twice (two weeks from now).
Historical Data
If you don’t want to wait two weeks to see your data and/or you want to see all your historical member status data up to this point, we can use the core_member_status_history table to generate historical membership status data for your metrics…
SET NOCOUNT ON GO DECLARE @ParentMetricID int DECLARE @MinHistoryDate datetime DECLARE @WorkingDate datetime DECLARE @Status varchar(15) SET @ParentMetricID = (SELECT MAX(metric_id) FROM mtrc_metric WHERE title = 'Membership Status' AND parent_metric_id IS NULL) SET @MinHistoryDate = (SELECT MIN(date_created) FROM core_member_status_history) SET @WorkingDate = GETDATE() DELETE mtrc_metric_item FROM mtrc_metric_item MI INNER JOIN mtrc_metric M ON M.metric_id = MI.metric_id WHERE M.parent_metric_id = @ParentMetricID WHILE @MinHistoryDate IS NOT NULL AND @WorkingDate > @MinHistoryDate BEGIN SET @Status = CONVERT(varchar(10), @WorkingDate, 101) + '...' RAISERROR (@Status, 0, 1) WITH NOWAIT; WITH memberStatusTable (person_id, member_status) AS ( SELECT person_id, ISNULL((SELECT TOP 1 member_status FROM core_member_status_history WHERE person_id = P.person_id AND date_created < @WorkingDate ORDER BY date_created DESC), p.member_status) AS member_status FROM core_person P WHERE date_created <= @WorkingDate ) INSERT INTO mtrc_metric_item SELECT GETDATE() ,GETDATE() ,'' ,'' ,M.metric_id ,(SELECT COUNT(*) FROM memberStatusTable WHERE member_status = L.lookup_id) ,@WorkingDate ,'' ,0 FROM core_lookup L INNER JOIN core_lookup_type LT ON LT.lookup_type_id = L.lookup_type_id INNER JOIN mtrc_metric M ON M.title = 'Number of ' + L.lookup_value + 's' AND M.parent_metric_id = @ParentMetricID WHERE LT.guid = '0B4532DB-3188-40F5-B188-E7E6E4448C85' SET @WorkingDate = DATEADD(wk, -1, @WorkingDate) END
This script will create data for the metrics you created above for as far back as you have data in the core_member_status_history table.
