July 2008 - Posts

What Version of K2 [blackpearl] am I Running?

Note to self:  To quickly see what version of K2 [blackpearl] you are currently running, just go to Control Panel, Add Remove Program and it should be there as part of the product name.

Needed this information when submitting a ticket to K2 Customer portal and I didn't quite recall what latest version was running on our production server.  Took a guess and it turned out to be wrong.  Chatted with K2 support and they told me how to quickly get that info.

Now, why didn't I think of doing that before?  Hehehe.

emoticon
Share this post: | | | |
Posted by Jimmy Chandra | with no comments
Filed under:

Setting Destination Users as Mail Event Recipient in K2 BlackPearl

So, I was working on a K2 BP workflow project.  One of the requirement for the project is to email a bunch of users (ideally those belonging to a role of some sort) when something happen.  So far, so good.  It seems simple enough. 

With that in mind, I created the role in K2 BlackPearl Management Console, launch Visual Studio and created a K2 Workflow project, drag a Default Activity from my toolbox, quickly configured my Destination Users to the role that I created previously and finally, I drag a Mail Event to the Activity.  The configuration dialog for the mail event came up and I started filling in details of the email. 

When I want to specify the current Activity's Destination User as my mail recipient I got a little surprised.  It's not checkable!  Oh my...

I cancelled out from the screen since I couldn't really do anything else except Cancel at this point.  Went back to the Activity Property dialog and made sure that I have Destination Users for it properly selected (which they are).

emoticon

What's going on here??? I did this before on another project and I was able to do just that (check the Destination User as the recipient in my mail event, albeit I did encounter something similar to this situation but somehow managed to get it to work).  How come it wouldn't let me do it this time?

After trying a couple more times and feeling frustrated, I decided to throw the towel and asked for help.  After chatting with a resource at SourceCode APAC (DC), he informed me to do the following:

     you need to change the dests to use "Plan per slot"

    by default it uses "Plan once" option and the mail code isnt clever enough to get the list of users at run time

Armed with the knowledge, I recalled doing something like this on the previous project.  Something involving running the Activity Destination Users Wizard in Advanced Mode.  So I went back to my Activity property dialog and choose Destination Users icon from the left side and clicked the Back button to get the Welcome screen (that has this option).  Ticked the checkbox and clicked next again.

Once I clicked next, I arrived at the Destination Rule Options Dialog page.  From here I can choose other Options instead of the default Plan just once option.  DC suggested Plan per slot, but actually Plan per destination will also work and in this case, I think is the more appropriate choice for me.

I continued setting up my Destination Rule to fit my requirement (send notification and let anyone in my destination users (role) complete  the task and move on to the next step).

Once I'm done with the activity's Destination Users setup, I went back and insert a Mail Event into the activity and look what I can do now...

Thanks, DC.

emoticon
Share this post: | | | |
Posted by Jimmy Chandra | with no comments
Filed under:

DataSet Xml Deserialization Data / Schema Load Order

Note to self:

When deserializing a dataset from xml, make sure to execute ReadXmlSchema before executing ReadXml, otherwise you'll have problem when you try casting your data into the correct data type.

using System;
using System.Data;
using System.IO;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            //Serialize the sample data
            var ds          = InitDataSource();
            var dataXml     = SerializeData(ds).ToString();
            var schemaXml   = SerializeSchema(ds).ToString();
 
            //Example of bad order
            var dsBad = new DataSet();
            dsBad.ReadXml(new StringReader(dataXml));
            dsBad.ReadXmlSchema(new StringReader(schemaXml));
 
            Console.WriteLine("Bad Example Result:");
 
            try
            {
                Console.WriteLine(
                    string.Format("{0}:{1} {2:N2}",
                        (int)dsBad.Tables[0].Rows[0][0],        //Will throw exception here
                        dsBad.Tables[0].Rows[0][1],
                        (decimal)dsBad.Tables[0].Rows[0][2]));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
 
            Console.WriteLine();
 
            //Example of good order
            var dsGood = new DataSet();
            dsGood.ReadXmlSchema(new StringReader(schemaXml));
            dsGood.ReadXml(new StringReader(dataXml));
 
            Console.WriteLine("Good Example Result:");
            Console.WriteLine(
                string.Format("{0}:{1} {2:N2}",
                    (int)dsGood.Tables[0].Rows[0][0],
                    dsGood.Tables[0].Rows[0][1],
                    (decimal)dsGood.Tables[0].Rows[0][2]));
 
            Console.WriteLine();
            Console.WriteLine("Press any key...");
            Console.ReadLine();
        }
 
        private static StringWriter SerializeSchema(DataSet ds)
        {
            using (var sw = new StringWriter())
            {
                ds.WriteXmlSchema(sw);
                return sw;
            }
        }
 
        private static StringWriter SerializeData(DataSet ds)
        {
            using (var sw = new StringWriter())
            {
                ds.WriteXml(sw);
                return sw;
            }
        }
    
        private static DataSet InitDataSource()
        {
            var ds = new DataSet("Foo");
 
            //Setup Sample DataTable
            var dt = new DataTable("Bar");
            dt.Columns.Add("Id", typeof (int));
            dt.Columns.Add("Description", typeof (string));
            dt.Columns.Add("Price", typeof (decimal));
 
            //Populate with Sample Data
            dt.Rows.Add(1, "Banana", 6.05m);
 
            ds.Tables.Add(dt);
            return ds;
        }
    }
}
Share this post: | | | |
Posted by Jimmy Chandra | with no comments
Filed under: ,