Вопрос

Объект - ContractVisa,
Метод- GetNotificationInfo

Ошибка: При формировании визы по договору получаем значение contract.AccountName и contract.ContactName.
Но если для объекта Account и/или Contact изменить поле для отображения то при получении значения contract.AccountName (contract.ContactName) получаем ошибку Undefined.

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

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

В объекте Contract нет отдельного поля AccountName. Это автоматически созданное поле для первичного поля отображения контрагента:

{
  "UId": "b1b39ef5-5550-41b4-9ad9-77f60c847d89",
  "Name": "Account",
  "CreatedInSchemaUId": "897be3e4-0333-467d-88e2-b7a945c0d810",
  "ModifiedInSchemaUId": "897be3e4-0333-467d-88e2-b7a945c0d810",
  "CreatedInPackageId": "1401a881-7126-4c81-86f8-4e9e355b0669",
  "DataValueTypeUId": "b295071f-7ea9-4e62-8d1a-919bf3732ff2",
  "ReferenceSchemaUId": "25d7c1ab-1de0-4501-b402-02e0e5a72d6e",
  "RequirementType": 1,
  "IsIndexed": true,
  "ColumnValueName": "AccountId",
  "DisplayColumnValueName": "AccountName"
},

Соответственно, при изменении первичного поля в настройках объекта Account поле в Contract тоже изменит название. С ContactName всё аналогично.

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

 

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

Отсутствует возможность установить связь Договора с Продажей. Что является странным, т.к. в стандартном процессе есть стадия "Контрактация". Т.е. стадия процесса есть, а связи с ключевым объектом стадии нет.Заказ сформировать из Продажи можно, Договор на основании Заказа - тоже можно. Но многие компании формируют с клиентом рамочный договор, т.е. исполняется 1 процесс продаж, заключается 1 договор, а вот заказов может быть неограниченное число. Такую модель отношений стандартной схемой не реализовать.

Ревью
1 комментарий

Добрый день, Наталья!

В базовой конфигурации системы действительно отсутствует деталь в продаже для связи с договором. Обходным решением может быть создание собственной детали используя наш мастер. Что же касается внесения данной функциональности в базовую логику работы системы, то по данному вопросу уже есть зарегистрированная проблема на команду разработки продукта с целью реализации в последующих релизах. Номер проблемы 989.

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

Добрый день!

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

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

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

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

Добрый день, Николай! По структуре данных всё осталось как и раньше: в объекте находятся оба поля: и Контрагент, и Контакт. А вот на странице используется специальный контрол. Вся логика прописана в схеме страницы. Можете взять за пример счет или заказ и скопировать в любую нужную вам сущность.

Юлия, спасибо! Буду пробовать.

Николай, необходимо сделать следующее:
- Добавить аттрибут Client с колонками Contact, Account (можно посмотреть в InvoicePageV2)
- В diff добавить поле Клиент и скрыть поля Account и Contact
- Настроить правила фильтрации (несколько полей в договорах вроде по Account фильтруются)

Еще раз спасибо за информацию - все получилось.
Но, столкнулся с одним нюансом. При выборе в поле Client записи из таблицы Contact, у которой в свою очередь проинициализировано поле Account, происходит заполнение поля Account в договоре, но согласно нашей бизнес-логике, такого не должно происходить.
Как я понимаю, это "дело рук" одного из унаследованных бизнес-правил. В связи с этим вопрос - как правильно отключать унаследованные бизнес-правила?
Пока вышел из ситуации переопределением данного бизнес-правила:

"Contact": {
  "FiltrationContactByAccount": {
    "ruleType": BusinessRuleModule.enums.RuleType.FILTRATION,
    "autocomplete": false,
    "autoClean": false,
    "baseAttributePatch": "Account",
    "comparisonType": this.Terrasoft.ComparisonType.EQUAL,
    "type": BusinessRuleModule.enums.ValueType.ATTRIBUTE,
    "attribute": "Account"
  }
}

Здравствуйте, Николай!

Вам необходимо заместить базовое правило его переопределением.

Хм... оказалось, не все так просто...
При вводе текста непосредственно в данное поле, происходит поиск по контрагентам и контактам - тут все ОК. Но, при попытке открыть окно выбора (при нажатии кнопки с лупой) на экране появляется пустое окно без контролов, а в консоле браузера наблюдается следующее сообщение об ошибке:

message: Cannot read property 'split' of undefined 
 date: Tue Dec 15 2015 23:53:11 GMT+1000 (VLAT)
 moduleId: SectionModuleV2_ContractSectionV2_CardModuleV2_chain00000000-0000-0000-0000-000000000000_LookupPage
 moduleName: LookupPage

Я так понимаю, где-то нужно указать правильный LookupPage. Вопрос - где?

Хм... оказалось, не все так просто...
При вводе текста непосредственно в данное поле, происходит поиск по контрагентам и контактам - тут все ОК. Но, при попытке открыть окно выбора (при нажатии кнопки с лупой) на экране появляется пустое окно без контролов, а в консоле браузера наблюдается следующее сообщение об ошибке:

message: Cannot read property 'split' of undefined 
 date: Tue Dec 15 2015 23:53:11 GMT+1000 (VLAT)
 moduleId: SectionModuleV2_ContractSectionV2_CardModuleV2_chain00000000-0000-0000-0000-000000000000_LookupPage
 moduleName: LookupPage

Я так понимаю, где-то нужно указать правильный LookupPage. Вопрос - где?

Проверил данный способ как на Документах, так и на Договорах. Опишу по пунктам действия:

1. Мастером раздела добавил любое существующее поле, что бы система создала замещающую схему страницы. Что не обязательно, если у вас уже есть в пользовательском пакете замещающая схема для страницы.

2. Убедился что в объекте есть колонки как "Контакт" так и "Контрагент".

3. Добавил зависимость на бизнес правила:

define('ContractPageV2', ['ContractPageV2Resources', 'GeneralDetails', "BusinessRuleModule"],
function(resources, GeneralDetails, BusinessRuleModule) {

4. Добавил атрибут:

attributes: {
   "Client": {
	"caption": "TestClient",
	"dataValueType": this.Terrasoft.DataValueType.LOOKUP,
	"multiLookupColumns": ["Contact", "Account"],
	"isRequired": false
   }
},

5. Вывел поле на форму:

diff: /**SCHEMA_DIFF*/[
	{
		"operation": "insert",
		"parentName": "Header",
		"propertyName": "items",
		"name": "Client",
		"values": {
			"layout": {"column": 0, "row": 3, "colSpan": 12},
			"controlConfig": {
				"enableLeftIcon": true,
				"leftIconConfig": {"bindTo": "getMultiLookupIconConfig"}
			}
		}
	}
]/**SCHEMA_DIFF*/,

6. Добавил правило:

rules: {
	"Contact": {
		"FiltrationContactByAccount": {
			"ruleType": BusinessRuleModule.enums.RuleType.FILTRATION,
			"autocomplete": false,
			"autoClean": false,
			"baseAttributePatch": "Account",
			"comparisonType": this.Terrasoft.ComparisonType.EQUAL,
			"type": BusinessRuleModule.enums.ValueType.ATTRIBUTE,
			"attribute": "Account"
		}
	}
},

7. В расчет не беру того факта что поле "Контрагент" по умолчанию обязательное к заполнению в договоре, но отключить это условие, не должно составить проблем, если то позволяет ваша бизнес логика.

Как итог, все работает:

Возможно причина ошибки в дополнительных действиях. Логика же добавления мультиполя верна.
Версия: 7.7.0.2161
Полный код схемы: https://jsfiddle.net/4x35pknd/

Причину ошибки удалось установить совместными усилиями с техподдержкой.
Дело оказалось в том, что пакете SalesContracts переопределен метод loadVocabulary, из-за этой подмены, карточка не открывалась. Нужно было вернуть методу исходный вид из карточки BasePageV2 и проблема ушла.
На всякий случай, вдруг кому-то еще пригодится, вот этот фрагмент кода:

methods: {
  loadVocabulary: function(args, columnName) {
    var multiLookupColumns = this.getMultiLookupColumns(columnName);
    var config = (Ext.isEmpty(multiLookupColumns))
      ? this.getLookupPageConfig(args, columnName)
	: this.getMultiLookupPageConfig(args, columnName);
    this.openLookup(config, this.onLookupResult, this);
  }
}
Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Доброго времени суток!
Собственно, задача состоит в следующем. Определенный тип договоров создается с обязательным полем, в котором указывается родительский договор. К одному родительскому договору могут прикреплены любое количество подчиненных договоров. Нужно: при прикреплении файла на деталь Файлы в подчиненных договорах, создавать такие же в родительском, т.е. на детали Файлы родительского договора должны быть все файлы всех подчиненных договоров. (естественно без дублей самих файлов в базе).
Как вариант решения - отслеживать добавление записей в разгрузочную таблицу tbl_FileInContract, и добавлять запись с ID родительского договора и ID файла. Правильный ли будет этот подход и каким образом его можно реализовать?

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

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

Здравствуйте, Константин!

Алгоритм абсолютно правильный. Вам следует добавить свою функцию в function ProcessAfterAddOperations(AddedFileIDsArray) в скрипте scr_FilesDetailGridArea

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

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

Для того чтобы добавить действие «Создать документ на основании договора» в раздел [Договоры] необходимо придерживаться следующего алгоритма:
1. Запустить Terrasoft Administrator.
2. Открыть сервис wnd_ContractsWorkspace. Перейти на закладку «Невизуальные», выделить компонент amiActions. Добавить новый ActionMenuItem:
o1

Заполнить свойства следующим образом:
o2

Сохранить изменения.
3. Перейти на закладку «События». Для добавленного компонента amiDocumentByContract создать обработчик события OnExecute:
o4

В теле функции обработки события прописать код:

FUNCTION amiDocumentByContractOnExecute(ActionMenuItem, Sender) {
         var ContractIDs = BaseWorkspace.Grid.SelectedIDs;
            var Count = ContractIDs.Count;
            IF (!Count||IsDatasetEmpty(dlContracts.Dataset)) {
                        ShowWarningDialog(GridNotContainsAnyRecords);
                        RETURN;
            }
            IF (Count > 1) {
                        var Message = FormatStr(GridContainsSomeRecords, Count);
                        IF (ShowConfirmationDialog(Message) == mrYes) {
                                   CreateDocumentByContract(ContractIDs);
                        }
            } else {
                        CreateDocumentByContract(ContractIDs);
            }
}

В этом же скрипте (wnd_ContractsWorkspaceScript) реализовать функцию FUNCTION CreateDocumentByContract(ContractIDs)

FUNCTION CreateDocumentByContract(ContractIDs) {
            var ContractDataset = dlContracts.Dataset;
            FOR (var i=0; iContractIDs.Count; i++) {
                        var Dataset = Services.GetSingleItemByUSI(ContractDataset.USI);
                        var ContractID = ContractIDs.Items(i);
                        ApplyDatasetIDFilter(Dataset, ContractID, true);
                        Dataset.DisableEvents();
                        Dataset.Open();
                        var DefaultValues = GetNewDictionary();
                        var NamedArray = GetDatasetFieldsValuesNamedArray(Dataset, new Array(
                                   'OwnerID', 'ContactID', 'CampaignID', 'OpportunityID',                            
                                   /* MODULE PROJECTS */ 'ProjectID'/* ENDMODULE PROJECTS */));
                        AddNamedArrayToDictionary(NamedArray, DefaultValues);
                        var InvoiceDate = GetFieldValueFromDisabledField(Dataset, 'StartDate');
                        var ContractID = GetFieldValueFromDisabledField(Dataset, 'ID');
                        Dataset.Close();
                        Dataset.EnableEvents();
                        DefaultValues.ADD('ContractID', ContractID);
                        DefaultValues.ADD('InvoiceDate', InvoiceDate);
                        var Attributes = GetNewDictionary();
                        Attributes('IsCreatedByContractID') = ContractID;
                        CreateNewWindowEdit(Self, 'wnd_DocumentEdit', DefaultValues, Attributes);
                       
            }
}

Таким образом скрипт будет иметь вид:
o5

4. Сохранить все внесенные изменения. Перезапустить приложение Terrasoft. Проверить работу функционала.

Перед внесением изменений в конфигурацию настоятельно рекомендуем создать резервную копию БД.

Поделиться

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

Здравствуйте. Как создавать автоматически договора?. Спасибо.

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

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

Запись в разделе [Договоры]?
Для этого есть много способов. В какой момент необходимо создавать?

У меня версия Sales. Я в ней не нахожу раздел договоры.

Terrasoft Sales не содержит данный функционал.

Если функционал договоров, критичен есть два пути:
1) Расширять конфигурацию до Terrasoft CRM;
2) Дорабатывать указанный функционал на имеющейся конфигурации.

Спасибо.

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

Возникла такая проблема при попытке выбора "проект/стадия/работа" в счете, договоре, операции возникает исключение: "несоответствие типа".
Версия: 3.3.2.116 XRM Professional Services + обновления сервисов для интеграции с 1С (131010)

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

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

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

// wnd_ProjectDictionaryScript
 
function InitializeGridButtons() {
	var ProjectsfrmButtons = Projects.Window.ComponentsByName('frmButtons');
	ProjectsfrmButtons.IsVisible = Self.Attributes('ShowEditButtons'); // в этой стороке

Self.Attributes('ShowEditButtons') значение дебаггером посмотрите наверняка undefined или null попадает

Замените эту строчку на такую:

ProjectsfrmButtons.IsVisible = !!Self.Attributes('ShowEditButtons');
Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день!
Подскажите пожалуйста, как к договору добавить а виде таблицы график поставок (закупок)и соответствующий ему график платежей. И какие стандартные средства можно использовать для контроля этапов выполнения этих графиков.

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

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

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

Уточните, пожалуйста, где именно должны быть данные графики и в каком виде представлены. На данный момент графики строятся на закладке менеджера деталей или на основной закладке на основании ранее созданного запроса в разделе [Запросы].

Terrasoft Support Team

Добрый день!
Я имею в виду следующую ситуацию. Есть договор поставок товара. К договору прилагается календарный план. В котором указано на какую дату и какое количество товара должно быть отгружено покупателю. Необходимо этот календарный план "прикрепить" к договору в разделе "Договора". И по возможности обеспечить контроль за графиком поставок. То есть сообщать менеджеру о приближении срока поставки.

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

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

Terrasoft Support Team

Добрый день!

У Вас есть два варианта возможной реализации даной функциональности в Системе Terrasoft CRM версии 3.2:

Вариант №1 (с помощью стандартных средств Террасофт).
- Внесение предварительных данных в систему.
В разделе [Договора] создать договор. Планируемую оплату по договору Вы можете создать в разделе [Операции]. Укажите в поле [Договор] карточки операции ссылку на договор.
В карточке продукта в договоре (деталь [Продукты] раздел [Договора]) есть поле [Дата доставки], в котором вручную можно указать необходимую дату доставки.
В карточке операции вы можете указать планируемую дату оплаты этой операции по договору (поле [Планируемая дата оплаты]).
- Контроль за графиком
Вы сможете отслеживать просроченые операции или операции, которые надо оплатить сегодня. Для этого в разделе [Операции] создаете динамическую группу со следующим фильтром в "меню Фильтров": Планируемая дата оплаты МЕНЬШЕ ИЛИ РАВНО ТЕКУЩЕЙ ДАТЕ <и> Состояние = В планах. (т.е. планируемый платеж).
Напоминания об необходимости проконтролировать конкретную доставку по договору или по оплате - создание вручную задачи в разделе [Задачи] и установка признака в группе полей карточки задачи [Напоминания].

Примечание: самый простой вариант - добавления в электронном виде файла на деталь [Файлы] раздела [Договора] графика платежей и/или поставок. Но по нему вы не сможете осуществлять контроль за графиком поставок или платежей автоматически.

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

Приятной работы!
Старший консультант по внедрению

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

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

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

WHERE :UserSelectedDate
BETWEEN :StartDate AND :DueDate

Спасибо!

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

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

Добрый день, Виталий!
Решить задачу, используя именно пользовательские фильтры, не получится. Самый простой и очевидный способ - реализовать в окне раздела элемент управления DateTimeControl для ввода даты, и если дата указана, накладывать фильтры программно, в скрипте раздела, по аналогии с фильтрами по дате начала договора.
Если же очень нужно использовать именно фильтры в построителе, то придется переделать условие на
(StartDate < значение_даты) И (DueDate > значение_даты), то есть реализовать два условия, и требуемую дату нужно будет ввести дважды.
Желаю успехов!

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

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

С уважением, Гашникова Екатерина

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

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

Как вариант:
if (Dataset.ValIsNull(DataFieldName)) {
ShowInformationDialog('Заполните ' + DataFieldName);
return;
}

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

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