Идея

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

Обсуждение
3 комментария

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

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

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

Мотков Илья пишет:
Сомневаюсь, что такое можно полностью реализовать.

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

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

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

Подскажите как добавить связь раздела "Согласующие" в список выбора?

У меня такой же вопрос

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

Для того чтобы добавлять произвольные "Связи" в штатную механику, Вам необходимо добавить ее описание в таблицу EntityConnection

  • SysEntitySchemaUId (это реплика к значению колонки UId из таблицы SysSchema запись в которой описывает схему объекта для которого устанавливается связь
  • ColumUId (это реплика к одноименному полю в таблице SysEntitySchemaReference запись в которой отражает связь объекта с субъектом и его полем, фактически является описанием соотношения справочных полей в объектах)

изучите на примере уже существующих связей.

PS: в помощь Вам SQL скрипт который поможет Вам найти нужное значение по имени колонки и схемы от которой строится связь

-- Ищем колонку Лида (Lead) в схеме Активности (Activity)
SELECT SysEntitySchemaReference.*, Name FROM SysEntitySchemaReference SysEntitySchemaReference
INNER JOIN dbo.SysSchema SysSchema ON SysEntitySchemaReference.SysSchemaId = SysSchema.Id
WHERE ColumnName = 'Lead' AND Name = 'Activity'

Севостьянов Илья Сергеевич,

Все намного проще:

1. Добавить в объект Activity колонку, ссылающуюся на нужный справочник .

2. Найти UId колонки добавленной в первом пункте (в метаданных справочника).

3) Выполнить скрипт предоставленный раннее

     INSERT INTO EntityConnection (SysEntitySchemaUId, ColumnUId) VALUES ('C449D832-A4CC-4B01-B9D5-8A12C42A9F89', 'UId_колонки_из_п.2');

     Где UId колонки - UId колонки для связи из метаданных обьекта Activity.

4) Выполнить очистку кэша и перезайти в систему.

Войдите или зарегистрируйтесь, чтобы комментировать
Идея
Было бы логично при ответе (Reply, Reply to All Forward) на письмо копировать все имеющиеся связи активности (Case, Invoice, Opportunity и остальные).Сейчас лишь подставляется Contact и Account
Реализована
4 комментария

Здравствуйте, Владимир!

Вы можете самостоятельно (базовыми средствами системы) управлять полями, которые будут копироваться при нажатии на кнопку "Копировать".
Для решения:
1) Заместите объект "Активность"
2) Разверните колонки объекта
3) Выберите нужную колонку
4) В свойствах колонки выберите признак "Копировать"
5) Опубликуйте объект

В результате значение выбранной колонки также будет копироваться.

"Демьяник Алексей" написал:Вы можете самостоятельно (базовыми средствами системы) управлять полями, которые будут копироваться при нажатии на кнопку "Копировать".

Алексей, я же специально написал, что e-mail не копируется, а на него пишется ответ (Reply, Reply to All Forward). В этом случае, очевидно, в bpm срабатывает другая логика, нежели при простом копировании.

Я проверял - признак "Копировать" никак не влияет на поля при ответе на письмо (тем более, этот признак в базовой системе уже установлен)

В итоге для Case решилось небольшим кодированием:

define("EmailPageV2", ["BusinessRuleModule", "ConfigurationConstants"],
	function(BusinessRuleModule, ConfigurationConstants) {
		return {
			entitySchemaName: "Activity",
			methods: {
				copyEntityColumnValues: function(entity, actionType) {
					var contact = entity.get("Contact");
					var account = entity.get("Account");
					debugger;
					var caseid = entity.get("Case")
					if (caseid) {
						this.set("Case", caseid);
					}
					if (contact) {
						this.set("Contact", contact);
					}
					if (account) {
						this.set("Account", account);
					}
					this.updateRecepientsOnReply(entity, actionType);
				},
				getEmailSelectColumns: function() {
					return ["Id", "Author", "Owner", "Contact", "Account", "Sender",
						"Recepient", "CopyRecepient", "BlindCopyRecepient", "Body",
						"Title", "StartDate", "MessageType", "Type","Case"];
				}
			},
			details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
			diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/
		};
	});

Здравствуйте, Владимир! Идея реализована в версии 7.11.0.

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

Y de nuevo Hola!

Вопрос возможно банальный. И требует понимание такого явления, как TerraSoft.
Есть карточка редактирования, на ней есть поле - Источник продаж.
"Его нужно поменять у имеющейся записи". После выбора нужного источника (двойной клик, либо кнопка OK) выбрасывается исключение:
Класс исключения EOleExeption
Сообщение об ошибке: Неопознанная ошибка
После повторного нажатия окно закрывается, но результат нулевый, то что должно произойти по логике не происходит.

У меня такой же вопрос

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

Откуда происходит вызов окна выбора источника? Где это прописывается в окне редактирования карточки?

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

F5 в скрипте, верно?
Если да, то в коде прописываю, но после запуска клиента, и вызова соответствующего кода, ничего не происходит.
Буду рад за маленькую инструкцию и по этому вопросу.

Yegor, по отладке ознакомьтесь с статьями:
1. http://www.community.terrasoft.ru/forum/topic/7007#comment-29952
2. http://www.community.terrasoft.ru/blogs/7804

C Debagger'ом разобрался. Спасибо.
На поверхность всплыл факт, не отработки метода Dataset.Append() ( Вечная проблема =) ).
Причина пока не ясна, Dataset, настроен соответствующим образом http://www.community.terrasoft.ru/forum/topic/10595, как описывал Дмитрий.
Первое что пришло в голову - это пересоздать Dataset =)

Может не стоит галка "генерировать запрос на вставку"?

Галки все стоят (кроме "Справочник"). Так же указано "Первичное поле для отображения", и ключевое поле. Вроде бы ничего не забыл...
Код:

try {				
    if (Dataset('StatusID') == osDone || Dataset('StatusID') == osCanceled || Dataset('StatusID') == osExport) {
        var ds = Services.GetNewItemByUSI('ds_SourcesWereChanged');
        ds.Open();
        ds.Append();			
        ds('OrderID') = Dataset('ID');
        ds('NumberOrder') = Dataset('NumberOrder');
        ds('OldSourceID') = Dataset('SourceID');
        ds('SourceID') = DataField.Value;
        ds.Post();
        ds.Close();
        }
} catch (e) {
        MessageBox(e);
}		

При мониторинге через debugger после ds.Append(); ловит [object Error].

Если нужен Append() - Open() делать не нужно. Хотя это вряд ли причина проблемы - но все же избавитесь от "лишнего" SELECT в БД.

"Олейник Дмитрий" написал:

Если нужен Append() - Open() делать не нужно. Хотя это вряд ли причина проблемы - но все же избавитесь от "лишнего" SELECT в БД.


Уяснил.
Проблему нашёл. Благодарю за поддержку!
Причина - неопытные кривые руки, не дают сделать по нормальному связку tbl + sq + ds =(
Прогнал через TerraSoft Administrator без отслеживания исключений, интерпретатор подсказал ошибку.
Думаю всё должно быть ОК. Сейчас буду проверять таблицу, что записал туда.
Дмитрий - спасибо за помощь!

Не за что. Обращайтесь.

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

Добрый вечер.
Задача , которую сейчас решаю: необходимо сделать возможным автоматическую замену связей во вложенных элементах Проекта. Можно считать, что уровень вложенности работ в проект только 1. Т.е. у меня есть Проект, я захожу в него, заполняю поля Клиент, Контакт, Поставщик, Продажа. Потом, стоя на этом проекте, выбираю в меню действия созданное мной действие "Расставить связи в проекте".
После этого срабатывает скрипт:

function amiProcessRelationsOnExecute(ActionMenuItem, Sender) {
        var ProjectID = null;
        if (BaseWorkspace.GridDataset.IsActive) {
                ProjectID = BaseWorkspace.GridDataset.Values('ID');
        }      
        if (ProjectID) {
                ProcessRelations(ProjectID);           
                ShowInformationDialog("Расставлены связи во всех вложенных элементах");
        } else {
                ShowWarningDialog("Проект не выбран");
        }      

}

function ProcessRelations(ProjectID, ProjectDataset) {
        var Relations = new Object();
        Relations.Opportunity = new Object();
        Relations.ObjectOpportunity = new Object();
        Relations.Client = new Object();
        Relations.Contact = new Object();
        Relations.Supplier = new Object();

        if (!Assigned(ProjectDataset)) {
                ProjectDataset = GetSingleItemByCode('ds_Project', 'ProcessRelations');
                ApplyDatasetFilter(ProjectDataset, 'ID', ProjectID, true);
                RefreshDataset(ProjectDataset);
        }      
   
        Relations.Opportunity = ProjectDataset.ValAsGUID('OpportunityID') ;
        Relations.ObjectOpportunity = ProjectDataset.ValAsGUID('object_projectID');
        Relations.Client = ProjectDataset.ValAsGUID('ClientID');
        Relations.Contact = ProjectDataset.ValAsGUID('ContactID');
        Relations.Supplier = ProjectDataset.ValAsGUID('SupplierID');
     
    ProjectDataset.DisableEvents();
   
        if (!Assigned(ChildDataset)) {
    var ChildDataset = GetSingleItemByCode('ds_Project', 'ProcessRelations');
        ApplyDatasetFilter(ChildDataset, 'ParentID', ProjectID, true);

  }
   ChildDataset.Open();
   ChildDataset.Edit();
        try {
                while (!ChildDataset.IsEOF) {
        ChildDataset.Values('OpportunityID') = Relations.Opportunity;
        ChildDataset.Values('object_projectID') = Relations.ObjectOpportunity;
        ChildDataset.Values('ClientID') = Relations.Client;
        ChildDataset.Values('ContactID') = Relations.Contact;
        ChildDataset.Values('SupplierID') = Relations.Supplier;
           
                ChildDataset.Post();    
                ChildDataset.GotoNext();
                }
        } finally {
       
            ChildDataset.Close();
                ApplyDatasetFilter(ChildDataset, 'ParentID', null, false);
                ChildDataset.EnableEvents();   
        }
       
 
        return true;
}

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

У меня такой же вопрос

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

Может я и глупость сморожу, но разве ChildDataset.Edit(); не должен стоять под while?
И зачем try? Наверное, из-за него и не выводит ошибку.

Убрала try, с замиранием сердца :smile: ожидала ошибку, но увы ее нет.

Ничего не написали про результат, видимо отрицательный.
А ChildDataset.Edit(); остался на своем месте? Задаю этот вопрос потому что в вашем случаи у меня выдавал ошибку если подчиненных несколько (либо вы его переставили, либо только один подчиненный)
Но и в том, и в другом случаи я не вижу причину почему не работает.
Наверное, надо пошагово через дебагер смотреть.

ChildDataset.Edit(); переставила.
И не ошибки, ни результата заполнения.

Пока думала над указанной выше задачей, написала функцию , которая в выбранном проекте расставляет крайние сроки во вложенных элементах. Надо было сделать так, чтобы к дате завершения каждой работы прибавлялся один день, и сохранятся в поле Крайний срок этой работы.
Так вот эта фукнция работает на ура!

function ProcessDeadline(ProjectID, ProjectDataset) {
 
    var ChildDataset = GetSingleItemByCode('ds_Project', 'ProcessRelations');
	ApplyDatasetFilter(ChildDataset, 'ParentID', ProjectID, true);
 
   ChildDataset.Open();
 
	try {
		while (!ChildDataset.IsEOF) {
		ChildDataset.Edit();
		var DueDate = ChildDataset.DataFields.ItemsByName('EstimatedDueDate').ValAsDateTime;
		var NewDate= new Date(DueDate);
		var Deadline  = AddDateDays(NewDate, 1).getVarDate();
		ChildDataset.Values('Deadline') = Deadline;
		ChildDataset.Post(); 	
		ChildDataset.GotoNext();
		}
	} finally {
 
	    ChildDataset.Close();
		ApplyDatasetFilter(ChildDataset, 'ParentID', null, false);
		ChildDataset.EnableEvents();	
	}
 
 
	return true;
}

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

var Relations = new Object();
Relations.Opportunity = new Object();
Relations.ObjectOpportunity = new Object();
Relations.Client = new Object();
Relations.Contact = new Object();
Relations.Supplier = new Object();

И писать на прямую

ChildDataset.Values('OpportunityID') = ProjectDataset.Values('OpportunityID');
//и т.д.

Но опять же советую, пошагово в дебагере посмотреть, что происходит.

Так на мой взгляд будет дольше работать скрипт, особенно если там 25 работ вложенных.
Я бы хотела сначала из проекта получить все необходимые мне связи, а потом присваивать эти значения в необходимом месте.
У вас может и не отрабатываться, потому, что object_projectID это мое поле.

И поверьте, никуда, кроме отладчика я не смотрю, однако же ошибку там найти не получается.

Виктория, в отладчике после строки

        ChildDataset.Values('OpportunityID') = Relations.Opportunity;

проверьте, что записано в ChildDataset.Values('OpportunityID').
Будет хотя бы ясно, где именно проблема.

Нашла в чем проблема. В отсутствии строки ApplyDatasetFilter(ProjectDataset, 'ID', null, false);

Окончательный вариант

function amiProcessRelationsOnExecute(ActionMenuItem, Sender) {
        var ProjectID = null;
        if (BaseWorkspace.GridDataset.IsActive) {
                ProjectID = BaseWorkspace.GridDataset.Values('ID');
        }      
        if (ProjectID) {
                ProcessRelations(ProjectID);           
                ShowInformationDialog("Расставлены связи во всех вложенных элементах");
        } else {
                ShowWarningDialog("Проект не выбран");
        }      
 
}
 
function ProcessRelations(ProjectID, ProjectDataset) {
        var Relations = new Object();
        Relations.Opportunity = new Object();
        Relations.ObjectOpportunity = new Object();
        Relations.Client = new Object();
        Relations.Contact = new Object();
        Relations.Supplier = new Object();
 
        if (!Assigned(ProjectDataset)) {
                ProjectDataset = GetSingleItemByCode('ds_Project', 'ProcessRelations');
                ApplyDatasetFilter(ProjectDataset, 'ID', ProjectID, true);
                RefreshDataset(ProjectDataset);
        }      
 
        Relations.Opportunity = ProjectDataset.ValAsGUID('OpportunityID') ;
        Relations.ObjectOpportunity = ProjectDataset.ValAsGUID('object_projectID');
        Relations.Client = ProjectDataset.ValAsGUID('ClientID');
        Relations.Contact = ProjectDataset.ValAsGUID('ContactID');
        Relations.Supplier = ProjectDataset.ValAsGUID('SupplierID');
 
   ApplyDatasetFilter(ProjectDataset, 'ID', null, false);
 
        if (!Assigned(ChildDataset)) {
    var ChildDataset = GetSingleItemByCode('ds_Project', 'ProcessRelations');
        ApplyDatasetFilter(ChildDataset, 'ParentID', ProjectID, true);
 
  }
   ChildDataset.Open();
 
        try {
                while (!ChildDataset.IsEOF) {
        ChildDataset.Edit();
        ChildDataset.Values('OpportunityID') = Relations.Opportunity;
        ChildDataset.Values('object_projectID') = Relations.ObjectOpportunity;
        ChildDataset.Values('ClientID') = Relations.Client;
        ChildDataset.Values('ContactID') = Relations.Contact;
        ChildDataset.Values('SupplierID') = Relations.Supplier;
 
                ChildDataset.Post();    
                ChildDataset.GotoNext();
                }
        } finally {
 
            ChildDataset.Close();
                ApplyDatasetFilter(ChildDataset, 'ParentID', null, false);
                ChildDataset.EnableEvents();   
        }
 
 
        return true;
}

Виктория, рад, что проблема решилась.

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

Коллеги, добрый день!

Есть ряд схем, когда из одного узла элемента (например типа сравнения) нужно сделать переходы к 4-м другим элементам (см. рисунок).
Вопрос: нужно ли "развязывать выходы"? Т.е. например из элемента "Сравнение" будет идти только 1 ветвь, на элемент типа "Скрипт", из которого уже будут выходы на 3 других элемента (соответственно 1 из них придется еще раз "развязывать")?

Есть подозрения что в случае как на рисунке, иногда проходятся не все элементы...
Спасибо!

У меня такой же вопрос

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

Здравствуйте, проверял на следующем БП
1
При этом в случае верности или не верности условия (MyVar == '1') в действии Decision (Сравнение) по БП выполняются несколько действий (в данном примере элементы Скрипт, которые выводят MessageBox). В случае верности или ложности условия все действия выполняются согласно логике.
Просьба проверить БП в прикрепленных файлах, отрабатывает ли он у Вас аналогичным образом.
Значение переменной MyVar устанавливается в скрипте scr1

var diag = GetDiagramByItem(ScriptItem);
WFSetParamValue(diag, 'MyVar', '1');

Если все отработает корректно, проверьте корректность связей между элементами диаграммы БП

Алексей, добрый день.

Выполнились все элементы (более того, в логически правильном порядке, т.к. открывающиеся окна сообщений - модальные, параллельно с ними ничего не будет выполняться). Стрелки в нашей диаграмме присоединены нормально.
Вопрос в том, что ИНОГДА срабатывают не все ветви (т.е. как правило, срабатывают, но не всегда). В нашем случае в каждой из ветвей должна быть создана новая запись в таблице (элемент "Действие системы" с установленным чек-боксом "Создавать новую запись").
В общем, как выяснилось, посде элемента сравнения у нас прицеплены кастомные элементы, реализованные в рамках проекта под нашу компанию. Придется тестировать, тестировать и еще раз тестировать :)

Спасибо.

Здравствуйте,
Вы можете написать на support@tscrm.com указать конкретный БП в котором возникает проблема, и как ее воспроизвести, мы данное обращение передадим в проектный департамент, где Вам помогут найти решение.

Алексей,

Спасибо за предложение, но у нашей проектной команды и так работы невпроворот, уж поверьте.
Я просто думал может есть какие-то выявленные случаи того, что не обрабатываются все ветви.

Спасибо!

Здравствуйте,
Поменял тестовый БП на использование более функциональных действий
1
В действиях чтение/запись данных я изменял значение полей "Полное название" контрагента, и имя контрагента "Ваша компания" (привязка к AccountID с параметов БП), данные действия оба отработали, по другой ветке, я создаю задачу, открываю окно, причем каждое действие отрабатывает.
Для того что бы проверить работоспособность тестового БП, можете подгрузить его в тестовую конфигурацию, предварительно поменяв ID в параметре AccountID

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

Есть замечательное поле "Связи" в Контактах. Но его нет в Контрагентах. Как его создать? Изрыл весь форум, ничего не нашел. Пробовал смотреть аналог в Контактах, но мне этого ничего не дало. Нид хелп!

Спасибо

У меня такой же вопрос

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

Добрый день, Тахир!
Уточните, о чем именно идет речь? Возможно, о полях группы "Средства связи" карточки контакта, или о детали "Взаимосвязи"? И о каком продукте и версии идет речь?

Дмитрий,

есть поле tbl_Contact.Svyazi "Связи"
Оно объединяет поля средств связи и собирает все данные в одном поле, используется для удобного поиска средств связи.
Его можно найти в быстром фильтре в Контактах и в других местах.

Так вот, хотелось бы реализовать аналогичное в tbl_Account.

Terrasoft Real Estate 3.2.0.60

C уважением,
Тахир

______________
www.abs.com.kz
Агентство недвижимости АБС Royal Estate

Тахир, не нашла в базовой версии системы ни в решении Terrasoft RealEstate 3.2.0, ни в Terrasoft Realty 3.2.0 такого поля.
Возможно, речь идет о поле Digits (Цифры номера)в таблице tbl_ContactCommunication.
В скрипте scr_Utils реализована функция, которая отбирает только цифры в номере:

function DigitsFromString(Number) {
	var ValidChars = "0123456789";
	var Result = '';
	var Char;
 
	if (Number.length != 0) {
		for (var i = 0; i < Number.length; i++) {
			Char = Number.charAt(i);
			if (ValidChars.indexOf(Char) != -1) {
				Result += Char;
			}
		}
	}
	return Result;
}

Функция вызывается на событие OnDatasetBeforePost для dlData карточки средства связи scr_CommunicationEdit.

function dlDataOnDatasetBeforePost(Dataset, DoPost) {
	Dataset.Values('Digits') = DigitsFromString(Dataset.Values('Number'));
}

Если у Вас все-таки поле "Связи", то, возможно, этот функционал был реализован в виде проектного решения?

Может и в качестве проектного, но почему оно не идет в стандартной сборке. Очень удобная штука. И кому теперь мне задавать этот вопрос?

Pics.kz Pics.kz

______________
www.abs.com.kz
Агентство недвижимости АБС Royal Estate

"Биккинин Т.Р." написал:И кому теперь мне задавать этот вопрос?

Тому, кто внедрял у Вас проект. Наверное, партнер... или Вы покупали коробку?

--
www.it-sfera.com.ua

да, Лабитек, если я не ошибаюсь.
Тем не менее я очень удивлен, что это не идет в стандартной сборке.

Спасибо
______________
www.abs.com.kz
Агентство недвижимости АБС Royal Estate

Добрый день, Тахир,
Поднял дампы Real Estate версий 3.1, 3.2 и 3.3... Не нашел ничего похожего, да и судя по скриншотам, это не наш стиль именования полей в таблицах, и разделы мы не переименовывали в "Физлица" и "Юрлица" :)
Уточните, пожалуйста, какую именно версию и у кого вы приобретали, делался ли апгрейд на другую версию, проводились ли доработки конфигурации? Можно на почту или в личку.
--------------------------------------------
Лабитек
Центр разработки приложений

А может это Terrasoft Realty, а не Real Estate?

--
www.it-sfera.com.ua

По скриншотам больше похоже на Terrasoft Realty 3.2.0, решение компании "Альфа-Информ", но в базовой версии такого поля точно нет.

"Биккинин Т.Р." написал:Оно объединяет поля средств связи и собирает все данные в одном поле, используется для удобного поиска средств связи.

в Контрагентах можно сделать по аналогии - делаем поле в таблице, в запросе, в датасете. А его заполнение наверное триггером проще сделать, по факту создания или изменения записи в tbl_Account собирать все значения полей Средство связи1, Средство связи2 и т.д... Либо скриптом на событии AfterPost датасета Контрагенты обновлять каждый раз значение этого поля, если я правильно понял как оно работает - содержит в себе ВСЕ что есть в средствах связи

"Виталий Ковалишин aka samael" написал:А может это Terrasoft Realty, а не Real Estate?

опа, новость для меня. а есть разница?

"Александр Кудряшов" написал:в Контрагентах можно сделать по аналогии - делаем поле в таблице, в запросе, в датасете. А его заполнение наверное триггером проще сделать, по факту создания или изменения записи в tbl_Account собирать все значения полей Средство связи1, Средство связи2 и т.д... Либо скриптом на событии AfterPost датасета Контрагенты обновлять каждый раз значение этого поля, если я правильно понял как оно работает - содержит в себе ВСЕ что есть в средствах связи

Александр, вы меня верно поняли. Поле то создано и скрипт на Afterpost тоже есть, но оно не собирает данные из Средств связи.
______________
www.abs.com.kz
Агентство недвижимости АБС Royal Estate

"Биккинин Т.Р." написал:опа, новость для меня. а есть разница?

Terrasoft Realty - это разработка Альфа-Информ
Real Estate - это разработка Лабитек

--
www.it-sfera.com.ua

хм.. будем знать. спасибо
______________
www.abs.com.kz
Агентство недвижимости АБС Royal Estate

Войдите или зарегистрируйтесь, чтобы комментировать