[ELMA3] Исключение дублирования контрагентов
Часто бывает, что необходимо обеспечить уникальность контрагентов в базе данных. В системе по умолчанию не организовано ограничение при вводе юридических и физических лиц. Реальная компания имеет свои правила при добавлении контрагента.
Рассмотрим популярную ситуацию, когда правило уникальности для контрагента формулируется так: в базе данных не может быть контрагентов, у которых одинаковые ИНН и город в юридическом адресе.
Реализовать это можно через перехват событий на обновление в базе данных.
Алгоритм следующий. Перед тем, как изменения в объекте будут записаны в базу данных (метод OnPreUpdate), определим тип объекта (IContractor). Если у контрагента указан город в юридическом адресе, ищем с таким же ИНН и городом среди сущаствующих. Если находим, выводим сообщение о не уникальности контрагента. Если город не указан, ищем с таким же ИНН.
Пример сценария с использованием PublicAPI
Для корректной работы сценария необходимо подключить следующие пространства имен:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EleWise.ELMA.API;
using EleWise.ELMA.ComponentModel;
using EleWise.ELMA.CRM.Models;
using EleWise.ELMA.Logging;
using EleWise.ELMA.Runtime.NH.Listeners;
using EleWise.ELMA.Runtime.Settings;
using EleWise.ELMA.Services;
using NHibernate.Event;
Текст сценария:
[Component]
public class ReSaveContractor : EntityEventsListener
{
public override bool OnPreUpdate(PreUpdateEvent @event)
{
// Определяем тип объекта
//----------------------------------------------------------
if (@event.Entity is IContractor) // интерфейс объекта типа Контрагент
{
var Kontragent = (IContractor)@event.Entity;
if (Kontragent.LegalAddress != null && !string.IsNullOrWhiteSpace(Kontragent.LegalAddress.City)) // Если ввели город в юридическом адресе
{
// Ищем по фильтру контрагента указываем ИНН и город и исключаем текущего контрагента
var findKA = PublicAPI.CRM.Contractor.Find(string.Format(@"(INN is NULL OR INN = ’{0}’) and LegalAddress in (City LIKE ’%{1}%’) and Id <> {2}", Kontragent.INN, Kontragent.LegalAddress.City.Trim(), Kontragent.Id));
if (findKA.Count == 0)
{
Logger.Log.Error("==Выход нет дублей ");
} else
{
throw new Exception("Контрагент уже существует. " + string.Format(@"{0}/CRM/ContractorLegal/Details/{1}",
Locator.GetServiceNotNull<CommonSettingsModule>().Settings.ApplicationBaseUrl,
findKA.ElementAt(0).Id) +
" Укажите другие ИНН и город.");
}
} else
{
// Ищем по фильтру контрагента указываем ИНН и город и исключаем текущего контрагента
var findKA = PublicAPI.CRM.Contractor.Find(string.Format(@"(INN is NULL OR INN = ’{0}’) and LegalAddress in (City is NULL OR City = ’’) and Id <> {1}", Kontragent.INN, Kontragent.Id));
if (findKA.Count == 0)
{
Logger.Log.Error("==Выход нет дублей ");
} else
{
throw new Exception("Контрагент уже ." + string.Format(@"{0}/CRM/ContractorLegal/Details/{1}",
Locator.GetServiceNotNull<CommonSettingsModule>().Settings.ApplicationBaseUrl,
findKA.ElementAt(0).Id) +
" Укажите другие ИНН и город.");
}
}
}
return false; // возврат в норме
}
}
Пример сценария без использования PublicAPI
Для этого создадим специальный объект в Дизайнере и назовём его Перехватчик. На вкладке Сценарии карточки этого объекта подключим необходимые пространства в начале сценария:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EleWise.ELMA.ComponentModel;
using EleWise.ELMA.CRM.Models;
using EleWise.ELMA.Logging;
using EleWise.ELMA.Model.Managers;
using EleWise.ELMA.Runtime.NH.Listeners;
using EleWise.ELMA.Runtime.Settings;
using EleWise.ELMA.Services;
using NHibernate.Event;
[Component]
public class ReSaveContractor : EntityEventsListener
{
public override bool OnPreUpdate(PreUpdateEvent @event)
{
// Определяем тип объекта
//----------------------------------------------------------
if(@event.Entity is IContractor) // интерфейс объекта типа Контрагент
{
var Kontragent = (IContractor)@event.Entity;
if (Kontragent.LegalAddress != null && !string.IsNullOrWhiteSpace(Kontragent.LegalAddress.City)) // Если ввели город в юридическом адресе
{
// Ищем по фильтру контрагента указываем ИНН и город и исключаем текущего контрагента
var filterString = string.Format(@"(INN is NULL OR INN = ’{0}’) and LegalAddress in (City LIKE ’%{1}%’) and Id <> {2}",Kontragent.INN, Kontragent.LegalAddress.City.Trim(), Kontragent.Id);
var findKA = EntityManager<IContractor>.Instance.Find(filterString);
if (findKA.Count == 0)
{
Logger.Log.Error("==Выход нет дублей ");
}
else
{
throw new Exception("Контрагент уже существует. "+string.Format(@"{0}/CRM/ContractorLegal/Details/{1}",
Locator.GetServiceNotNull<CommonSettingsModule>().Settings.ApplicationBaseUrl,
findKA.ElementAt(0).Id)+
" Укажите другие ИНН и город.");
}
}
else
{
// Ищем по фильтру контрагента указываем ИНН и город и исключаем текущего контрагента
var filterString = string.Format(@"(INN is NULL OR INN = ’{0}’) and LegalAddress in (City is NULL OR City = ’’) and Id <> {1}",Kontragent.INN, Kontragent.Id);
var findKA = EntityManager<IContractor>.Instance.Find(filterString);
if (findKA.Count == 0)
{
Logger.Log.Error("==Выход нет дублей ");
}
else
{
throw new Exception("Контрагент уже ."+string.Format(@"{0}/CRM/ContractorLegal/Details/{1}",
Locator.GetServiceNotNull<CommonSettingsModule>().Settings.ApplicationBaseUrl,
findKA.ElementAt(0).Id)+
" Укажите другие ИНН и город.");
}
}
}
return false; // возврат в норме
}
}
Здесь можно ещё добавить, что метод OnPreUpdate(PreUpdateEvent @event) вызывается и при создании нового объекта, и при изменении существующего. Таким образом, любые изменения названия и/или города юридического адреса контрагентов будут отслеживаться системой.