2008-09-19

На событие OnSave формы сущности account


/*Start:Script added by Me*/
var CRM_FORM_TYPE_CREATE=1;
var CRM_FORM_TYPE_QCREATE=5;
var Return;
/******* comment 21.04 *******/
if ((crmForm.FormType==CRM_FORM_TYPE_CREATE)||(crmForm.FormType==CRM_FORM_TYPE_QCREATE))
{
var str="http://servername/Dedup/duplicatelist.aspx?name=" + escape(crmForm.all.name.DataValue)+"&EntityTypeId=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
Return = showModalDialog(str,"","resizable=yes;");
if(Return==true)
{ /* продолжить сохранение */
event.returnValue = true;
return true;
}
else
{ /* отменить сохранение */
event.returnValue = false;
crmForm.detachCloseAlert();
//return false;
window.close();
}
}
/******* comment 21.04 *******/
/*End:Script added by Me*/

2008-09-17

Plugin's Starter Execution Method

Have found excellent method at David Fronk blog Starter Execution Method and slightly update it in to separate method.

// based on Starter Execution Method

/// 
/// Return the opportunity id
/// 
/// Plugin context/// opportunityid
public string GetEntityId(IPluginExecutionContext context)
{
 string opportunityid = "";
 DynamicEntity opportunityClose = null;

 switch (context.MessageName)
 {
  case "Create":
   if (context.OutputParameters.Properties.Contains("id"))
   {
    opportunityid = context.OutputParameters.Properties["id"].ToString();
   }
   break;
  case "Update":
   if (context.InputParameters.Properties.Contains(ParameterName.Target) && context.InputParameters.Properties[ParameterName.Target] is DynamicEntity)
   {
    DynamicEntity entity = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target];
    opportunityid = ((Key)entity.Properties["opportunityid"]).Value.ToString();
   }
   break;
  case "SetState":
   if (context.InputParameters.Properties.Contains("EntityMoniker"))
   {
    if (context.InputParameters.Properties.Contains("State"))
    {
     Moniker entityMoniker = (Moniker)context.InputParameters.Properties[ParameterName.EntityMoniker];
     opportunityid = entityMoniker.Id.ToString();
    }
   }
   break;
  case "SetStateDynamicEntity":
   if (context.InputParameters.Properties.Contains("EntityMoniker"))
   {
    if (context.InputParameters.Properties.Contains("State"))
    {
     Moniker entityMoniker = (Moniker)context.InputParameters.Properties[ParameterName.EntityMoniker];
     opportunityid = entityMoniker.Id.ToString();
    }
   }
   break;
  case "Win":
   opportunityClose = (DynamicEntity)context.InputParameters["OpportunityClose"];
   Lookup WonLook = (Lookup)opportunityClose.Properties["opportunityid"];
   opportunityid = WonLook.Value.ToString();
   break;
  case "Lose":
   opportunityClose = (DynamicEntity)context.InputParameters["OpportunityClose"];
   Lookup LoseLook = (Lookup)opportunityClose.Properties["opportunityid"];
   opportunityid = LoseLook.Value.ToString();
   break;
  case "Assign":
   if (context.InputParameters.Properties.Contains("Assignee") && context.InputParameters.Properties["Assignee"] is SecurityPrincipal)
   {
    Moniker assignEntity = (Moniker)context.InputParameters.Properties["Target"];
    opportunityid = assignEntity.Id.ToString();
   }
   break;
  case "Delete":
   if (context.InputParameters.Properties.Contains("Target"))
   {
    Moniker entityMoniker = null;
    entityMoniker = (Moniker)context.InputParameters.Properties[ParameterName.Target];
    opportunityid = entityMoniker.Id.ToString();
   }
   break;
 }
 return opportunityid;
}

2008-09-09

Сущность template, plug-in и Javascript

Начну с того, что сущность template не изменяемая, но настраиваемая. Однако, это не преимущество. Я не понимаю по каким причинам сущность template была скрыта от нас, но ни форма ни события на ней нам недоступны.
Более того, plug-in на шаг PreCreate для этой сущности дает поразительный результат - при выбрасывании InvalidPluginExecutionException стирает тело и тему самого template.
А задача простая - не дать или хотя бы уведомить пользователя о том, что шаблон с таким именем уже существует. Ну чтобы пользователь потом не выбирал из десятка шаблонов с одинаковым title.
Как же решить? Plug-in не функционален, скрипт вставить некуда. Решил внедриться в оригинальную страничку. Называется она emailtemplateeditor.aspx. Там есть функция Save в нее и написал свой код.
Но проблема обнаружилась и тут. Оказывается CRM не дает обратиться к значению поля templateid (нужно, чтобы title не сравнивать с самим собой), т.е. crmForm.all.templateid.DataValue не работает.
Что ж решил действовать старым проверенным способом через crmForm.FormType, чтобы узнать создаем новый шаблон(FormType=1) или редактируем старый(FormType=2). И тут Microsoft окончательно убедил меня в том, что его сотрудники видимо произошли не от углеродной формы жизни - FormType=0 (Undefined form type). Т.е. согласно SDK сущность создана для системных нужд "For internal use only".

Спасло свойство crmForm.ObjectId, которое и содержало значение поля templateid.
В результате скрипт был закончен и стал иметь такой вид:


var url = "http://mcrm4/wsTemplateCreateCheckDup/CheckTemplateTitleDup.asmx/IsDup";
var templateid="null";
if (crmForm.ObjectId != null)
{
templateid=crmForm.ObjectId;
templateid=templateid.slice(1, templateid.indexOf('}'));
}
var paramstr = "TemplateTitle="+crmForm.all.title.DataValue+"&"+"TemplateId="+templateid;
try{
var oXmlHTTP = new ActiveXObject("Msxml2.XMLHTTP");
oXmlHTTP.open("POST", url,false);
oXmlHTTP.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
oXmlHTTP.send(paramstr);
if(oXmlHTTP.status == 200)
{
var retstr=oXmlHTTP.responseText;
var retidx=retstr.indexOf(">found");
if(retidx>0)
{
alert("Имя шаблона '"+crmForm.all.title.value+"' уже есть в списке.\n Пожалуйста, задайте другое имя.");
SubjectEditor.focus();
event.returnValue=false;
return false;
}
}
else
{
alert("Ошибка "+ oXmlHTTP.status+" при проверке на повторное использование имени шаблона.");
}
}
catch(e){alert(e);}