Технические вопросы
5.x

При настройке SMTP для отправки писем всеми пользователями системы указываю значения

SmtpHost - smpt.yandex.ru
SmtpPort - 25 (587)

SmtpUserName - login или login@yandex.ru, без разницы
SmtpUserPassword - свой пароль

При попытке отправить письмо система выдаёт ошибку
The server rejected the specified sender email address. The server responded: 503 5.5.4 Error: send AUTH command first..

В чем может быть проблема?

Нравится

14 комментариев

"Салихов А" написал:smpt.yandex.ru

А если smtp.yandex.ru?

Опечатка в посте. В системе, конечно, smtp.yandex.ru :smile:

Здравствуйте.

Для решения проблемы в схеме SmtpClient в методе SendMessage создание объекта сервер должно быть таким:

var server = new SmtpServer(_credentials.Host, _credentials.UserName, _credentials.UserPassword) {
		  Port = _credentials.Port,
		  SslMode = _credentials.UseSsl ? SslStartupMode.OnConnect : SslStartupMode.Manual,
		  Timeout = _credentials.Timeout,
};

Перед внесением изменений настоятельно рекомендую создать резервную копию базы данных.

Александр, заработало! Спасибо!

Ещё вопрос. Судя по всему значение отправителя берется из поля E-mail контакта, который создаёт новое письмо. Однако параметры SMTP настраиваются только на один почтовый ящик.
Значит ли это, что пользователи системы могут отправлять письма только с одного ящика?

Да, именно так. Отправка происходит с одного почтового ящика, который указан в системных настройках.

Но ведь тогда получается, что у каждого сотрудника в карточке контакта в поле e-mail должен стоять адрес, на который настроена система. Нелогично как-то.

Не совсем. Отправка, действительно, происходит с одного ящика, а в карточке можно указать реальный адрес контакта и тогда физически он отправит письмо с ящика который фигурирует в системных настройках, а в письме будет указано, что с того, который - в карточке контакта.

Александр, механизм ясен. Но я попробовал изменить адрес в карточке контакта, соответственно изменился адрес отправителя в карточке E-mail и при попытке отправить письмо я получил ошибку

The server rejected the specified sender email address. The server responded: 553 5.7.1 Sender address rejected: not owned by auth user..

Значит, Яндекс такого читерства не любит.

"Зверев Александр" написал:

Значит, Яндекс такого читерства не любит.

Неужели всё так безнадёжно?)

Полный код метода, на всякий случай:

		public void SendMessage(MailMessage message) {
			try {
				var client = new Smtp();
				client.Charset = "utf-8";
				var server = new SmtpServer(_credentials.Host, _credentials.UserName, _credentials.UserPassword) {
					Port = _credentials.Port,
					AccountName = _credentials.UserName,
					Password = _credentials.UserPassword,
					SslMode = _credentials.UseSsl ? SslStartupMode.OnConnect : SslStartupMode.Manual,
					Timeout = _credentials.Timeout,
				};
				server.SmtpOptions = ExtendedSmtpOptions.NoChunking;
				client.SmtpServers.Add(server);
				client.Message = message;
				client.Send();
			} catch (MailBeeSmtpNoAcceptedRecipientsException e) {
				throw new SmtpException("ErrorOnSend", NoAcceptedRecipientsError, e);
			} catch (Exception e) {
				throw new SmtpException("ErrorOnSend", e.Message, e);
			}
		}

Попробовал через GMail - письмо отправляется вне зависимости от того, какой e-mail указан в карточке контакта, однако у получателя в поле адреса отправителя отображается адрес, на который настроена система..

Действительно, некоторые почтовики могут распознавать подмену адреса отправителя. В поле "От" будет адрес из карточки контакта.

Показать все комментарии
Технические вопросы
5.x

Здравствуйте, коллеги.
Подскажите, как можно реализовать следующий функционал:
после первого сохранения объекта (пусть, например, это будет счет) нужно запустить хранимую процедуру, в которую нужно передать ID этого объекта.

Нравится

3 комментария

А почему бы не триггером?

триггер AFTER INSERT в БД
что типа

ALTER trigger [TRIGGERNAME] ON [TABLENAME] 
after insert
as
begin
	set nocount on 
	exec sp_YOURPROCEDURE @ID = [INSERTED].[ID]
end

Не забудьте убедиться только, что у пользователя будут права на запуск этой хранимой процедуры.

Показать все комментарии
Технические вопросы
5.x

Здравствуйте!

Как можно организовать доступ для пользователя так, чтобы он мог видеть контактов, контрагентов, активности и т.д., относящихся только к определенной продаже?

Заранее спасибо!

Нравится

1 комментарий

Здравствуйте, Акмаль!

Данную функциональность можно реализовать только на уровне скриптов конфигурации.

В частности, автоматизировать раздачу прав доступа на записи в зависимости от определенного критерия. Например, при установке/изменении ответственного по продаже вычитывать наличие у данного ответственного прав, если их нет - добавлять. делать это лучше всего на событии после сохранения записи.

Раздать права на уровне конфигурации можно следующей конструкцией:

SetEntitySchemaColumnRightLevel(Guid adminUnitId, string schemaName, string columnName, EntitySchemaColumnRightLevel rightLevel)

ОБратите внимание, автоматизация раздачи прав доступа - существенная проектная доработка, она тредует глубокого понимания структуры системы для корректно реализации.

Показать все комментарии
5.x

Здравствуйте!

Есть вопрос по Service Desk. Об отношении сервис - инцидент. От чего нужно отталкиваться?

Вариант 1:
Есть сервисы, которые предоставляет компания (услуги колл-центра, предоставление хостинга и т.д) и инциденты (пропал интернет, что-то не работает и т.д.), которые возникают в контексте этих сервисов. При этом способов разрешения этих инцидентов может быть множество и поэтому классифицировать их не важно.

Вариант 2:
Есть сервисы первого уровня (те же услуги колл-центра, предоставление хостинга и т.д) и те же инциденты, но отталкиваемся уже от сервисов - инструментов разрешения инцидентов (переустановка системы, наладка ПО, что-то ещё).

Как правильно организовать работу СД относительно этих вопросов? Возможно есть другая модель, или может быть различные модели используются в разных случаях?

Проясните пожалуйста ситуацию!

Заранее спасибо.

Нравится

12 комментариев

Если я верно поняла Ваш вопрос, обратите внимание на группировку сервисов. Сервисы делятся на два типа: «Бизнес-сервисы» и «Технические сервисы».
Бизнес-сервис обобщенно группирует подчиненные или связанные с ним технические сервисы, которые представляют собой определенные операции, выполняемые в рамках сервисного обслуживания.
Таким образом Вы можете создать бизнес сервисы «Предоставление хостинга», «Услуги колл-центра», в которые включить технические сервисы «пропал интернет», «настройка учетных записей» и др.
Затем при создании инцидента указать тот сервис в рамках сервисного договора, по которому возник и решается инцидент.

Наталия, спасибо за ответ.
Вы не ошиблись? «пропал интернет» будет относиться к техническим сервисам, а не к инцидентам?

Привела в качестве примера. Можете назвать сервис "Восстановление доступа к Интернет", а инцидент будет звучать "пропал интернет".

Понятно. А можно классифицировать как услугу постпродажную техподдержку? Можно ли сказать, что сбои в проданном ПО будут инцидентами, а прочие обращения - запросами на обслуживание?

Акмаль,

Конечно же можно классифицировать постпродажную техподдержку как услугу. К примеру : сервис будет иметь название "гарантийное обслуживание", в него будут включаться оговоренные время реакции и время разрешения. Соответственно, все сбои будут фиксироваться как инциденты.

Что касательно второй части вопроса - то тут Вы можете самостоятельно выбрать, по какой схеме работать. Классический ITIL называет инцидентом любое событие, не являющееся частью стандартных операций по предоставлению услуги, которое привело или может привести к нарушению или снижению качества этой услуги.

Запрос на Обслуживание — это Запрос от пользователя на поддержку, предоставление информации, консультации или документации, не являющийся сбоем ИТ-инфраструктуры.

Исходя из этого, можно сделать Вывод что предложенная Вами схема работы (сбой в ПО - инцидент, не сбой - запрос на обслуживание) является рекомендуемой.

Игорь, большое спасибо!
Честно говоря не хочется вызывать желание у посетителей треда отправить меня "учить матчасть" и "курить мануалы" (я этим занимаюсь каждую свободную минуту), однако сроки, в которые мне нужны ответы поджимают.
Так что позволю себе ещё пару вопросов, чтобы прояснить ситуацию.

По поводу технических сервисов. Я так понимаю, они определяются, как действия по устранению инцидентов и выполнению запросов на обслуживание? Если да, то как определить минимальное количество технических сервисов, которое должно быть определено? По количеству типовых инцидентов и запросов? Обязательно ли при каждом появлении нетипичного инцидента добавлять новый тс в каталог?

И по поводу процессов и бизнес-процессов. Какую роль они играют во внедрении SD? Понятно, что для обработки входящих событий, которые мы можем составить только после определения перечня услуг, должен быть процесс. Существуют ли ещё какие-то обязательные процессы? И как (и нужно ли) это всё соотнести с процессами, происходящими в бизнесе, которые зависят от предоставляемых услуг?

Буду крайне признателен за ответы.

Акмаль, Вы не вызываете таких желаний и Ваши вопросы вполне обоснованы.

По поводу технических сервисов Вы абсолютно правы. У каждого бизнес сервиса (Печать, Телефония, Интернет итд.) Могут быть неограниченное количество технических сервисов. Количество определяется для каждой компании самостоятельно исходя из состава наиболее частых запросов на обслуживание или инцидентов. При появлении нетипичного инцидента 2 варианта опять же : либо добавить ( потребуется примерная оценка планируемого времени реакции/разрешения и оценка трудозатрат) , либо категоризировать инцидент по существующему сервису (в любом случае некоторые сервисы будут иметь схожее происхождение) . Принимать решение необходимо взвешенно, опять же, исходя из индивидуальной схемы работы каждого клиента.

Касательно бизнес процессов. Безусловно, процессы имеют главенствующую роль, ведь одна из целей внедрение системы - автоматизация работы и прозрачность каждого действия.
Кроме процесса обработки инцидентов, о котором Вы писали, есть целый перечень других процессов : Управление изменениями, релизами, проблемами и многое другое. Безусловно, процессы напрямую связаны с сервисами.

Связать же можно, только изучив задачи клиента и поняв, какие задачи конкретно предстоит решать.Приношу извинения, но более подробно под этого клиента я не смогу описать Вам.
Всё, вышеизложенное - теория, на практике необходимо смотреть специфику для каждого клиента.

Буду рад ответить на любые вопросы возможные.

Игорь, большое Вам спасибо! Вы многое прояснили. Буду двигаться дальше)

Скажите, а имеет ли смысл добавлять в раздел "Сервисы" певоначальные работы по внедрению? Например бизнес-услуга "Инсталляция ПО" и сервисы, входящие в неё - "Установка ОС", "Установка MSSQL Server" и т.д.?

Спасибо.

Предыдущий вопрос в силе. Есть ещё один.

Интересно мнение специалистов, корректно ли будет с точки зрения ITIL, SD, чего угодно, заполнять раздел "Сервисы", отталкиваясь от возможных инцидентов с оборудованием/услугами? Например так:

Бизнес-сервис: Маршрутизаторы (Поддержка работы маршрутизаторов)
Технический сервис: Устранение зависание маршрутизаторов
Технический сервис: Устранение аппаратных сбоев маршрутизаторов
Технический сервис: Устранение системных сбоев маршрутизаторов

или

Бизнес-сервис: Хостинг (Предоставление хостинга)
Технический сервис: Устранение ошибок доступа к сайту из мира
Технический сервис: Устранение ошибок доступа к сайту из другой сети
Технический сервис: Устранение ошибок доступа к сайту по FTP

Заранее спасибо.

"Салихов А" написал:

Скажите, а имеет ли смысл добавлять в раздел "Сервисы" певоначальные работы по внедрению? Например бизнес-услуга "Инсталляция ПО" и сервисы, входящие в неё - "Установка ОС", "Установка MSSQL Server" и т.д.?

Спасибо.


Акмаль, если идет проект по внедрению, выполняемые работы группируются в виде стадий конкретного проекта без привязки к сервисам. Если же услуги оказываются после внедрения проекта - тогда имеет смысл формировать бизнес услугу с входящим в нее набором технических сервисов.
"Салихов А" написал:

Интересно мнение специалистов, корректно ли будет с точки зрения ITIL, SD, чего угодно, заполнять раздел "Сервисы", отталкиваясь от возможных инцидентов с оборудованием/услугами? ......


Подобная структура корректна.

Наталия, спасибо за ответ!

Показать все комментарии
Web_Portal
Технические вопросы
5.x

Здраствуйте,

Можна ли, связать WebPortal не только разделом "Инциденты", но и также другими разделами?
Напр., в зависимости от типа обращение созданном на портала, попадали на раздел "проблема" , или на какой-та, другой новый раздел.

С уважением,
Гюнель

Нравится

1 комментарий

Добрый день, Гюнель.

Для реализации Вашей задачи необходимо в процесс обработки инцидента (вызывается из процесса объекта инцидента) добавить необходимоую Вам логику - запись данных в интересующий Вас раздел, чтение свзянных данных (при необходимости) и т.д.

Показать все комментарии
Технические вопросы
5.x

Если мы решим перейти с CRM на CRM + Service Desc возможно ли будет перенести всю существующую информацию в новую систему?

Спасибо.

Нравится

8 комментариев

решал такую задачу для 3.3 CRM -- 3.4 XRM
было весело ))

Суть следующая:
1) Доработать на новой конфигурации то, что было на старой (главное справочники и детали)
2) написать скрипт SQL версии 1 (и чуть позже последующих)) и добиться его отработки без ошибок:
- надо сбросить (в новой базе) все ключи на данные, которые подлежат копированию (и сразу писать ту часть, где Вы будете их включать обратно). М.б. стоит сбросить и триггеры - я этого не делал.
- скопировать все таблицы из старой базы в новую, сохраняя структуру данных, добавляя там где надо значения по умолчанию (для новых справочников) и т.д.
Возможно, где-то надо будет извращаться как-то так:

CREATE TABLE #AccountBillingInfo(
	[ID] [uniqueidentifier] ROWGUIDCOL  NULL,
	[CreatedOn] [datetime] NULL,
	[CreatedByID] [uniqueidentifier] NULL,
	[ModifiedOn] [datetime] NULL,
	[ModifiedByID] [uniqueidentifier] NULL,
	[AccountID] [uniqueidentifier] NULL,
	[Description] [nvarchar](500) NULL,
	[IsDefault] [int] NULL,
	[Name] [nvarchar](250) NOT NULL,
	[Position] [nvarchar](250) NULL,
	[FIO] [nvarchar](250) NULL,
	[Ground] [nvarchar](250) NULL,
	[CountryID] [uniqueidentifier] NULL,
	[INN] [nvarchar](250) NULL,
	[KPP] [nvarchar](250) NULL,
	[RSN] [nvarchar](250) NULL,
	[BIK] [nvarchar](250) NULL,
	[KSN] [nvarchar](250) NULL,
	[OGRN] [nvarchar](250) NULL,
	[EGRPOU] [nvarchar](250) NULL,
	[NumSertificateNDS] [nvarchar](250) NULL,
	[RegDate] [datetime] NULL,
	[RNN] [nvarchar](250) NULL,
	[IIK] [nvarchar](250) NULL,
	[KBE] [int] NULL,
	[OKPO] [nvarchar](250) NULL,
	[SSN] [nvarchar](250) NULL,
	[UNN] [nvarchar](250) NULL,
	[BankID] [uniqueidentifier] NULL,
	[SignerID] [uniqueidentifier] NULL,
	[Address] [nvarchar](250) NULL)
use [terra2]
go
ALTER TABLE [dbo].[tbl_Document] DROP CONSTRAINT [FK12426AccountSignerIDtbl13]
ALTER TABLE [dbo].[tbl_Invoice] DROP CONSTRAINT [FK115613CustomerSignerIDt14]
ALTER TABLE [dbo].[tbl_Contract] DROP CONSTRAINT [FK134618CustomerSignerIDt3]
ALTER TABLE [dbo].[tbl_Document] DROP CONSTRAINT [FK12426AccountLegalEntity11]
ALTER TABLE [dbo].[tbl_Contract] DROP CONSTRAINT [FK134618CustomerLegalEnti0]
ALTER TABLE [dbo].[tbl_Invoice] DROP CONSTRAINT [FK115613CustomerLegalEnti12]
go
delete tbl_AccountLegalEntitySigner where LegalEntityID in (select (LegalEntityID) from tbl_AccountLegalEntitySigner group by LegalEntityID having COUNT(LegalEntityID) > 1)
												and Position = 'Главный бухгалтер' and LegalEntityID not in (select ID from tbl_AccountLegalEntity where AccountID = (select id from tbl_Account where Name = 'Сфера'))
 
update tbl_Document set AccountSignerID = null where AccountSignerID = 'AEE5C2D2-552B-4009-9A93-E437E405A756'
update tbl_Invoice set CustomerSignerID = null where CustomerSignerID = 'AEE5C2D2-552B-4009-9A93-E437E405A756'
 
delete tbl_AccountLegalEntitySigner where ID ='AEE5C2D2-552B-4009-9A93-E437E405A756'
 
update tbl_Document set AccountSignerID = null where AccountSignerID = 'D834E542-B940-44AE-8A32-5B1052916C99'
update tbl_Invoice set CustomerSignerID = null where CustomerSignerID = 'D834E542-B940-44AE-8A32-5B1052916C99'
 
delete tbl_AccountLegalEntitySigner where ID ='D834E542-B940-44AE-8A32-5B1052916C99'
 
update tbl_Document set AccountSignerID = null where AccountSignerID = 'F5FB7F83-5439-485C-82AE-D36857787542'
update tbl_Invoice set CustomerSignerID = null where CustomerSignerID = 'F5FB7F83-5439-485C-82AE-D36857787542'
 
delete tbl_AccountLegalEntitySigner where ID ='F5FB7F83-5439-485C-82AE-D36857787542'
 
go
 
INSERT INTO #AccountBillingInfo
           ([ID]
           ,[CreatedOn]
           ,[CreatedByID]
           ,[ModifiedOn]
           ,[ModifiedByID]
           ,[AccountID]
           ,[IsDefault]
           ,[Name]
           ,[INN]
           ,[KPP]
           ,[RSN]
           ,[OGRN]
           ,[BankID]
           ,[Address])
SELECT entity.[ID]
      ,entity.[CreatedOn]
      ,entity.[CreatedByID]
      ,entity.[ModifiedOn]
      ,entity.[ModifiedByID]
      ,[AccountID]
      ,[IsDefault]
      ,[LegalName]
      ,[INN]
      ,[KPP]
      ,[RS]
      ,[OGRN]
      ,[BankID]
      ,[LegalAddress]
  FROM [terra2].[dbo].[tbl_AccountLegalEntity] as entity 
 
update #AccountBillingInfo
set #AccountBillingInfo.Position =  t2.Position, #AccountBillingInfo.FIO = t2.Name, #AccountBillingInfo.Ground = t2.BasisForSignature, #AccountBillingInfo.SignerID = t2.ID
from #AccountBillingInfo 
inner join tbl_AccountLegalEntitySigner as t2
	on #AccountBillingInfo.ID = t2.LegalEntityID
 
 INSERT INTO #AccountBillingInfo
           ([ID]
           ,[CreatedOn]
           ,[CreatedByID]
           ,[ModifiedOn]
           ,[ModifiedByID]
           ,[AccountID]
           ,[IsDefault]
           ,[Name]
           ,[Position]
           ,[FIO]
           ,[Ground]
           ,[INN]
           ,[KPP]
           ,[RSN]
           ,[OGRN]
           ,[BankID]
           ,[SignerID])
SELECT signer.ID
      ,entity.[CreatedOn]
      ,entity.[CreatedByID]
      ,entity.[ModifiedOn]
      ,entity.[ModifiedByID]
      ,[AccountID]
      ,[IsDefault]
      ,[LegalName]
      ,[Position]
      ,signer.[Name]
      ,signer.[BasisForSignature]
      ,[INN]
      ,[KPP]
      ,[RS]
      ,[OGRN]
      ,BankID
      ,signer.ID
from [tbl_AccountLegalEntity] as entity left outer join [tbl_AccountLegalEntitySigner] as signer on entity.ID = signer.LegalEntityID
where not exists (select SignerID from #AccountBillingInfo where SignerID = signer.ID) and signer.ID is not null
 
update #AccountBillingInfo
set #AccountBillingInfo.BIK =  t3.MFO, #AccountBillingInfo.KSN = t3.KS
from #AccountBillingInfo 
inner join tbl_Bank as t3
	on #AccountBillingInfo.BankID = t3.ID
 
update tbl_Document 
set tbl_Document.AccountLegalEntityID = #AccountBillingInfo.ID
from tbl_Document inner join #AccountBillingInfo on tbl_Document.AccountSignerID = #AccountBillingInfo.SignerID
where AccountSignerID in (select ID from #AccountBillingInfo where ID = SignerID)
 
update tbl_Invoice 
set tbl_Invoice.CustomerLegalEntityID = #AccountBillingInfo.ID
from tbl_Invoice inner join #AccountBillingInfo on tbl_Invoice.CustomerSignerID = #AccountBillingInfo.SignerID
where CustomerSignerID in (select ID from #AccountBillingInfo where ID = SignerID)
 
update tbl_Contract 
set tbl_Contract.CustomerLegalEntityID = #AccountBillingInfo.ID
from tbl_Contract inner join #AccountBillingInfo on tbl_Contract.CustomerSignerID = #AccountBillingInfo.SignerID
where CustomerSignerID in (select ID from #AccountBillingInfo where ID = SignerID)

- восстановить все сброшенные ключи в новой базе
3) настроить права доступа и раздать их на все существующие записи (во всех администрируемых таблицах)

Вот и все. в принципе ничего сложного :biggrin:

Можно сбрасывать не все ключи, но тогда надо следить за порядком копирования: например перед копированием раздела контрагентов скопировать все его справочники (тип, типы средств связи т.д.) и справочники этих справочников (если есть), т.е. чтобы всегда существовали записи, на которые в копируемых записях есть ключи. Мне было проще сбросить сразу все).

Могу скинуть скрипты, которые я использовал, если саппорт не против

Добрый день!

В рамках технической поддержки, мы можем предоставить готовый пакет перехода, с помощью которого Вы сможете выполнить обновление базы, а также, перенести все существующие данные.

Также, если у Вас нет специалистов, которые могут выполнить перевод, Вы можете воспользоваться услугами специалистов Terrasoft.

Для предоставления утилиты перехода, Вам нужно предоставить на оценку копию Вашей базы данных (обезличенной), после чего, департамент разработки приступает к подготовке утилиты.

С уважением,
Белецкий Арсений
Группа компаний Terrasoft

Большое спасибо всем за ответы.

Кстати, здесь на комюнити есть блог, где обсуждается эта тема.

Для переноса данных очень удобно использовать утилиты dbForge Schema Compare for SQL Server и dbForge Data Compare for SQL Server

А как осуществить экспорт/импорт отдельных элементов? Например, какого-то справочника или контактов?

Для отдельного справочника можно сгенерировать на старой базе INSERT-скрипт, используя SQL Script Generator (для MS) или TOAD (для Oracle, но TOAD не умеет записывать в скрипт BLOB-поля), а потом его запустить на новой базе. Для раздела - аналогично, но сначала перенести связанные справочники и разделы, либо избавиться в скрипте от значений в колонках типа "справочник", которые не будем переносить.

Показать все комментарии
Технические вопросы
5.x

Здравствуйте.

Подскажите, какие есть способы организовать новому сотруднику доступ на чтение и изменение к, например, активностям по определённым контрагентам?

И ещё. Как сделать, чтобы ответственный имел доступ изменять активность, ему назначенную?

Нравится

2 комментария

Здравствуйте.

Если это уже существующие записи, то доступ на них нужно распространять скриптом.
Что-то вроде:

declare @UserName nvarchar(250)
set @UserName = 'ИмяПользователя' --которому предоставляется доступ
declare @Account nvarchar(250)
set @Account = 'ИмяКонтрагента' --по которому предоставляется доступ на активности
declare @AdminUnitID uniqueidentifier
set @AdminUnitID = (select top 1 Id from SysAdminUnit where Name = @UserName)
declare @Reading int
set @Reading = 1 --0 - запрет чтения, 1 - разрешение чтения, 2 - разрешение раздачи прав доступа на чтения
declare @Writing int 
set @Writing = 1 --0 - запрет изменения, 1 - разрешение изменения, 2 - разрешение раздачи прав доступа на изменение
declare @Deleting int 
set @Deleting = 1 --0 - запрет удаления, 1 - разрешение удаления, 2 - разрешение раздачи прав доступа на удаление
 
if (@AdminUnitID is null)
begin
return
end
 
INSERT INTO SysActivityRight([Id], [RecordId], [SysAdminUnitId], [Operation], [RightLevel])
select newid(), a.Id, @AdminUnitID, 0, @Reading
from Activity a
where a.AccountId = (select Id from Account where Name = @Account)
 
INSERT INTO SysActivityRight([Id], [RecordId], [SysAdminUnitId], [Operation], [RightLevel])
select newid(), a.Id, @AdminUnitID, 1, @Writing
from Activity a
where a.AccountId = (select Id from Account where Name = @Account)
 
INSERT INTO SysActivityRight([Id], [RecordId], [SysAdminUnitId], [Operation], [RightLevel])
select newid(), a.Id, @AdminUnitID, 2, @Deleting
from Activity a
where a.AccountId = (select Id from Account where Name = @Account)

Максим, спасибо.

Показать все комментарии
Ответственному
Технические вопросы
5.x

Здраствуйте,

Хочу добавить функцию "Напоминание" на карточку раздела "проблема". Добавила и опубликовала следующие новые поля на объект и карточку раздела.
1. Справочник "Ответственный"
2. Логическое поле "Ответственному"
3. Время/ Дата "Время напоминаний"

Но когда на карточке указываю время напоминании, то появляется следующая предупреждение.

Предупреждение
Невозможно произвести вставку/обновление данных в таблице "Reminding" из-за нарушения целостности данных
The transaction ended in the trigger. The batch has been aborted.

В чем проблема? Не смогли бы подсказать?

С Уважением,
Гюнель

Нравится

2 комментария

Gunel, помимо добавления полей скриптовую логику прописывали?
Вложите, пожалуйста, редактируемые схемы.

Скорее всего вы не заполнили колонку/колонки типа "Справочник".
Напишите код который создает Entity "Reminding".

Показать все комментарии
if
insert
select
добавить
дубли
Технические вопросы
5.x

Подскажите пожалуйста. Вопрос у меня по работе с БД.
Необходимо осуществить добавления в БД не повторяющихся данных из файла. Как получить данные из файла и добавить я разобрался. Добавление делаю с помощью insert:

if (????????){
var insert = new Insert(UserConnection)
  .Into("ConfItemsCode")
  .Set("Name", Column.Const(str));
  insert.Execute();
}

Но передо добавлением в БД мне надо проверить есть ли в этой таблице уже такая запись. Делаю это так:
var select = new Select(UserConnection)
  .Column("Name")
  .From("ConfItemsCode")
  .Where("Name").IsEqual(str); // пробовал и IsLike

str - это переменная типа string - данный из файла.
Вопрос: Как мне узнать есть ли в select какие -либо записи. Пробовал RowCount, HasCondition. Подскажите как это сделать правильно. Желательно получить int или bool для того чтобы проверить а только потом добавлять.

Нравится

2 комментария

Здравствуйте.

Проще всего воспользоваться EnitySchemaQuery классом:

string Str = "test";
 
 
var manager = UserConnection.EntitySchemaManager;
var query = new EntitySchemaQuery(manager, "Account");
var currentAccountId = query.AddColumn(query.RootSchema.PrimaryColumn.Name);
var accountPhone = query.AddColumn("Name").Name;
query.Filters.Add(query.CreateFilterWithParameters(FilterComparisonType.Equal, "Name", Str));
var queryResult = query.GetEntityCollection(UserConnection);
if (queryResult.Count == 0) 
{
       var insert = new Insert(UserConnection)
  .Into("ConfItemsCode")
  .Set("Name", Column.Const(str));
  insert.Execute();
}

Дмитрий, спасибо. Все получилось

Показать все комментарии
BPM. Фильтр DataSource
Технические вопросы
5.x

Добрый день, Коллеги !!!
У меня возник вопрос, как добавить фильтр с подзапросом в DataSource или как загрузить в DataSource EntitySchemaQuery или отобразить вместимое EntitySchemaQuery на гриде. Так как метод CreateFilter() в DataSource отсуствует.
Пример запроса

SELECT ID FROM TABLE WHERE ID IN (SELECT ID FROM TABLE2 WHER FIELD=1);

Нравится

3 комментария

Здравствуйте, Сергей!

Пример создания подобного фильтра для Datasource ниже:

var dataSource = Page.DataSource;
var structure = dataSource.CurrentStructure;
var filtersName = "SubselectFilters";
var filters = dataSource.FindFiltersGroupByName(filtersName);
if (filters != null) {
	structure.Filters.Remove(filters);
}
filters.Add(structure.CreateIsNotNullFilter(dataSource.Schema, "[Activity:Id:Id].Id"));
structure.Filters.Add(filters);

при необходимости можете использовать механизм вложенных фильтров.

Здраствуйте, Анна.

А подскажите как реализовать примерно такой запрос?

SELECT
	[Account].[Id]
FROM
	[dbo].[Account]
	INNER JOIN [dbo].[AccountAddressCLADR] ON ([Account].[Id] = [AccountAddressCLADR].[AccountId])
  --INNER JOIN [dbo].[Address] ON ([Address].[Id] = [AccountAddressCLADR].[AddressId])
WHERE
	[AccountAddressCLADR].[AddressString] LIKE N'%' + N'Кобрин' + N'%'
UNION
SELECT
	[Account].[Id], Account.Name
FROM
	[dbo].[Account]
	INNER JOIN [dbo].[Contact] ON ([Account].[Id] = [Contact].[AccountId])
	INNER JOIN [dbo].[ContactAddressCLADR] ON ([Contact].[Id] = [ContactAddressCLADR].[ContactId])
  INNER JOIN [dbo].[Address] ON ([Address].[Id] = [ContactAddressCLADR].[AddressId])
WHERE
	[Address].[AddressString] LIKE N'%' + N'Кобрин' + N'%'

Здравствуйте, Илья!

В данном случае я рекомендую использовать запросы в БД при помощи DBExecutor, для того, чтобы выбрать необходимые идентификаторы, а затем передавать их в фильтр. Пример:

var sel = new Select(Page.UserConnection)
	.Column("Account", "Id")
	.Column("Account", "Name")
	.Column("AccountCommunication", "Number")
	.Column("CommunicationType", "Name").As("CommunicationTypeName")
	.From("Account")
	.Join(JoinType.Inner, "AccountCommunication").As("AccountCommunicationSearch")
		.On("Account", "Id").IsEqual("AccountCommunicationSearch", "AccountId")
	.Join(JoinType.Inner, "CommunicationType")
		.On("CommunicationType", "Id").IsEqual("AccountCommunicationSearch", "CommunicationTypeId")
	.Join(JoinType.Inner, "AccountCommunication").As("AccountCommunication")
		.On("Account", "Id").IsEqual("AccountCommunication", "AccountId")
	.Where("CommunicationType", "Id").In(_communicationTypeUidQP)
	.And("CommunicationType", "Id").IsEqual("AccountCommunication", "CommunicationTypeId")
	.And("AccountCommunicationSearch", "SearchNumber").IsLike(Column.Parameter(_searchNumber))
	.OrderByAsc("Account", "Name").OrderByAsc("CommunicationType", "Name") as Select;
using (DBExecutor dbExecutor = _userConnection.EnsureDBConnection()) {
	using (IDataReader dataReader = sel.ExecuteReader(dbExecutor)) {
		while (dataReader.Read()) {
			var id = new Guid(dataReader["Id"].ToString());
			var number = dataReader["Number"].ToString();
			if (!_accountDictionary.ContainsKey(id)) {
				_accountDictionary.Add(id, dataReader["Name"].ToString());
				_communicationInfo.Add(id, new Dictionary<string, string>());
			}
			if (!_communicationInfo[id].ContainsKey(number)) {
				_communicationInfo[id].Add(number, dataReader["CommunicationTypeName"].ToString());
			}
		}
	}
}
Показать все комментарии