Задача
В системе ведутся заказы разных типов. Требуется для каждого типа заказа сделать разные карточки, с разным набором полей.
Описание решения
- Создаём обработчик, который при добавлении нового заказа будет предлагать в отдельном окне выбрать тип создаваемого заказа.
- Создаём обработчик, который будет перед открытием карточки заказа определять тип заказа и открывать карточку, соответствующую этому типу заказа.
- Настраиваем выбор типа проекта по умолчанию в карточке проекта.
- Создаём копии каталога ./config/sections/Project и настраиваем в каждой копии свой вид карточки.
Далее представлено решение с примерами кода.
Обработчик выбора типа заказа при создании заказа
В файле /config/sections/Project/g_project.js прописываем обработчик project_addNewProject()
, который будет вызываться при создании нового заказа.
// При добавлении нового заказа показать форму выбора типа заказа
function project_addNewProject(p_grid_id, p_mode) {
if (p_mode == 0) {
new Ajax.Request(g_path+g_Project_ScriptFileName, {
parameters: {
'_func': 'Project_GetTypes'
},
//После получения списка возможных типов проектов, отобразим их
onSuccess: function(transport) {
var l_res = transport.responseText.evalJSON();
//Доступные типы заказов
var select_sql = '<select id="NewProjectTypeSelect" ' +
'class="edtText" onblur="this.className = \'edtText\';" ' +
'onfocus="this.className = \'edtText_selected\';" ' +
'style="width: 250px;">';
select_sql = select_sql + '<option value="" selected="selected"></option>';
for (var i=0; i<l_res.length; i++) {
select_sql = select_sql + '<option value="'+l_res[i].Code+'">'+l_res[i].Name+'</option>';
}
select_sql = select_sql + '</select>';
//Отобразим форму выбора типа заказа
Dialog.confirm('Укажите тип создаваемого заказа:<br>' + select_sql, {
onOk: function() { project_addNewProject(p_grid_id, 1); },
className: "iris_win",
width: 300,
height: null,
buttonClass: "button",
okLabel: "ОК",
cancelLabel: "Отмена"
});
return;
}
});
}
var select = $('NewProjectTypeSelect').up().down('select');
var value = select.options[select.selectedIndex].value;
if (value == '') {
select.className = 'edtText_empty';
return;
}
Dialog.closeInfo();
//Откроем карточку нового заказа выбранного типа
openCard({
source_type: 'grid',
source_name: 'Project',
rec_id: '',
parent_id: p_grid_id,
card_params:
'{"mode": "'+value+'", ' +
'"detail": "'+$(p_grid_id).getAttribute('detail_name')+'", ' +
'"parent_rec_id": "'+$(p_grid_id).getAttribute('detail_parent_record_id')+'"}'
});
}
В конец функции project_grid_init()
пропишем вызов этого обработчика.
var elem = getGridFooterTable(p_grid_id);
elem.down('input[value="Добавить"]').hide().insert({
after: '<input ' +
'class="button" ' +
'type="button" ' +
'title="Добавить новую запись" ' +
'value="Добавить" ' +
'onclick="project_addNewProject(\''+p_grid_id+'\', 0)" ' +
'style="width: 70px;"/>'
});
В результате при добавлении нового заказа будет предварительно отображаться окно с выбором типа заказа.
Обработчик при открытии карточки заказа
Создаём файл ./config/sections/Project/s_project.php, в котором прописываем обработчик при открытии существующего заказа.
<?php
//********************************************************************
// Серверная логика карточки заказа
//********************************************************************
include_once GetPath().'/config/common/Lib/lib.php';
//По коду типа заказа возвращает имя секции заказа
function GetProjectSection($project_type) {
return 'Project'.($project_type ? '-' : '').$project_type;
}
//Перед открытием карточки в завистмости от типа проекта подставим нужную карточку
function Project_onPrepare($params) {
if ($params['card_params'] == 'undefined')
$params['card_params'] = null;
$card_params = json_decode($params['card_params'], true);
if ($card_params != null) {
// если передан параметр, указывающий какую карточку открыть, то откроем нужную карточку
if ($card_params['mode'] != null) {
$params['parent_type'] = 'grid';
$params['source_name'] = GetProjectSection($card_params['mode']);
$params['parent_page'] = $card_params['mode'].'$params-delimenter$'.'{"detail": "'.$card_params['detail'].'", "parent_rec_id": "'.$card_params['parent_rec_id'].'"}';
$params['detail_name'] = '';
$params['detail_column_value'] = '';
//$params['card_params'] = '{"detail": "'+$card_params['detail']+'"}'; - card_params передаются через parent_page
return $params;
}
//
if ($card_params['detail'] != null) {
// если карточка открыта из вкладки, то заполним ее поля компания и контакт
if ($card_params['detail'] == 'd_Contact_Project') {
$contact_name = GetFieldValueByFieldValue('contact', 'id', $card_params['parent_rec_id'], 'name');
$values = FieldValueFormat('ContactID', $card_params['parent_rec_id'], $contact_name, $values);
$account_id = GetFieldValueByFieldValue('contact', 'id', $card_params['parent_rec_id'], 'accountid');
}
if ($card_params['detail'] == 'd_Account_Project') {
$account_id = $card_params['parent_rec_id'];
}
if ($account_id != '') {
$account_name = GetFieldValueByFieldValue('account', 'id', $account_id, 'name');
$values = FieldValueFormat('AccountID', $account_id, $account_name, $values);
}
return $values;
}
}
// если режим update, то покажем нужную карточку в зависимости от кода типа заказа
if ($params['mode'] == 'update') {
$con = db_connect();
$cmd = $con->prepare("select T1.code as pt_code ".
"from iris_project T0 left join iris_projecttype T1 on T0.projecttypeid = T1.id ".
"where T0.id=:id");
$cmd->execute(array(":id" => $params['rec_id']));
$record = current($cmd->fetchAll(PDO::FETCH_ASSOC));
$params['parent_type'] = 'grid';
$params['source_name'] = GetProjectSection($record['pt_code']);
$params['parent_page'] = $record['pt_code'];
$params['parent_type'] = 'grid';
$params['detail_name'] = '';
$params['detail_column_value'] = '';
}
return $params;
}
Прописываем вызов этого обработчика в structure.xml в теге EDITCARD.
php_source_file="config/sections/Project/s_project.php"
php_on_prepare="Project_onPrepare"
Выбор типа проекта по умолчанию
Чтобы в карточке проекта автоматически устанавливался выбранный тип проекта, необходимо выполнить следующие изменения.
В файле c_project.php комментируем следующую строку в функции Project_GetDefaultValues()
.
// Значения справочников
$l_result = GetDictionaryValues(
[
['Dict' => 'ProjectState', 'Code' => 'Plan'],
['Dict' => 'ProjectStage', 'Code' => 'Sale_Info'],
['Dict' => 'Currency', 'Code' => 'RUB'],
],
$con
);
В файле c_project.js комментируем следующую строку в функции c_Project_GetDefaultValues_end()
.
try {
//p_form.ProjectTypeID.removeAttribute('disabled');
}
catch (e) {};
В этот же файл добавляем функцию получения кода типа проекта.
//Получить код типа проекта по названию раздела
function c_project_getProjectType(p_form)
{
var projectSection = p_form._source_name.value;
var projectTypeCode = 'GasPhysic'; //Тип по умолчанию
if (projectSection != 'Project') {
projectTypeCode = projectSection.split('-')[1];
}
return projectTypeCode;
}
Также в этом же файле меняем строку
c_Common_SetDefaultValues(l_form, c_Project_ScriptFileName,
function() { c_Project_GetDefaultValues_end(l_form); });
на следующие строки, где заполняется тип проекта в зависимости от открываемой карточки проекта.
var projectTypeCode = c_project_getProjectType(l_form);
try {
SetSelectValueByAttribute(l_form.ProjectTypeID, 'code', projectTypeCode);
}
catch (e) {};
c_Common_SetDefaultValues(l_form, c_Project_ScriptFileName,
function() { c_Project_GetDefaultValues_end(l_form); },
[{'Name': 'sectioncode', 'Value': projectTypeCode}]);
Также в файле structure.xml необходимо добавить атрибут db_field_ext для поля ProjectTypeID.
<FIELD elem_type="select" caption="Тип"
db_field="ProjectTypeID" db_field_ext="code" mandatory="no" datatype="id"
row_type="fk_column" row_type_parent_table="iris_ProjectType"
row_type_parent_display_column="Name" />
Создание копий каталога раздела
Создайте копии каталога ./config/sections/Project. Назовите их так: Project-<Код типа заказа>. Удалите из копий каталога все файлы кроме structure.xml.
В примере, на основе которого подготовлен данный материал, коды типов заказа были такие: Electric, GasLegal, GasLimit, GasPhysic, Ground. Поэтому структура каталогов в нашем случае такова.
Project
c_project.js
c_project.php
dc_advantage.js
dc_product.js
dc_product.php
g_project.js
g_project.php
s_project.php
structure.xml
Project-Electric
structure.xml
Project-GasLegal
structure.xml
Project-GasLimit
structure.xml
Project-GasPhysic
structure.xml
Project-Ground
structure.xml
Сделайте в файлах structure.xml изменения, чтобы в карточке каждого типа заказа отображались нужные поля.