Фильтрация продуктов прайс-листа при формировании заказа

Столкнулся со странной ситуацией:

  1. в CRM заведено несколько прайс-листов,
  2. эти прайсы назначены разным клиентам,
  3. создаём заказ для одного из клиентов (с определённым прайсом),
  4. добавляем в заказ продукт (через создание записи типа "продукт для прайс-листа".

И тут наблюдаем следующее поведение:

  1. в окне лукапа доступны для выбора ВСЕ продукты, независимо, входят ли они в прайс заказа или нет,
  2. в окне лукапа не отображаются продукты у которых не заполнено поле "прайс-лист по умолчанию", даже если этот продукт входит в необходимый прайс (т.е. есть продукт, есть прайс, есть productpricelevel, который их связывает, но при создании заказа, этот продукт недоступен в лукапе (окно "продукт для заказа") пока на самом продукте не будет проставлено поле "прайс по умолчанию", причём прайс этот может отличаться от указанного в заказе).

После небольшого разбора само собой нашлось решение.

ВНИМАНИЕ: это неподдерживаемое решение (т.н. unsupport). Используёте его на свой страх и риск ©

На событие OnLoad сущности "Продукт для заказа" (salesorderdetail) добавлем следующий скрипт:

/*
Функция для получения значния get-параметра из URL формы.
См. также: http://wiki.crrm.ru/index.php/QueryString_параметр_в_Javascript
*/
window.GetQueryString = function(paramName)
{
    var regEx = new RegExp("[?|&]" + paramName + "=([^&|$]*)", "ig");

    if(regEx.exec(window.location.search) != null)
    {
        return RegExp.$1;
    }

    return null;
}

/*
Функция для получения значения заданного атрибута записи CRM.
См. также: http://wiki.crrm.ru/index.php/Клиентские_скрипты_CRM
*/
window.GetAttributeValueFromID = function(sEntityName, sGUID, sAttributeName)
{
    var sXml = "";
    var oXmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

    // set up the SOAP message
    sXml += "";
    sXml += "";
    sXml += GenerateAuthenticationHeader()
    sXml += " ";
    sXml += " " + sEntityName + "";
    sXml += " " + sGUID + "";
    sXml += " " + sAttributeName + "";
    sXml += " ";
    sXml += " ";

    // send the message to the CRM Web service
    oXmlHttp.Open("POST", "/MsCrmServices/2006/CrmService.asmx", false);
    oXmlHttp.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2006/WebServices/Retrieve");
    oXmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    oXmlHttp.setRequestHeader("Content-Length", sXml.length);
    oXmlHttp.send(sXml);

    // retrieve response and find attribute value
    var result = oXmlHttp.responseXML.selectSingleNode("//q1:" + sAttributeName);
    
    return result;
}

/*
Выставление доп.параметра лукапа на продукты в значение GUID прайса, связанного с заказом,
чтобы в файле "\\crmserver\c$\Program Files\Microsoft Dynamics CRM\Server\ApplicationFiles\productwithpricelevel.xml"
по этому значению отфильтровывались только продукты данного прайса.
*/
crmForm.all.productid.AddParam("reportname", GetAttributeValueFromID("salesorder", unescape(GetQueryString('_CreateFromId')), "pricelevelid").nodeTypedValue);

Теперь осталось исправить системное условие фильтрации продуктов в поле "Продукт" карточки "Продукт для заказа". Фильтр данного лукапа прямым текстом описан в файле "c:\Program Files\Microsoft Dynamics CRM\Server\ApplicationFiles\productwithpricelevel.xml".

Выяснилось это следующим образом:

Свойства лукапа в IEDevToolbar

Содержимое файла "productwithpricelevel.xml" до исправления:

<lookup name="ProductWithPriceLevel">
	<objects>
		<object type="1024">
			<columns>
				<column data="name" type="normal" size="200"/>
				<column data="productnumber" type="normal"/>
			</columns>
			<datasource>
				<filter type="and">
					<condition attribute="statecode" operator="eq" value="0"/>
					<condition attribute="pricelevelid" operator="not-null" />
					<filter type="or">
						<condition attribute="productnumber" operator="eq" value="!searchvalue"/>
						<condition attribute="name" operator="like" value="!searchvalue"/>
					</filter>
				</filter>
			</datasource>
		</object>
	</objects>
</lookup>

Доработанная версия файла "productwithpricelevel.xml":

<lookup name="ProductWithPriceLevel">
    <objects>
        <object type="1024">
            <columns>
                <column data="name" type="normal" size="200"/>
                <column data="productnumber" type="normal"/>
            </columns>
            <datasource>
                <filter type="and">
                    <condition attribute="statecode" operator="eq" value="0"/>
                    <filter type="or">
                        <condition attribute="productnumber" operator="eq" value="!searchvalue"/>
                        <condition attribute="name" operator="like" value="!searchvalue"/>
                    </filter>
                </filter>
                <link-entity name="productpricelevel" from="productid" to="productid" alias="pp">
                    <filter type="and">
                        <condition attribute="pricelevelid" operator="eq" value="!reportname" />
                    </filter>
                </link-entity>
            </datasource>
        </object>
    </objects>
</lookup>

Как видно, было удалено условие <condition attribute="pricelevelid" operator="not-null" /> и добавлен фильтр по связанной сущности. Значение параметра !reportname выставляется в скрипте, описанном выше (строкой crmForm.all.productid.AddParam("reportname"...</code>).

Теперь при добавлении продукта в заказ в окне поиска будут отображаться только продукты прайс-листа, который был указан для данного заказа.

Более подробно о фильтрации значений полей типа Lookup смотрите в статье на http://wiki.crrm.ru/index.php/Filtered_Lookup

Русский
field_vote: 
0
Голосов пока нет

Добавить комментарий