09.03.2008, 17:11 | #1 |
Участник
|
Автономерация в MS CRM 4
Доброе время суток. Подскажите как сделать автономерацию вида
ККК0001/2008 где: "ККК0001"- , это «Код клієнта». Меняется на один (ККК0001, ККК0001, ККК0003...) «/» - это - «/», 2008, это год. И год автоматически менялся с наступлением нового года.
__________________
Быть в курсе всего первым - значит быть Первым! |
|
11.03.2008, 08:14 | #2 |
Вопрошающий
|
Видимо, используя callout :-)
В SDK описаны подобные примеры
__________________
Победивший противника - силен, победивший себя - величественнен |
|
11.03.2008, 12:00 | #3 |
CRM
|
Да не факт, т.к. может такое получиться, что будут 2 клиента с одним номером. callout вроде асинхронно выполняются, могу ошибаться.
|
|
11.03.2008, 18:42 | #4 |
Участник
|
Если можно, пришлите пример?
__________________
Быть в курсе всего первым - значит быть Первым! |
|
11.03.2008, 20:09 | #5 |
Moderator
|
Callout-ы (в версии 3.0) работают синхронно. Plug-in (в версии 4.0) могут работать как синхронно, так и асинхронно.
|
|
11.03.2008, 22:20 | #6 |
Moderator
|
Мы по тройке такую проблему обсуждали, попробуйте поискать ответ тут: Простая задача нумерации элементов.
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. MS Certified Dirty Magic Professional |
|
06.06.2008, 23:48 | #7 |
Участник
|
Для решения этой задачи могу порекомендовать следующий способ (только что сам возился с этим): создаем плагин который обращается к специально созданной таблице в sql со счетчиком и формируем индекс. Инструкции можно посмотреть здесь: http://blogs.msdn.com/sqlcat/archive...10/572848.aspx
|
|
17.06.2008, 10:22 | #8 |
Заноза в заднице
|
Имею отношение к решению аналогичной задачи двумя способами. После перехода на четверку создал-таки специальную сущность "Нумераторы" (и не в SQL-табличке какой-нить, а непосредственно в базе CRM). Таблицу нумераторов снабдил четырьмя ключевыми атрибутами: "Имя сущности" - nvarchar.45 (такую длину выбрал не помню исходя из каких соображений - тут на истину не претендую, но мне хватает); "Номер" - int; "Префикс" - nvarchar.5 (снова-таки по длине мне пяти символов - за глаза); "Кратность" - int.
"Имя сущности" должно содержать оригинальное имя нумеруемой сущности так, как оно именуется в системе в единственном числе (account, contact, phonecall etc.). "Номер" - целочисленное значение номера последнего нумерованного элемента. "Префикс" - строковое значение, которое необходимо добавить перед номером, а-ля: ККК0001. "Кратность" - целочисленное значение количества разрядов числа, которое не может быть превышено при нумерации элементов, но в то же время, если текущее число нумерации имеет меньшую разрядность, то разница будет заполнена нулями, чтобы получить такое например значение номера: 000000000000432. Данные нумераторов обрабатываются синхронно, плагином перед записью необходимой сущности (pre-action).
__________________
Лень мудрого человека - это необходимое средство нейтрализации кипучей активности руководящих им дураков! |
|
04.08.2008, 17:51 | #9 |
Участник
|
2 Likefire
В данный момент решаю аналогичную задачу. Можно посмотреть на исходный код вашего plug-in'а |
|
06.08.2008, 12:01 | #10 |
Участник
|
2 Likefire:
Это наиболее правильный подход! 2 Dem1urg: Вот мой кусок кода (работающий! под 4-ку! ) Код: int leadNumber = 1; // загружаем системные параметры QueryExpression qeParams = new QueryExpression(); qeParams.ColumnSet = new AllColumns(); qeParams.EntityName = EntityName.new_customparams.ToString(); BusinessEntityCollection customParams = serv.RetrieveMultiple(qeParams); if ((customParams.BusinessEntities != null) && (customParams.BusinessEntities.Length > 0)) { new_customparams currentParams = (new_customparams)customParams.BusinessEntities[0]; DateTime leadlastdate = DateTime.Parse(currentParams.new_leadlastdate.Value); if (leadlastdate.ToString("d") == DateTime.Today.ToString("d")) { leadNumber = currentParams.new_leadcounter.Value + 1; } else { currentParams.new_leadlastdate = new CrmDateTime(); currentParams.new_leadlastdate.Value = DateTime.Today.ToString("s"); } currentParams.new_leadcounter.Value = leadNumber; serv.Update(currentParams); } // присваиваем номер интересу lead currentLead = (lead)serv.Retrieve(EntityName.lead.ToString(), leadId, new AllColumns()); currentLead.new_number = "L-" + DateTime.Now.ToString("yyyyMMdd") + "-" + leadNumber.ToString("000"); serv.Update(currentLead); |
|
07.08.2008, 11:24 | #11 |
Участник
|
А нельзя ли заполнять значение атрибута сущности непосредственно через contex, не вызывая метод Update веб-сервиса?
|
|
07.08.2008, 15:32 | #12 |
Участник
|
2 Dem1urg:
По идее можно! Можно в плагине создать DynamicEntity, содержащую входные параметры: Код: DynamicEntity de = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target]; Но! Атрибуты должны попасть в контекст! В коде, который я приводил выше (кстати, плагин на PostCreate), заполняется поле new_number, которое на форме заблокировано, а потому в контекст никак не попадёт. Чтобы поле попало в контекст, либо оно должно быть изменено на форме, либо передано "насильно" с помощью Image (оформляется при регистрации плагина). Вроде так. |
|
08.08.2008, 18:11 | #13 |
Moderator
|
Поддерживаю Dem1urg. В случае pre действия разумно менять сам контекст записи.
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. MS Certified Dirty Magic Professional |
|
27.10.2008, 11:15 | #14 |
Участник
|
Денис, можете выложить весь код плагина?
|
|
27.10.2008, 13:49 | #15 |
Участник
|
Не могу понять:
должны использовать объект интерфейса Цитата:
ICrmService service = (ICrmService)context.CreateCrmService(true);
|
|
27.10.2008, 16:49 | #16 |
Участник
|
Да, Microsoft настоятельно рекомендует использовать в плагинах исключительно Dynamic Entity. Но...
Короче, я сделал так: Разбил плагин на два класса. В одном - референсы на Sdk, в другом - на CrmService. LeadAutoNumeration.cs Код: using System; using System.Collections.Generic; using System.Text; using Microsoft.Crm.Sdk; using Microsoft.Crm.SdkTypeProxy; namespace My.LeadAutoNumeration { public class LeadAutoNumeration : IPlugin { public void Execute(IPluginExecutionContext context) { string contextOrgName = context.OrganizationName; Guid leadId = (Guid)context.OutputParameters[ParameterName.Id]; AutoNumeration.SetLeadNumber(leadId, contextOrgName); } } } Код: using System; using System.Collections.Generic; using System.Text; using LeadAutoNumeration.CrmData; namespace My.LeadAutoNumeration { class AutoNumeration { public static void SetLeadNumber(Guid leadId, string orgName) { CrmAuthenticationToken token = new CrmAuthenticationToken(); token.AuthenticationType = 0; token.OrganizationName = orgName; CrmService serv = new CrmService(); serv.Url = (string)Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("Microsoft").OpenSubKey("MSCRM").GetValue("ServerUrl") + "/2007/CrmService.asmx"; serv.CrmAuthenticationTokenValue = token; serv.Credentials = System.Net.CredentialCache.DefaultCredentials; int leadNumber = 1; // загружаем системные параметры QueryExpression qeParams = new QueryExpression(); qeParams.ColumnSet = new AllColumns(); qeParams.EntityName = EntityName.new_customparams.ToString(); BusinessEntityCollection customParams = serv.RetrieveMultiple(qeParams); if ((customParams.BusinessEntities != null) && (customParams.BusinessEntities.Length > 0)) { new_customparams currentParams = (new_customparams)customParams.BusinessEntities[0]; DateTime leadlastdate = DateTime.Parse(currentParams.new_leadlastdate.Value); if (leadlastdate.ToString("d") == DateTime.Today.ToString("d")) { leadNumber = currentParams.new_leadcounter.Value + 1; } else { currentParams.new_leadlastdate = new CrmDateTime(); currentParams.new_leadlastdate.Value = DateTime.Today.ToString("s"); } currentParams.new_leadcounter.Value = leadNumber; serv.Update(currentParams); } // присваиваем номер интересу lead currentLead = (lead)serv.Retrieve(EntityName.lead.ToString(), leadId, new AllColumns()); currentLead.new_number = "L-" + DateTime.Now.ToString("yyyyMMdd") + "-" + leadNumber.ToString("000"); serv.Update(currentLead); } } } |
|
31.10.2008, 00:56 | #17 |
Участник
|
Коллеги, а вы не учитываете возможность одновременного обращения за номером нескольких плагинов и получение таким образом двух записей с одинаковыми номерами? Ведь процесс получения номера и обновление его потом - это же не транзакция. Или такую ситуацию вы считаете невозможной?
|
|
31.10.2008, 06:38 | #18 |
Участник
|
При регистрации плагина выбираете Execution mode - Synchronous (Синхронный режим выполнения) - дубликатов быть не должно.
Цитата:
Synchronous and asynchronous execution of plug-ins. Synchronous plug-ins are executed in a pre-defined order as part of the main Microsoft Dynamics CRM event processing. Asynchronous plug-ins are queued and executed independently.
|
|
31.10.2008, 12:06 | #19 |
Участник
|
Цитата:
Гипотетическая ситуация: сущность Account, на Pre-Create зарегистрировано два плагина - PlugIn1 и PlugIn2 (плагины разные, зарегистрированы синхронно). Два человека на двух разных компах инициировали событие Pre-Create сущности Account. По вашему получается, что пока не выполняться PlugIn1 и PlugIn2 для одного пользователя, эти плагины не начнут выполняться для другого пользователя (или может быть пока не выполниться PlugIn1 для одного пользователя он не начнет выполняться для другого). Но такая последовательность выполнения плагинов должна жутко тормозить систему. Получается что пользователи выстраиваются в очередь на обработку плагинов. Не правильнее ли думать, что синхронность будет заключаться в том, что у одного пользователя оба плагина будут выполняться синхронно, тоесть пока не отработает PlugIn1, не запуститься PlugIn2 (а не так, что плагины отработают когда то потом и в какой последовательности фик знает). При этом у второго пользователя эти плагины работают так же но в параллельном потоке. Таким образом пользователи не мешают друг-другу. Но тогда как раз и может возникнуть ситуация, что в двух параллельных потоках одновременно идет доступ к одним и тем же данным. |
|
31.10.2008, 14:03 | #20 |
Moderator
|
Нет. Синхронный механизм доступа предусматривает именно очередь команд и никакой параллелизации. Тормозить жутко не будет, так как ваш плагин вряд ли содержит и 5% от той логики, которая выполняется в системе во время события создания записи.
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. MS Certified Dirty Magic Professional |
|
|
|