Wednesday, March 9, 2011

Getting clean HTML from a Word document using Gmail

Recently, I had to convert a word document into an HTML file. First, like everyone else, I tried to directly save the word file as HTML web page from word.
This saved the file as HTML alright, but when I went to view the HTML source, there were just too many unnecessary tags and the HTML looked almost illegible. So I had to find other means to get this done.

After some search on the Internet, I got to know the following method which helped me get clean HTML out of my word document.
1. Send the word document as an attachment to your Gmail account.
2. Log into Gmail.
3. Open the email with this attachment and click on the "View" next to the attachment.
4. This will open up a new window/tab where Gmail tries to read your word document.
5. On this page click on View->Plain HTML
6. Now you should see the same data without all the formatting as just plain text.
7. Right Click on this Page->View Source to get the HTML portion of this page.
8. The HTML you have right now will be very clean and you can easily work with it from here on.

That's it!


Using CRM Attribute Types

The following are the default values to be set for the different attribute types as defined in the SDK.
// Set up the CRM Service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = 0; 
token.OrganizationName = "AdventureWorksCycle";
 
CrmService service = new CrmService();
service.Url = "http://crm:5555/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;

CrmBoolean boolean = new CrmBoolean();
boolean.Value = true;

CrmDateTime dateTime = new CrmDateTime();
dateTime.Value = "2006/5/27T17:00:00";

CrmDecimal dec = new CrmDecimal();
dec.Value = (decimal)10.1;

CrmFloat f = new CrmFloat();
f.Value = (float)10.1;

CrmMoney money = new CrmMoney();
money.Value = (decimal)10.00;

CrmNumber number = new CrmNumber();
number.Value = 10;

Lookup lookup = new Lookup();
lookup.Value = user.UserId;
lookup.type = EntityName.systemuser.ToString();

Owner owner = new Owner();
owner.type = EntityName.systemuser.ToString();
owner.Value = user.UserId;

Picklist list = new Picklist();
list.Value = 1;

Status status = new Status();
status.Value = 1;

EntityNameReference reference = new EntityNameReference();
reference.Value = EntityName.systemuser.ToString();

Key key = new Key();
key.Value = user.UserId;

Friday, March 4, 2011

PostCreate/UpdatePlugin

Here, when a custom entity is created or updated, I am updating a varchar field in the related contact entity
public void Execute(IPluginExecutionContext context)
        {
            DynamicEntity entity=null;

            //Check if the input parameters contains a target of type Dynamic Entity
            if (context.InputParameters.Properties.Contains("Target") &&
                context.InputParameters.Properties["Target"] is DynamicEntity)
            {
                //obtain the entity from the input parameters
                entity = (DynamicEntity)context.InputParameters.Properties["Target"];

                //TextWriter log1 = TextWriter.Synchronized(File.AppendText(@"D:\Srihari Backup\Log.txt"));
                if (entity.Name == "new_testEntity")
                {
                    
                    try
                    {
                        //log1.WriteLine("inside try");                       

                        
                        DynamicEntity testEntity= (DynamicEntity)context.InputParameters[ParameterName.Target];
                        string clinicName = String.Empty;
                        string contactId= String.Empty;

                        if (testEntity.Properties.Contains("new_clinicname"))
                        {
                            clinicName = (string)testEntity["new_clinicname"];
                            //log1.WriteLine(clinicName);
                        }
                        if (context.MessageName == MessageName.Create)
                        {
                            if (testEntity.Properties.Contains("new_contactid"))
                            {
                                //log1.WriteLine("contains patient id");                                

              //Since the contact is a lookup, cast the object as a lookup.
                                //log1.WriteLine("create message :-");
                                Lookup contactLookup = (Lookup)testEntity["new_contactid"];
                                contactLookup.type = EntityName.contact.ToString();
                                contactId= contactLookup.Value.ToString(); //get the guid of the lookup   
                            }                   
                           
                            
                        }
                        else if (context.MessageName == MessageName.Update)
                        {
                            //log1.WriteLine("update message :-");
//Since this is an update, only the values updated on the form will be available in the context. Hence I am getting the value from an Image that I have registered.
                            DynamicEntity postTestEntity = (DynamicEntity)context.PostEntityImages["contactId"];//The name or 'entityalias' of the image
                            //log1.WriteLine(postCCProvider);
                            Lookup contactLookup = (Lookup)postTestEntity.Properties["new_contactid"];
                            //log1.WriteLine(patientLookup);
                            contactId = contactLookup.Value.ToString();
                            //log1.WriteLine(patientId);

                            //log1.Close();
                        }
                        
                        DynamicEntity contact = new DynamicEntity();
                        contact.Name = EntityName.contact.ToString();

                        Key contactKey = new Key();
                        contactKey.Value = new Guid(contactId);

                        KeyProperty contactGuid = new KeyProperty();
                        contactGuid.Name = "contactid";                 
                        contactGuid.Value = contactKey;
                        contact.Properties.Add(contactGuid);

                        //set the field that needs to be updated in the contact entity.
                        StringProperty ccProviderNameProperty = new StringProperty("new_communitycareprovider", clinicName);
                        contact.Properties.Add(ccProviderNameProperty);

                        ICrmService service = context.CreateCrmService(true);
                        service.Update(contact);


                        
                    }
                    catch (SoapException soapEx)
                    {
                        //log1.Close();
                        throw new InvalidPluginExecutionException("Soap error occured in the plugin", soapEx);                        
                        
                    }
                    catch (Exception ex)
                    {
                        //log1.WriteLine(ex.Message);
                        //log1.Close();
                        throw new InvalidPluginExecutionException("An error occured in the plugin", ex);
                    }
                }
            }
            else
            {
                return; 
            }

           
        }

Creating a document library in Sharepoint through code.


Recently there was a requirement to create a document library in Sharepoint from an ASP.NET page. I used the following code to achive this:
1. Add a reference to the sharepoint list service web service.
2. I then used the List webservice to create the document library using the code below
Web_Reference_Folder.Lists listService = new Web_Reference_Folder.Lists();
listService.Credentials = new System.Net.NetworkCredential("username", "password");
XmlNode ndList = listService.AddList("document library name", "Type any description for your document library", 101);
"101" in the above code is used to create a document library.
Thats it! :)
 –Srihari.

Searching for a file/doc in a document library in Sharepoint


//Call my document library’s listservice webservice 
Sharepoint_WebService.Lists listService = new Sharepoint_WebService.Lists();
                            listService.Credentials = new System.Net.NetworkCredential("username", "password");
                            //get the entire list items from the specified document library
                            XmlNode ndList = listService.GetListItems(accountName, null, null, null, null, null, null);
                            XmlNamespaceManager nsMgr = new XmlNamespaceManager(ndList.OwnerDocument.NameTable);
                            nsMgr.AddNamespace("rs"”, "urn:schemas-microsoft-com:rowset");
                            nsMgr.AddNamespace("z", "#RowsetSchema");
                            //if the document library is empty
                            if (ndList != null)
                            {
                                XmlNode dataNode = ndList.SelectSingleNode("rs:data", nsMgr);
                                int itemCount = Convert.ToInt32(dataNode.Attributes.GetNamedItem("ItemCount").Value);
                                if (itemCount == 0)
                                {
                                    MessageBox.Show("No file to search");                               
                               }
                                else
                                {
                                    //get the entire items in the document library
                                    foreach (XmlNode row in dataNode.SelectNodes("z:row", nsMgr))
                                    {
                                        //if one of the item equals "Group Verification.docx"
                                        if ((row.Attributes.GetNamedItem("ows_LinkFilename").Value).ToString() == "Group Verification.docx")
                                        {
                                            MessageBox.Show("File Found");
                                        }
                                            //no verification document has been uploaded
                                        else
                                        {
                                            MessageBox.Show("File not found");                                       
                                        }
                                    }
                                }
                            }

Points about Pre-update plugin


1. A pre-update plugin can be used to update the field values of the same record/entity.
2. Only the values that we are changing in the entity form will be available in the entity context.
3. If we want to access the values of fields that we are not going to update, then we need to register the image for that entity and include the attributes whose value we need.
4. Finally, we need to directly update the entity context for the changes to get reflected.
Note: We cannot do a service.update(entity) as this will cause the code to go in a circular loop and finally the plugin will throw an error and the changes will not get saved!
Code Sample:
//Updating a boolean value to true or false using Pre-update
// Obtain the target business entity from the input parameters.
entity = (DynamicEntity)context.InputParameters.Properties["Target"];
//Instantiating the boolean property and passing the boolen field name and value to the property
CrmBooleanProperty boolProp = new CrmBooleanProperty("new_verified", new CrmBoolean(false));
//Adding the Property to the entity properties
entity.Properties.Add(boolProp);
-Srihari.

Determining if an Account is a part of a DitributeCampaignActivity


Scenario: Given an account GUID, I should be able to determine if the account is a part of a  "Distribute  Campaign Activity"
The functional flow of the data would be CampaignCampaign ActivitiesCampaign Activity ItemTarget Marketing ListsMarketing List MembersAccounts
 I was trying to look into the database for my answers and before reaching the solution, the following are my findings:
1.       List and ListMember are the tables that contain the data about a marketing list
2.       Similarly, Campaign and CampaignActivity tables contain information about the Campaign records.
3.       Intersect Tables: When there is a many-to-many relationship between two entities, an intersect table is created. This is true for both system relationships built in to the product as well as custom many-to-many relationships. This is how we used to create M:M relationships in CRM 3.0 but it’s implemented OOB in CRM 4.0(See “Using Intersect Tables” in SDK for more info)
4.       The Intersect Table between List and CampaignActivity isCampaignActivityItem.
5.       There is also a ‘DistributeCampaignActivity’ message using which we can distribute a campaign programmatically. However, we cannot register a plugin against this message as it’s not supported.
6.       So, although I was getting all the info individually, I was still not able to determine if an account was a part of a DistributeCampaignActivity.
7.       Then I found that all the plugin registration messages are stored in theSdkMessageBase and the SdkMessageFilterbase tables and there was a‘DistributeCampaignActivity’ message in the table but it was not exposed.
8.       So, I used the below query  in order to expose the‘DistributeCampaignActivity’ message in the plugin registration tool.(Unsupported)

update sdkmessagefilterbase
set isCustomProcessingStepAllowed=1
where sdkmessageid=(select sdkmessageid from sdkmessagebase where name='DistributeCampaignActivity')
9.       I then registered a post-update plugin with message name‘DistributeCampaignActivity’ and Primary Entity: CampaignActivity10.   This time, when I clicked on the ‘DistributeCampaignActivity’ button for a Campaign, I was able to debug the plugin and find out that it was creating a record of type BulkOperationID11.   Naturally, I checked and found that there were 2 tables:  BulkOperation andBulkOperationLog and an entry was made into these tables ONLY when the record was of type “Distribute” or “QuickCampaign“.
12.   Finally, I was able to arrive at the below query which tells me if an account is a part of a ‘DistributeCampaignActivity’ or a QuickCampaign created in the last 7 days based on the account GUID: 
select COUNT(1) 
from FilteredBulkOperation FBO, FilteredBulkOperationLog FLOG 
where FBO.activityid=FLOG.bulkoperationid 
and FBO.actualend >= GETDATE()-7 and actualend<= GETDATE()
and FLOG.regardingobjectid ='20C7A5F8-AD02-DE11-83DE-0003FFE51F61'  /*–The Account GUID–*/
Thats it! :)