Примеры кода

Рассмотрим подробно, из чего состоит и как работает «Объект» «Контакты с контрагентом» (Documents.relationship) в Системе.

Данные объект располагается в «Конфигураторе» по адресу: /configurator/documents.relationship/

k1

Т. к. у нас это тип Объекта — «Документ», то автоматически создались поля: visible, date, number.

У этого объекта 4 «Формы»:

1. «Форма редактирования». Адрес формы: Companies/relationship. Используется для редактирования «Объекта». «Companies» означает, что «Объект» редактируется в «Контрагенте»

2. «Форма списка» (1). Адрес формы: Companies/relationship. Используется для вывода списка «Объектов» («Контактов»), принадлежащих определенному объекту «Контрагент» (т. е. все «Контакты» по определенному «Контрагенту»). Ссылка доступна из меню «Список контрагента» (тип ссылки в меню: «company»)

3. «Форма списка» (2). Адрес формы: Relationship. Используется для вывода всех «Объектов» («Контактов») по всем «Контрагентам». Ссылка доступна из меню «Общего списка» (тип ссылки в меню: left»).

4. «Печатная форма». Адрес формы: main. Используется для вывода «Объекта» на печать. Ссылка на форму обычно располагается в «Форме редактирования» «Объекта» и называется «Печать».

Рассмотрим каждую форму детально.

Форма редактирования

k2

Сценарий (PHP-код):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?php
 
	namespace Applications\Companies\Relationship; 
 
	class Edit extends \Kernel\Actions\Forms\Edit {
 
		use \Applications\Companies\LeftMenu; // Слева выводим меню "Контрагента"
 
		protected function onPlay() { // Функция, срабатывающая при открытии формы
 
			// Ниже идет код, который срабатывает, когда содается новый "Контакт"
			if (!$this->structure->id) { // Если "Объект" еще не создан, то срабатывает следующий код
				$this->structure->priority(2)->getField("priority")->markAsSaved(); // поле "Приоритет" задаем значение по-молчанию = 2 (Т.е. "Приоритет" = "Средний"), и помечаем его, как markAsSaved()
				$this->structure->owner($this->parents[0]->getKey())->getField("owner")->markAsSaved(); // Задаем в поле owner родителя, т.к. id "Контрагента", в котором будет находиться наш будущий "Контакт" и тоже помечаем его markAsSaved()
 
				$this->structure->responsible($this->User->getEmployee()->id)->getField("responsible")->markAsSaved(); // В поле "Ответственный" вставляем ID текущего пользователя, т. е. того человека, который создает сейчас данный "Контакт"
 
				// Ниже идет код, который срабатывает, когда в объекте "Задача" нажали кнопку "Создать контакт" (на основе "Задачи")
				$task_id = $this->Http->Get->request("task", "Numeric"); // Считываем переменную "task" методом GET и приводим ее к числу. 
				if($task_id>0) // Если число положительное, то создается новый Контакт.
				{
					$task_obj = $this->Data->Documents->Tasks->filter("id=".$task_id); // По ID задачи находим "Объект" "Задача"
					$this->structure->contact($task_obj->contact->id)->getField("contact")->markAsSaved(); // В новом "Контакте" переносим "Контактное лицо" из "Задачи"
					$this->structure->phone($task_obj->phone)->getField("phone")->markAsSaved(); //Переносим телефон 
					$this->structure->email($task_obj->email)->getField("email")->markAsSaved(); //Переносим E-mail 
				}
 
				$this->structure->types(1)->getField("types")->markAsSaved(); // Задаем тип "Контакта" (например, "Звонок")
 
				$this->page->block("BASE.NOEMAIL"); // Отображаем блок из шаблона "BASE.NOEMAIL", т. е. "Контакт" когда создается только, из него нельзя отправить электронное письмо
			}
			else
			{
				// Если объект "Контакт" уже существует у нас, то...
				$this->page->block("BASE.TASK"); // Выводим блок шаблона BASE.TASK, т. е. кнопки "Создать задачу"
				$this->page->set(["TITLE"=>"Контакт от ".$this->structure->getField("date")->toFormat("d.m.Y")]); // Задаем TITLE страницы с указанием даты, приводя ее к формату: "d.m.Y"
				$this->page->set(["BASE.company" =>$this->structure->owner->id]); // Передаем на форму переменную = owner->id (id контрагента), необходима при смене Контрагента
				$this->page->block("BASE.EMAIL"); // Выводим блок шаблона BASE.EMAIL, позволяющий отправить электронное письмо из него
				// передаем переменные в блок E-MAIL
				this->page->set(["BASE.EMAIL.mail"=>$this->structure->email, 
				"BASE.EMAIL.mail_name"=>$this->structure->contact->name,
				"BASE.EMAIL.theme"=>$this->structure->subject,
				"BASE.EMAIL.from"=>$this->structure->responsible->name,
				"BASE.EMAIL.message"=>rawurlencode($this->User->getEmployee()->signature)
				]);
			}
 
 
		}
 
		protected function onChange() { }
 
		protected function onSave() { }
		protected function onSaved(){
		// данный код выполняется после уже сохранения данного Объекта
			$task_id = $this->Http->Get->request("task", "Numeric");
			if($task_id>0)
			{
				$task_obj = $this->Data->Documents->Tasks->filter("id=".$task_id);
				$this->structure->deal($task_obj->deal)->sync();
			}
		}
	}
 
?>

Шаблон:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <fields> // подключаем шаблон для вывода "Полей"
	{BASE append}
	#include <tabs> // подключаем шаблон для вывода "Закладок"
		<form class="form-horizontal" method="post"> 
			<fieldset class="row">
				[[field | type: input | object: data | name: date  | params:  disabled="true" style="text-align: center"]] // Вывод поле "Дата" типа "Дата"
				[[field | type: select | object: data | name: types |field:name]] // Вывод выпадающего списка "Типы контактов". То что выпадающий список указывает type
				[[field | type: subSelect | object: data | name: contact | field:name | master: owner | loadData: position,email,phone,fax ]] // Вывод "Контактного лица" "Контрагента", при этом будут автоматически заполняться поле Должность, Е-майл, Телефон, Факс на форме
				[[field | type: select | object: data | name: direction |field:name]] // Вывод выпадающего поля "Направление"
				[[field | type: formSelect | object: data | name: owner | field: name | form: /companies/select/ | value: $data.owner.name.value]]// Выбор "Контрагента", открывается модальное окно выбора Контрагента при нажатии на "лупу"
				[[field | type: select | object: data | name: responsible |field:name]] // Выпадающий список "Ответственного сотрудника"
				[[field | type: input | object: data | name: position | accept: contact.position]]// простое поле "Должность" с пометкой, что оно зависимое: accept: contact.position
				[[field | type: input | object: data | name: email | accept: contact.email]]
				[[field | type: input | object: data | name: phone | accept: contact.phone]]
				[[field | type: input | object: data | name: fax | accept: contact.fax]]
				[[field | type: select | object: data | name: duration | field:name]]    
				[[field | type: select | object: data | name: priority | field:name]]   
				<div style='width:400px'>
					[[field | type: input | object: data | name: subject | params:style="width:580px;" | size:  span12 | label: style='font-weight:bold']] // Вывод поле "Тема" с доп параметрами, размером span12 и доп. параметры на label (название поле) - жирным текстом выделить
				</div>  
				<div style='width:400px'>
					[[field | type: textarea | object: data | name: result | types:  span7 |params:style="width:580px;height:250px;font-size:14pt"]] // поле "описание" (textarea)
				</div>
			</fieldset>
			<div class="form-actions bbtns">
				[[save]] // Вывод кнопки "Сохранить" (submit)
				{EMAIL} // начало блока EMAIL
				<button class='btn' type='button' onclick="send_email('$mail','$mail_name','$theme','$from','$message');" ><i class='icon-envelope'></i>  EMAIL</button>  
				{/EMAIL} // окончание блока EMAIL
				{NOEMAIL}// начало блока NOEMAIL
				<button class='btn' disabled='disabled'><i class='icon-envelope'></i>  EMAIL</button> 
				{/NOEMAIL}// окончание блока NOEMAIL
				{TASK} // начало блока TASK
				<a href="/tasks/add/?relationship=$data.id.value$" class="btn"><span style='color:black'><i class="icon-plus "></i> #L:Task</span> </a> 
				{/TASK}// окончание блока TASK
 
				##<a target="_BLANK" href="/companies/$data.owner.id.value$/relationship/$data.id.value$/main/" class="btn"> #L:Print</a> // спец символ - ## говорит, что данные код не будет выведен на форму
			</div>
		</form>
 
 
		// JS скрипт
		<script>
			// функция при отправки письма, выведет модальное окно отправки письма
			function send_email(mail, mail_name, theme, from, message){
				showFormModal("/email/form/select/", {
					"mailto": mail,
					"mailtoName": mail_name,
					"theme": theme,
					"from": from,
					"message":message
				});
			}
			//После отправки письма сообщение выводится
			function sent() {
				hideModal();
				showAlert("Письмо отправлено");
			}
			objEdit="documents.relationship";
 
			// проверка при нажатии на кнопку "Сохранить", чтобы поле "Тема" была заполнена 
			$("form").submit(function(e){
				if($("#f_subject").val().trim().length==0){
					e.preventDefault();
					showAlert("Заполните поле <b>'$data.subject.name'</b>", "error");
					$("#f_subject").css("border","1px solid red");
				}
			});
 
 
			// выбор картинки в TEXTAREA
			function elFinderBrowser (field_name, url, type, win) {
				tinymce.activeEditor.windowManager.open({
					file: '/system_images/select/',
					width: 900,  
					height: 450,
					resizable: 'yes'
					}, {
					setUrl: function (url) {
 
						win.document.getElementById(field_name).value = url;
					}
				});
				return false;
			}
 
		</script>
		{/BASE}
		{JS append}
		// подключение стандартных JS библиотек к шаблону
		[[js | name: lib/tiny_mce/tiny_mce]]
		[[js | name: interface/ajax_form]]
		[[js | name: interface/modal_form]]
 
		[[js | name: lib/tablescroll]]
		[[js | name: lib/bootstrap-modal]]
		[[js | name: companies/relationship/edit]]
		[[js | name: companies/select]]
	{/JS}

Интерфейс (JS-код):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// функция, которая срабатывает после выбора контрагента, вызывается она из формы выбора Контрагента
function selectCompany(id, name) {
  $("#f_owner").val(id).change();
  $("#f_form_owner input").val(name);
  hideModal();
}
// tinyMCE
tinyMCE.init({
  setup : function(ed)
              {
                  ed.onInit.add(function(ed)
                      {
                          ed.getDoc().body.style.fontSize = '14px';
                      });
              },
        theme : "advanced",
        mode : "textareas",
      	plugins : 			"table, advhr,preview, media,inlinepopups, searchreplace,print, contextmenu,paste, noneditable,visualchars, ibrowser",
 
 
		theme_advanced_buttons1 : "bold,italic,underline,strikethrough, | ,justifyleft,justifycenter,justifyright,justifyfull, | ,styleselect,formatselect,fontselect,fontsizeselect , bullist,numlist",
      file_browser_callback : 'elFinderBrowser',
		theme_advanced_buttons2 : "link,unlink,anchor,image,cleanup,|,forecolor,backcolor, |,hr,advhr,removeformat,visualaid, |,sub,sup,|,charmap,media, |,print,visualchars,  preview,code",		
      	relative_urls : false,
    //style_formats : [{fontSize : '18px'}],
 
	});

Форма списка (1)

k4

Сценарий (PHP-код):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
 
	namespace Applications\Companies\Relationship;
 
	class Enlist extends \Kernel\Actions\Forms\Enlist {
		use \Applications\Companies\LeftMenu; // Подключаем левое меню
		protected function onPlay()
		{ // передаем данные таблице в шаблоне с именем: form
		$this->printDataTable("form",
			[ // массив полей
			"company" => ["id" => "owner.id", "name" => "owner.name"], // "Название компании", поле (колонка) типа LINK (ссылка). Обязательно передается параметр ID, и ИМЯ. В данном случае, будет ссылка на "Контрагент" из "Контакта":  /companies/3
			"date" => ["id","name"=>"date", "owner"=>"owner.id"], //Дата, поле типа LINK (ссылка). Будет ссылка в итоге на этот сам объект: /companies/3/relationship/1/
			"position", //должность
			"contact"=>["owner" => "owner.id", "id"=>"contact.id", "name" => "contact.name"], //Контактное лицо, тоже ссылка: /companies/3/contacts/1/
			"phone", // телефон
			"subject",// тема контакта
			"types"=>"types.name", // Поле указатель, выведет не ID "Типа контакта", а выведет его "Имя" (Звонок, Встреча...), это дает нам конструкция: "types"=>"types.name"
			"email", // e-mail
			"responsible"=>"responsible.name", // Выведет ФИО ответственного в таблице
		"fax",// факс
		"edit" => ["id", "owner" => "owner.id" ] // Выведет иконку "редактировать" (объект)
		],
		["date", DESC] //отсортирует вывод таблицы по дате, по убыванию
		);
		}
	}
 
 
 
?>

Шаблон:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <table> // подключаем шаблон таблиц
	#include <fields>// подключаем шаблон полей
		{BASE append} // начало базового шаблона
		<div class="smallHeader">Поиск контакта</div>
		<form class="form-horizontal" method="get">
			<fieldset class="row">
				[[diapason | type: date | name: date | object: data |  prefix: filter ]] //фильтр по дате, будут созданы сразу ДВА поля: С___ ПО___
				[[field | type: input | name: subject | object: data  | value: $filter_subject | prefix: filter ]] // фильтр по теме
				[[field | type: input | name: result | object: data  | value: $filter_result | prefix: filter]] // фильтр по результату
				[[field | type: select |field:name| name: types | object: data | prefix: filter | addempty: true | value: $filter_types ]]   // фильтр "Типу контакта", также есть флаг  addempty: true, это необходимо добавлять, если у поля стоит флаг в Конфигураторе "Обязательное для заполнения", иначе там всегда будет первое значение стоять из Перечисления
				[[field | type: select |field:name| name: direction | object: data | prefix: filter | addempty: true | value: $filter_direction ]]
				[[field | type: select | name: priority |field:name| object: data| prefix: filter | addempty: true  | value: $filter_priority]]
				[[field | type: select | name: responsible | object: data | prefix: filter |field:name| addempty: true | value: $filter_responsible]]   
				<div class="control-group span5">
					<label class="control-label" for=""></label>
				</div>
				<div class="rightButtons">
					<button type="submit" class="btn btn-vk rBtn"><i class="icon-search icon-white"></i> #L:Find</button> // Кнопка "Поиск"
					<a href="/companies/$parent0/relationship/" class="btn">#L:Reset</a>// Кнопка "Сброс"
				</div>
			</fieldset>
		</form> 
		<a href="add/" class="btn btn-vk addf addBtn"><i class="icon-plus icon-white"></i> #L:Add</a>// Кнопка "Добавить"
		<div class="tableHolder">
			[[table | name: form]] // Задаем вывод таблицы с названием: form
			// задаем вывод колонок у этой таблицы
			[[column | table: form | name: date | width: 10% | header: $data.date.name | type:link | path:/companies/$owner/relationship | align: center]] // колонка типа LINK, выведет ссылку на сам объект на поле "Дата". Ширина 10%, header: $data.date.name (Заголовок столбца = Названию поля в Конфигураторе
 
			[[column | table: form | name: types | width: 10% | header: $data.types.name | align: center]]
			[[column | table: form | name: contact | width: 20% | header: $data.contact.name  | type: link | path: /companies/$owner/contacts | align: center]]
			[[column | table: form | name: subject | width: 80% | header: $data.subject.name]]
			[[column | table: form | name: responsible | width: 30% | header: $data.responsible.name | align:center]]
            [[edit | table: form | path: /companies/$owner/relationship]] // Кнопка редактировать со ссылкой на объект (см. PHP сценарий)
			[[delete | table: form]] // Задаем кнопку "Удалить" в таблице
			[[restore | table: form]// Задаем кнопку "Восстановить" в таблице
			[[wipe | table: form]]// Задаем кнопку "Стереть" в таблице
		</div>
		#include <pagination>// Включаем пагинацию (переходы по страницам внизу)
		{/BASE} // окончание базового шаблона

Форма списка (2)

k4

Описание соответствует полностью «Форме списка (1)». Отличие между формой в «Общем списке» и в «Списке в контрагенте» в том, что в «Общем списке» добавляется поле «Контрагент» (LINK).

Печатная форма

k5

Сценарий (PHP-код):

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
 
	namespace Applications\Companies\Relationship\Prints;
 
	class Main extends \Kernel\Actions\Forms\Prints {
 
		protected function onPlay()
		{
			$this->page->set(["BASE.result"=>html_entity_decode($this->structure->result)]); // В базовый шаблон в поле result передаем преобразованное значение поле Результат. Остальные поля идут без преобразования. См. ниже.
		}
	}
 
?>

Шаблон:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
{BASE append} // начало базового шаблона
<table width="644" border="0" cellpadding="0" cellspacing="0" bordercolor="#000000">
	<tr>
		<td height="3" colspan="5" valign="top" class="pt10"><hr size="1" /></td>
	</tr>
	<tr>
		<td width="148" height="36" valign="top" class="pt10"><strong>Тип контакта:</strong></td>
		<td width="133" height="36" valign="top" class="pt10">$data.types.name.value$</td> // вывод "Типа контакта". Выведется именно "Название", а не просто ID, т.к. едет ссылка на другой "Объект" и берется его "Имя" (name).
		<td width="133" valign="top" class="pt10"><div align="right"><strong>Направление:&nbsp;</strong></div></td>
		<td width="100" valign="top" class="pt10">$data.direction.name.value$</td>// Аналогично, выведется "Направление контакта" (входящий/исходящий)
		<td width="130" valign="top" class="pt10"><strong>Дата:</strong> $data.date.value$// вывод просто поле "Дата"
		</tr>
        <tr>
			<td height="36" valign="top" class="pt10"><strong>Контактное лицо:</strong></td>
			<td height="36" valign="top" class="pt10">$data.contact.name.value$</td> // Выведется "ФИО" "Контактного лица"
			<td height="36" valign="top" class="pt10">&nbsp;</td>
			<td height="36" valign="top" class="pt10"><strong>Длительность:</strong></td>
			<td height="36" valign="top" class="pt10">$data.duration.name.value$</td>// Выведется "Должность" "Контактного лица"
		</tr>
        <tr>
			<td height="36" valign="top" class="pt10"><strong>Должность:</strong></td>
			<td height="36" colspan="2" valign="top" class="pt10">$data.position.value$</td>
			<td height="36" valign="top" class="pt10"><strong>Телефон:</strong></td>
			<td height="36" valign="top" class="pt10">$data.phone.value$</td> // Выведется просто поле "Телефон" из карточки "Контакта"
		</tr>
        <tr>
			<td height="36" valign="top" class="pt10"><strong>E-mail:</strong></td>
			<td height="36" colspan="2" valign="top" class="pt10">$data.email.value$</td>
			<td height="36" valign="top" class="pt10"><strong>Факс:</strong></td>
			<td height="36" valign="top" class="pt10">$data.fax.value$</td>
		</tr>
        <tr>
			<td height="36" valign="top" class="pt10"><strong>Ответственный:</strong></td>
			<td height="36" colspan="2" valign="top" class="pt10">$data.responsible.name.value$</td>
			<td height="36" valign="top" class="pt10"><strong>Приоритет:</strong></td>
			<td height="36" valign="top" class="pt10">$data.priority.name.value$</td>
		</tr>
        <tr>
			<td height="9" colspan="5" valign="top" class="pt10"><hr size="1" /></td>
		</tr>
        <tr>
			<td height="36" valign="top" class="style5">Тема контакта</td>
			<td height="36" colspan="4" valign="top" class="pt10"><table width="100%" border="0" cellpadding="0" cellspacing="0" style="border:#999999 solid 1px; padding:2px; font-size:10pt">
				<tr>
					<td>$data.subject.value$<br /></td>
				</tr>
			</table>
			<br /></td>
		</tr>
        <tr>
			<td height="36" valign="top" class="pt10"><strong>Результат контакта:</strong></td>
			<td height="36" colspan="4" valign="top" class="pt10"><table width="100%" border="0" cellpadding="0" cellspacing="0" style="border:#999999 solid 1px; padding:2px; font-size:10pt; background:#CCCCCC">
				<tr>
					<td bgcolor="#FFFFFF">$result</td>
				</tr>
			</table>
			<br /></td>
		</tr>
        <tr>
			<td height="36" valign="top" class="pt10"><strong>Примечание:</strong></td>
			<td height="36" colspan="4" valign="top" class="pt10"><table width="100%" border="0" cellpadding="0" cellspacing="0" style="border:#999999 solid 1px; padding:2px; font-size:10pt; background:#CCCCCC">
				<tr>
					<td bgcolor="#FFFFFF">&nbsp;<br /></td>
				</tr>
			</table></td>
		</tr>
	</table>
{/BASE} // окончание базового шаблона
Последние правки: 08.08.2016 17:13:39