2010-07-27

TFS 2010 SharePoint Project Portal 403 Forbidden

When you try to open or create the workitem through the project portal you'll get an 403 forbidden error. This is because you have not enough privileges to the folder Inetpub\wwwroot\bin at the TFS server machine.

Just set the next rights to the all domain users.
From IT Blog Posts

Via http://www.cnblogs.com/patrick/archive/2010/04/30/1725167.html

2010-06-22

How to hide a section or field by picklist value

That code snippet will hides a section by name(label) or by label of any field wich is in this section.
if(crmForm.all.new_1!=null)
{
 var oField = crmForm.all.new_1;
 
 // field to hide
 var FieldToHide;
 if(document.getElementById("IDENT") != null)
 {
  FieldToHide = document.getElementById("IDENT");
  FieldToHide.style.display = "block";  
 }
 
 
 // section to hide
 var td = document.getElementsByTagName("td");
 var tableH;
 for(var i=0; i<td.length; i++)
 {
  // enter the correct section name
  if(td[i].innerText == "Section name")
  {
   tableH = td[i].parentNode.parentNode.parentNode;
   tableH.style.display = "block";
  }
 }
 
 
 // here set the needed picklist value
 if(oField.DataValue == 1)
 {
  // field to hide
  if(FieldToHide != null)
  {
   FieldToHide.style.display = "none";  
  }
 }
 else
 if(oField.DataValue == 3)
 {
  // section to hide
  if(tableH != null)
  {
   tableH.style.display = "none";
  }

 }
}

2010-06-10

Tooltip

To add a tooltip at some field on form, jast add next snippet with your changes to form On Load

var ele = document.getElementById("firstname_c");
ele.title = "Name Name Name!";

2010-02-27

Get the localized names of all entities

select  ObjectTypeCode, Name, LogicalName, l.Label
from MetadataSchema.Entity e left join
MetadataSchema.LocalizedLabel l on e.EntityId=l.ObjectId
where l.ObjectColumnName='LocalizedName'
 and l.CustomizationLevel=1

union

select  ObjectTypeCode, Name, LogicalName, l.Label
from MetadataSchema.Entity e left join
MetadataSchema.LocalizedLabel l on e.EntityId=l.ObjectId
where l.ObjectColumnName='LocalizedName'
 and l.CustomizationLevel=0 
 and ObjectTypeCode not in 
  ( select  ObjectTypeCode
   from MetadataSchema.Entity e left join
   MetadataSchema.LocalizedLabel l on e.EntityId=l.ObjectId
   where l.ObjectColumnName='LocalizedName'
    and l.CustomizationLevel=1
  )

Get the params of all localized attributes and all picklist values

SELECT
 e.Name as EntityName
 ,l.Label as 'Наименование атрибута', a.LogicalName ,at.Description as 'Тип атрибута' ,a.AttributeLogicalTypeId
 ,apv.Value as 'Значения пиклиста', lp.Label as 'Наименования пиклиста'
 ,[AttributeRequiredLevelId]
 ,[MaxLength]
 ,[MinValue]
 ,[MaxValue]
 ,LookupClass
 ,LookupStyle
 ,LookupBrowse
FROM
 [NaviconGroup_MSCRM].[MetadataSchema].[Attribute] a
 join MetadataSchema.Entity e on e.EntityId=a.EntityId
 join MetadataSchema.AttributeTypes at on at.AttributeTypeId=a.AttributeTypeId
 join MetadataSchema.LocalizedLabel l on l.ObjectId=a.AttributeId and l.ObjectColumnName='DisplayName'
 left join MetadataSchema.AttributePicklistValue apv on apv.AttributeId=a.AttributeId
 left join MetadataSchema.LocalizedLabel lp on lp.ObjectId=apv.AttributePicklistValueId
order by EntityName, l.Label, at.Description,apv.Value

2010-02-04

Get Picklist Value By Picklist Name

I wrote some method to get picklist value by knowing picklist name.

namespace test
{
    public class CrmServiceProvider
    {

  private WebMetadataService.MetadataService _MetaService = null;
  
  ///* Create a MetadataService end point */
        private WebMetadataService.MetadataService MetaService
        {
            get
            {
                if (_MetaService == null)
                {
                    _MetaService = new WebMetadataService.MetadataService();
                    _MetaService.Url = "http://localhost/mscrmservices/2007/metadataservice.asmx";

                    // Use a special user credentials
     NetworkCredential cred = new NetworkCredential();
                    cred.Domain = ConfigurationManager.AppSettings["Domain"];
                    cred.UserName = ConfigurationManager.AppSettings["UserName"];
                    cred.Password = ConfigurationManager.AppSettings["PassWord"];

                    _MetaService.UseDefaultCredentials = false;
                    _MetaService.Credentials = cred;

                    _MetaService.UnsafeAuthenticatedConnectionSharing = true;

                    WebMetadataService.CrmAuthenticationToken token = new WebMetadataService.CrmAuthenticationToken();
                    token.AuthenticationType = 0;
                    token.OrganizationName = ConfigurationManager.AppSettings["Organization"];

                    _MetaService.CrmAuthenticationTokenValue = token;
                }
                return _MetaService;
            }
        }


  public int GetPicklistValueByPicklistName(string PicklistName, string EntityLogicalName, string LogicalName)
  {
   int retval = -1;
   
   /* Retrieve the attribute metadata */
   WebMetadataService.RetrieveAttributeRequest attributeRequest = new WebMetadataService.RetrieveAttributeRequest();
   attributeRequest.EntityLogicalName = EntityLogicalName;
   attributeRequest.LogicalName = LogicalName; //picklist

   WebMetadataService.RetrieveAttributeResponse attributeResponse =
      (WebMetadataService.RetrieveAttributeResponse)MetaService.Execute(attributeRequest);

   /* Cast the attribute metadata to a picklist metadata */
   WebMetadataService.PicklistAttributeMetadata picklist =
      (WebMetadataService.PicklistAttributeMetadata)attributeResponse.AttributeMetadata;


   foreach (WebMetadataService.Option op in picklist.Options)
   {
    if (op.Label.UserLocLabel.Label == PicklistName)
     retval = op.Value.Value;
   }

   return retval;
  }
 }
}

To call this method use the next construction:
int psv = GetPicklistValueByPaymentSystemName(categorycode, "account", "accountcategorycode");
if (psv > 0)
{
 acc.accountcategorycode = new Picklist();
 acc.accountcategorycode.Value = psv;
}

2009-12-21

Upgrade of javascript function to hide "Add Existing ..." button

I improved the source code for one of my previous post — Remove 'Add Existing...' button from associated view entities form.

function HideAssociatedViewButtons(areaPrefix, loadAreaId, buttonTitles,addAreaParams){
 var navElement = document.getElementById(areaPrefix+loadAreaId); 
   if (navElement != null)    {
        navElement.onclick = function LoadAreaOverride(){
            if(addAreaParams.length>0)
    loadArea('area'+loadAreaId, addAreaParams[0]);
   else
    loadArea('area'+loadAreaId);
            var iframeid='area' + loadAreaId + 'Frame';
   HideViewButtons(document.getElementById(iframeid), buttonTitles);
        }
    }
}
 
function HideViewButtons(Iframe, buttonTitles) { 
    if (Iframe != null ) {
  Iframe.onreadystatechange = function HideTitledButtons() { 
            if (Iframe.readyState == 'complete') { 
                var iFrame = frames[window.event.srcElement.id]; 
                var liElements = iFrame.document.getElementsByTagName('li');
 
    for (var j = 0; j < buttonTitles.length; j++) { 
                    for (var i = 0; i < liElements.length; i++) { 
                        if (liElements[i].getAttribute('title') == buttonTitles[j]) { 
                            liElements[i].style.display = 'none'; 
                            break; 
                        }
                    } 
                } 
            } 
        } 
    }
} 

2009-12-03

On form load set some selected value for related entity pick-list

I had to set the value for related entity pick-list — filter of date for Activities of some account, like it was default Selected value.

SelectArea('Activities', 'scheduledend');
SelectArea('ActivityHistory', 'actualend');

function SelectArea(loadAreaId, selectId)
{
var navElement = document.getElementById('nav'+loadAreaId); 
if (navElement != null) 
{
 navElement.onclick = function LoadAreaOverride() {
  loadArea('area'+loadAreaId);
  var iframeid = 'area'+loadAreaId + 'Frame';
  var Iframe=document.getElementById(iframeid);
  if (Iframe != null ) {
   Iframe.onreadystatechange = function SetAllasDefault() { 
    if (Iframe.readyState == 'complete') { 
     var iFrame = frames[window.event.srcElement.id]; 
     var oSelect = iFrame.document.getElementById(selectId);
     var oOption = oSelect.options[oSelect.options.length-1];
     oOption.selected = true;
     oSelect.FireOnChange();
    }
   }
  }
 
  
 }
}
}
Put at form OnLoad() event;

2009-11-13

Passing parameters between MS CRM plugins

I was needed to pass a variable from one plugin to another. If you have a two plugin at pre and post stage registered for on entity, then you can use a SharedVariables context property. But, if every plugins is a different assembly, and they are registered for a different entities... So, when the first plugin is firing, the second, which is starting after that, needed to know some information for redirecting it logic to another way.

I had created some common assembly with helper methods and called it "Helper". Then I had created a static class with static variable and had put the value into it, at the first plugin execution runtime. In the second plugin I just get the value from the static common variable.

And nothing about read\write DB operations.
Helper assembly.
namespace Helper
{
    public static class Keeper
    {
        private static bool _UpdateOppAfterHistory = true;
        public static bool UpdateOppAfterHistory 
        {
            get { return _UpdateOppAfterHistory; }
            set { _UpdateOppAfterHistory = value; }
        }
        
    }
    public class OpportunityHelper
    { ... }
}

First firing plugin code
Keeper.UpdateOppAfterHistory = false;

OpportunityHelper.CreateOpportunityHistory(Opp,crmService);
                
// removing the flag to the back
Keeper.UpdateOppAfterHistory = true;

Second firing plugin code
// common shared variable analysis
bool UpdateOppAfterHistory = Keeper.UpdateOppAfterHistory;
if (UpdateOppAfterHistory)
{ ... }

2009-11-10

How to hide an items of drop-down list?

"We should not be able to choose some steps of Opportunity History, if the opportunity has no quotes or sales orders." - that was they said.

And that was I wrote.

var oService = null;
var oppid = null;

function FormOnLoad()
{
 oService = new Ascentium_CrmService(null, null);
 
 var oParentCrmForm = window.opener.parent.document.all.crmForm;
 if(oParentCrmForm)
 { 
  oppid = oParentCrmForm.ObjectId;
 }
 
 HideComboboxItems();
}


window.HideComboboxItems = function()
{
var newstep = document.getElementById("new_step");
if(newstep)
{
 // checking opportunity for quotes
 var sFetchXml ='<fetch mapping="logical" aggregate="true" version="1.0"><entity name="quote"><attribute name="quoteid" aggregate="count" alias="count" />'+
  '<filter><condition attribute="opportunityid" operator="eq" value="'+oppid+'" /></filter></entity></fetch>';
 
 var aoFetchResult = oService.Fetch(sFetchXml); 
 var quoteCount = 0;

    if(aoFetchResult.length > 0)
    {
       quoteCount = aoFetchResult[0].attributes["count"].value;
    }
 
 // if no qoutes, then hiding items 4,5,6,7 of dropdown list
 if(quoteCount == 0 )
 {
  var allDropDownElements = newstep.childNodes;
  var lastnodevalue = allDropDownElements.length;
  for(var i=lastnodevalue; i >= 4; i--)
  {
    newstep.options.remove(i);
  }
 }
 else
 {
  // if there is some qoutes, then checking for salesorders
  var sFetchXml ='&lr;fetch mapping="logical" aggregate="true" version="1.0"><entity name="salesorder"><attribute name="salesorderid" aggregate="count" alias="count" />'+
   '<filter><condition attribute="opportunityid" operator="eq" value="'+oppid+'" /></filter></entity></fetch>';
  
  var aoFetchResult = oService.Fetch(sFetchXml); 
  var SOCount = 0;

  if(aoFetchResult.length > 0)
  {
     SOCount = aoFetchResult[0].attributes["count"].value;
  }
  
  // if no salesorders, then hiding items 6,7
  if(SOCount == 0)
  {
   var allDropDownElements = newstep.childNodes;
   var lastnodevalue = allDropDownElements.length;
   for(var i=lastnodevalue; i >=6; i--)
   {
     newstep.options.remove(i);
   }
  }
 }
 
}
}

2009-11-09

Salesorder Fulfill state

I was trying to catch the Fulfill state of sales order and my try was successful, with registering plugin to Update message at Child pipeline. But there was a one little problem - you can't get the salesorderdetail thru service. I don't know why, but the simple code like in "Example 1" was falling down with Generic SQL error x80044150.

//  Example 1
QueryByAttribute qba = new QueryByAttribute();
qba.EntityName = EntityName.salesorderdetail.ToString();
qba.ColumnSet = new AllColumns();
qba.Attributes = new string[] { "salesorderid" };
qba.Values = new object[] { soid };
BusinessEntityCollection bec = crmService.RetrieveMultiple(qba);


Then I was switch on the Fulfill Sdk Message and everything start working fine!
1. open up the SdkMessage view, filter by Name and find the SdkMessageId
2. open up the SdkMessageFilter view, filter by SdkMessageId you got from step 1.
3. change IsCustomProcessingStepAllowed to 'True'

update dbo.SdkMessageFilter
set IsCustomProcessingStepAllowed=1
where SdkMessageId=
(select top 1 SdkMessageId from dbo.SdkMessage where name ='Fulfill')

I have a question, why the Fulfill message has been unplugged from customization?

2009-11-02

Parse XML date in CRM date with Javascript

A JavaScript function to parse an XML (ISO-8601) date string (e.g., "2008-01-18") that returns a JavaScript Date object.

// parsing
function parseDate(xmlDate)
{
      if (!/^[0-9]{4}\-[0-9]{2}\-[0-9]{2}/.test(xmlDate)) {
           throw new RangeError("xmlDate must be in ISO-8601 format YYYY-MM-DD.");
      }
      return new Date(xmlDate.substring(0,4), xmlDate.substring(5,7)-1, xmlDate.substring(8,10));
}

// and using
if(retrievedOpp.attributes["estimatedclosedate"] != null && retrievedOpp.attributes["estimatedclosedate"] != undefined){
     crmForm.all.new_estimatedclosedate.DataValue = parseDate(retrievedOpp.attributes["estimatedclosedate"].value);}

Source http://dev.ektron.com/blogs.aspx?id=14140

2009-10-29

How to determine on which pipeline a plugin is executing - Parent or Childe

The InvocationSource property is an integer value that you can use to determine whether the current plug-in is running in a child pipeline.

MessageInvocationSource Values
FieldValueDescription
Child 1 Specifies a child pipeline
Parent 0 Specifies a parent pipeline

2009-10-20

MS CRM Fetch and Retrieve from javascript

This code snippet was writing exactly like recommended in MSCRM SDK 4.09.
I was put it in OnLoad() event of my account form, and in the lookup field(at my example - new_postalcodeid) at OnChange() event I was calling my function.

There is two function that are doing the same work but with different methods.

var authenticationHeader = GenerateAuthenticationHeader();
crmForm.all.address1_city.ForceSubmit = true;

window.GetRegionByIndex_Retrieve = function()  
{  
 
if (crmForm.all.new_postalcodeid.DataValue == null)
{
  crmForm.all.address1_city.Disabled = false;
 crmForm.all.address1_city.DataValue = "";
 return;
}

var lookupItem = new Array;

lookupItem = crmForm.all.new_postalcodeid.DataValue;
if(lookupItem[0] != null)
{
 // Prepare the SOAP message.
 var xml = "<?xml version='1.0' encoding='utf-8'?>"+ 
 "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'"+
 " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"+
 " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"+ 
 authenticationHeader+ 
 "<soap:Body>"+ 
 "<Retrieve xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>"+ 
 "<entityName>new_postalcode</entityName>"+ 
 "<id>"+lookupItem[0].id+"</id>"+ 
 "<columnSet xmlns:q1='http://schemas.microsoft.com/crm/2006/Query' xsi:type='q1:ColumnSet'>"+ 
 "<q1:Attributes>"+ 
 "<q1:Attribute>new_regcityarea</q1:Attribute>"+ 
 "</q1:Attributes>"+ 
 "</columnSet>"+ 
 "</Retrieve>"+ 
 "</soap:Body>"+ 
 "</soap:Envelope>";
 // Prepare the xmlHttpObject and send the request.
 var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
 xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
 xHReq.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Retrieve");
 xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
 xHReq.setRequestHeader("Content-Length", xml.length);
 xHReq.send(xml);
 // Capture the result.
 var resultXml = xHReq.responseXML;

 // Check for errors.
 var errorCount = resultXml.selectNodes('//error').length;
 if (errorCount != 0)
 {
 var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
 alert(msg);
 }
 // Display the retrieved value.
 else
 {
 crmForm.all.address1_city.DataValue = resultXml.selectSingleNode("//q1:new_regcityarea").nodeTypedValue;
 crmForm.all.address1_city.Disabled = true;
 }
}
}



window.GetRegionByIndex_Fetch = function (){
if (crmForm.all.new_postalcodeid.DataValue == null)
{
  crmForm.all.address1_city.Disabled = false;
 crmForm.all.address1_city.DataValue = "";
 return;
}

var lookupItem = new Array;

lookupItem = crmForm.all.new_postalcodeid.DataValue;
if(lookupItem[0] != null)
{
 var xml = "<?xml version='1.0' encoding='utf-8'?>" +
 "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'" +
 " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +
 " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +
 authenticationHeader +
 "<soap:Body>" +
 "<Fetch xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>" +
 "<fetchXml>" +
 "&lt;fetch mapping='logical'&gt;" +
 "&lt;entity name='new_postalcode'&gt;" +
 "&lt;attribute name='new_postalcodeid'/&gt;"+
 "&lt;attribute name='new_regcityarea'/&gt;"+
 "&lt;filter type='and'&gt;"+
 "&lt;condition attribute='new_postalcodeid' operator='eq' value='"+lookupItem[0].id+"'/&gt;"+
 "&lt;/filter&gt;&lt;/entity&gt;&lt;/fetch&gt;" +
 "</fetchXml>" +
 "</Fetch>" +
 " </soap:Body>" +
 "</soap:Envelope>";

 var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
 xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
 xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Fetch");
 xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
 xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
 xmlHttpRequest.send(xml);
 
 var resultXml = xmlHttpRequest.responseXML;
 // Check for errors.
 var errorCount = resultXml.selectNodes('//error').length;
 if (errorCount != 0)
 {
  var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
  alert(msg);
 }
 // Process and display the results.
 else
 {

  // Capture the result and UnEncode it.
  var resultSet = new String();
  resultSet = resultXml.text;
  resultSet.replace('&lt;','<');
  resultSet.replace('&gt;','>');

  var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
  xmlDoc.async = false;
  xmlDoc.loadXML(resultSet);
  var results = xmlDoc.getElementsByTagName('result');
  
  for(i=0;i<results.length;i++)
  {
   crmForm.all.address1_city.DataValue = results[i].selectSingleNode('//new_regcityarea').nodeTypedValue;
  }
   crmForm.all.address1_city.Disabled = true;
 }
}
}

2009-10-13

How to retrieve from many-to-many entity.

If you need to retrieve something from many-to-many relationship entity, and there is no such entity in CRM, then you should use the FetchXml, instead of Query.
// Base bodel of FetchXml for get relationship entity
string fetchXML =
"<fetch distinct='false' mapping='logical'>" +
"<entity name='" + relationshipName + "'><filter type='and'>" +
"<condition attribute='" + relatedEntityName + "id' operator='eq' value='" + relatedId + "' />" +
"<condition attribute='" + typeEntityName + "id' operator='eq' value='" + profileId + "' />" +
"</filter></entity>" + "</fetch>";

For example, next code snippet is checking a count of relations between the Account entity and New_Industry entity, wich relationship is many-to-many. To achieve this, I need to check the relationship entity - New_industry_account, wich is contains all of relation of our two entities.
ICrmService crmService = context.CreateCrmService(true);

// check for relation
#region FetchXML
string fetchXML =
"<fetch distinct='false' mapping='logical'>" +
"<entity name='new_industry_account'><filter type='and'>" +
"<condition attribute='accountid' operator='eq' value='" + accountid.ToString() + "' />" +
"</filter></entity></fetch>";
#endregion

string fetchresult = crmService.Fetch(fetchXML);
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(fetchresult);
XmlNodeList xnodlist = xmldoc.SelectNodes("resultset/result");
if (xnodlist.Count > 0) { return; }

Update a number of custom attributes of DynamicEntity with TargetUpdateDynamic.

This code I was used in plugins for updating the custom attributes using Microsoft.Crm.SDK.

using System;
using System.Collections.Generic;
using System.Collections;

// Microsoft Dynamics CRM namespaces
using Microsoft.Crm.Sdk;
using Microsoft.Crm.Sdk.Query;
using Microsoft.Crm.SdkTypeProxy;

...

// Extract the DynamicEntity from the request.
entity = (DynamicEntity)retrieved.BusinessEntity;

// declare a property array
ArrayList arrProps = new ArrayList();

// create some property
CrmBooleanProperty new_withindustry = new CrmBooleanProperty();
new_withindustry.Name="new_withindustry";
new_withindustry.Value= new CrmBoolean();
new_withindustry.Value.Value=true;
arrProps.Add(new_withindustry);

// create another property
CrmMoneyProperty new_industrydeal = new CrmMoneyProperty();
new_industrydeal.Name = "new_industrydeal";
new_industrydeal.Value = new CrmMoney();
new_industrydeal.Value.Value = 12345.0m;
arrProps.Add(new_industrydeal);

//   Update the properties array on the DynamicEntity.
entity.Properties.AddRange((Property[])arrProps.ToArray(typeof(Property)));

// Create the update target.
TargetUpdateDynamic updateDynamic = new TargetUpdateDynamic();

// Set the properties of the target.
updateDynamic.Entity = entity;

//   Create the update request object.
UpdateRequest update = new UpdateRequest();

//   Set request properties.
update.Target = updateDynamic;

//   Execute the request.
UpdateResponse updated = (UpdateResponse)crmService.Execute(update);

Dynamic hyperlink in Reporting Services 2008

I had a custom entity - project and was needed to open a project card from the report.
So I had done exactly as saying in http://msdn.microsoft.com/en-us/library/ms157159.aspx and in the expression field of hyperlink I was typed next

="http://SERVERNAME/ORGANIZATIONNAME/userdefined/edit.aspx?id=%7b" & Fields!projectid.Value.ToString() & "%7d&etc=10005"

SERVERNAME and ORGANIZATIONNAME must be replaced with your crm values.

2009-10-12

Registering plugins for event on many-to-many entities

I found that from the box MS CRM 4.0 are not supported the events on many-to-many relationship entities(bridge entities). But Aaron Elder has hack it.

All you need is just register it at AssociateEntities or DiassociateEntities event with empty Primary and Secondary Entity fields.

-- ============================================================================
-- Enable Associate and Disassociate Plug-in Events Script v1.0
-- ----------------------------------------------------------------------------
-- (c) 2009 Aaron Elder
-- ============================================================================
-- DISCLAIMER:
-- This script is provided "AS IS" with no warranties, and confers no rights.
-- ============================================================================
-- While this is obviously "unsupported", I think the fact that these events
-- are not available is a bug and hopefully it will be fixed in a rollup.
-- ============================================================================

USE AscentiumCrmDev_MSCRM
GO

-- Find the deployments SDK Filter ID for the
-- Associate and Disassociate Entity SDK Messages
DECLARE @DisassociateEntitiesFilterId uniqueidentifier
DECLARE @AssociateEntitiesFilterId uniqueidentifier
SET @DisassociateEntitiesFilterId = (SELECT SdkMessageId FROM SdkMessageBase WHERE [Name] = 'DisassociateEntities')
SET @AssociateEntitiesFilterId = (SELECT SdkMessageId FROM SdkMessageBase WHERE [Name] = 'AssociateEntities')

-- Enable the Associate and Disassociate Filters to be valid for custom processing
-- Custom Processing means "you register plug-ins against it"
-- Note: We only do this for the "generic" (OTC == 0) case, just to be safer
UPDATE SdkMessageFilterBase SET IsCustomProcessingStepAllowed = 1
       WHERE SdkMessageId = @DisassociateEntitiesFilterId AND PrimaryObjectTypeCode = 0


UPDATE SdkMessageFilterBase SET IsCustomProcessingStepAllowed = 1
       WHERE SdkMessageId = @AssociateEntitiesFilterId AND PrimaryObjectTypeCode = 0
(C)
http://consulting.ascentium.com/blog/crm/Post533.aspx

2009-10-07

Window redirect and close

This was the window that was opened from CRM form menu (ISV.Config.xml). The window has received some parameters and then redirected to another window, which is preparing and opening the MS Word document, but the pop-up window was still open - this is rude. So, I've closed it.

// call this code on body onload event
function redirect()
{
    // needed URL of pop-up window or modify current location URL
    window.opener.location = window.location.href.replace(/Default2/, "Default");
    window.top.close();
}

Close window from server-side

// closethe page if successful update
RegisterStartupScript("load", "<" + "script type=\"text/javascript\">\n" +
"self.close();\n" +
"<" + "/script>");

Dim strscript As String = "<"+"script language=javascript>window.top.close();<"+"/script>"
If (Not ClientScript.IsStartupScriptRegistered("clientScript")) Then
ClientScript.RegisterStartupScript(Page.GetType(), "clientScript", strscript)
End If

System.Text.StringBuilder sb = System.Text.StringBuilder ();

sb.Append("");

if(!IsClientScriptRegistered("myScript",sb.ToString())
   this.RegisterClientScriptBlock("myScript",sb.ToString());

All of code was found in Internet