Как сделать разные карточки для разных типов заказов

Задача

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

Описание решения

  1. Создаём обработчик, который при добавлении нового заказа будет предлагать в отдельном окне выбрать тип создаваемого заказа.
  2. Создаём обработчик, который будет перед открытием карточки заказа определять тип заказа и открывать карточку, соответствующую этому типу заказа.
  3. Настраиваем выбор типа проекта по умолчанию в карточке проекта.
  4. Создаём копии каталога ./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(
	array (
//		array ('Dict' => 'ProjectType', 'Code' => 'Sale'),
		array ('Dict' => 'ProjectState', 'Code' => 'Plan'),
		array ('Dict' => 'ProjectStage', 'Code' => 'Sale_Info'),
		array ('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 изменения, чтобы в карточке каждого типа заказа отображались нужные поля.

Навигация