logo

[ELMA3] Отображение документов на карточке контрагента (с возможностью поиска)

Данная статья описывает возможность доработки системы ELMA таким образом, чтобы появилась возможность просмотра документов по контрагенту на карточке контрагента в отдельной вкладке, с возможностью поиска:

Рис. 1. Представление доработки

На рисунке 1 показана дополнительная вкладка на карточке Контрагента (типа юридическое лицо). На ней могут отображаться документы по данному контрагенту. Чтобы документы имели возможность отображения на новой вкладке в карточке контрагента, в рамках данной доработки, они должны иметь атрибут типа Контрагент. На вкладке имеются поля фильтра, кнопка «Искать» и список найденных документов.

Далее подробно описано, как реализовать такой функционал в системе ELMA.

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

1. Создайте в Дизайнере форм дополнительную вкладку для формы просмотра объекта Контрагент.

Рис. 2. Дизайнер форм Контрагента

Рис. 3. Панель для отображения описываемой доработки

2. Добавьте на вкладку панель без названия, в настройках который должен быть указан относительный путь до файла с разметкой, которая будет в ней отображена. Путь выглядит так “~/Modules/EleWise.ELMA.CRM.Web/Views/ContractorLegal/Docs.cshtml”.

3. Схема функционирования доработки следующая – в пустую панель на вкладке (рис.3) добавляется разметка, которая описывает форму поиска и отображения документов. Почти все поля формы поиска относительно просты в реализации. Для поля «Тип документа» требуется перебрать в цикле всех наследников определённого типа документов и сформировать из них выпадающий список. Как упоминалось выше, модификация работает лишь с одним типом документов и его наследниками, два разных типа документа в раках данной доработки обработать нельзя.

4. В файле с разметкой должен быть следующий код:

//подключаем объект контрагент для возможности 
//манипуляций с объектами данного класса
@model EleWise.ELMA.CRM.Models.IContractor
//подключаем объекты документов для возможности 
//манипуляций с документами
@using EleWise.ELMA.Documents.Models
//Определяем, какое действие будет выполнено при нажатии кнопки «искать».
//Это действие будет определено в частичном представлении вместе с полями формы поиска
<div class="filter-search-form">
<form id="FilteringGridForm" action="".onsubmit="applyFilterGrid(’Contractor_Docs’); return false;">
        @Html.Partial("docsFilter", new DocumentFilter{RegistrationCard = new RegistrationCardFilter() }, new ViewDataDictionary{TemplateInfo = new TemplateInfo{HtmlFieldPrefix = "DocumentFilter"}}) 
    </form>
</div>
//Определяем способ вывода найденных документов в виде таблицы. Из представления с формой поиска //будет передан объект с параметрами поиска. Метод, заполняющий таблицу, найдет нужные документы и //отобразит.
<div>
@Html.Action("Grid", "FilterDocumentFolder", new RouteValueDictionary { 
{ "id", null }, 
{ "area", "EleWise.ELMA.Documents.Web"},//где искать
{ "gridId", "Contractor_Docs"},// куда выводить 
{ "DocumentFilter.Types[0].TypeUid", EleWise.ELMA.Model.Services.InterfaceActivator.UID<EleWise.ELMA.Documents.Models.DokumentyPoKontragentu>().ToString() },
{ "DocumentFilter.__TypeName", "EleWise.ELMA.Documents.Models.DokumentyPoKontragentuFilter, EleWise.ELMA.DynamicModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" },
//сопоставить значение атрибута типа контрагента из //документа с контрагентом, в форме которого находимся в данный момент
{ "DocumentFilter.Kontragent.Id", Model.Id},
{ "enableChecked", false }, 
{ "mergeFilter", false } 
})
</div>

Этот фрагмент разметки описывает таблицу, в которой отобразятся найденные документы. В нём подключается другой фрагмент, описывающий форму поиска и передающий первому фрагменту параметры для поиска.

Здесь

{ "DocumentFilter.Types[0].TypeUid", EleWise.ELMA.Model.Services.InterfaceActivator.UID<EleWise.ELMA.Documents.Models.DokumentyPoKontragentu>().ToString() }, 

и здесь

{ "DocumentFilter.__TypeName", "EleWise.ELMA.Documents.Models.DokumentyPoKontragentuFilter, EleWise.ELMA.DynamicModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" },

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

Второй файл разметки, на который ссылается первый

@model EleWise.ELMA.Documents.Models.IDocumentFilter
@using EleWise.ELMA.Web.MVC.Html
@using EleWise.ELMA.Web.Mvc.Extensions;
@using EleWise.ELMA.Web.Mvc.Models.Grids;
@using Telerik.Web.Mvc.UI.DropDown;
@using System.Collections.Generic;
@using System.Linq;
@using System.Web.Mvc;
@using EleWise.ELMA.BPM.Web.Common.ExtensionPoints;
@using EleWise.ELMA.Common.ExtensionPoints;
@using EleWise.ELMA.Common.Extensions;
@using EleWise.ELMA.Common.Managers;
@using EleWise.ELMA.Common.Models.Filters;
@using EleWise.ELMA.ComponentModel;
@using EleWise.ELMA.Extensions;
@using EleWise.ELMA.Helpers;
@using EleWise.ELMA.Model.Common;
@using EleWise.ELMA.Model.Entities;
@using EleWise.ELMA.Model.Entities.EntityReferences;
@using EleWise.ELMA.Model.Filters;
@using EleWise.ELMA.Model.Metadata;
@using EleWise.ELMA.Model.Services;
@using EleWise.ELMA.Serialization;
@using EleWise.ELMA.Services;
//Описание полей формы поиска
<div class="filter-search-form">        
	<table style="width: 50%; margin: 10px;">
		<td>
			<div style="width = 370px; margin: 10px;">
				@Html.EditableProperty("Name")
			</div>
		</td>
		<td>	
			<div style="margin: 10px">
				@Html.EditableProperty("CreationDate")
			</div>
			<div style="margin: 10px">
				@Html.EditableProperty("ChangeDate")
			</div>
			<div style="width: 380px; margin: 10px;">
				@Html.EditableProperty("RegistrationCard.Flow")
			</div>
		</td>
		@{
//формирование списка типов документов доступных для выбора
            var types = new List<SelectListItem>();
			var data = (ClassMetadata)MetadataLoader.LoadMetadata(InterfaceActivator.UID<EleWise.ELMA.Documents.Models.DokumentyPoKontragentu>());
            var metadata = MetadataLoader.GetChildClasses(data);
			var def = new SelectListItem 
						{ 
							Text = " ",
							Value = " "
						};
			types.Add(def);
			var first = new SelectListItem 
						{ 
							Text = System.Web.HttpUtility.HtmlEncode(data.DisplayName ?? ""),
						Value = (data.Uid).ToString()
						};
			types.Add(first);
            foreach (var md in metadata)
            {
		var item  = new SelectListItem
		{
                            Text = System.Web.HttpUtility.HtmlEncode(md.DisplayName ?? ""), 
                            Value = (md.Uid).ToString()
                  };
             types.Add(item);
            }
		var css = new HtmlAttributes().Set(a => a.style.width = "280px"); 
//заполнение выпадающего списка названиям доступных для выбора типов документов	
        var dropDownList = Html.Telerik().DropDownList().Name(ViewData.TemplateInfo.GetFullHtmlFieldName("Types[0].TypeUid")).BindTo(types).Value("Text").Encode(false).HtmlAttributes(css);
		}
			<td><div style="margin: 5px 0px 0px 0px">Тип документа</div></td>
			<td><div style="margin: 5px 0px 0px 0px"> @dropDownList  </div></td>
		  
		
	</table>
	<input type = "submit" value = "Искать"/>
</div>

Стоит обратить внимание на строку:

var data = (ClassMetadata)MetadataLoader.LoadMetadata(InterfaceActivator.UID<EleWise.ELMA.Documents.Models.DokumentyPoKontragentu>());

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

Первый файл должен иметь имя Docs.cshtml, второй docsFilter.cshtml. Можно дать и другие имена, но это придётся учитывать при указании пути до первого файла в Дизайнере и при указании ссылки на второй файл в разметке первого.

Вот здесь в первом файле прописывается имя второго файла

<form id="FilteringGridForm" action="" onsubmit="applyFilterGrid(’Contractor_Docs’); return false;">
        @Html.Partial("docsFilter", new DocumentFilter{RegistrationCard = new RegistrationCardFilter() }, new ViewDataDictionary{TemplateInfo = new TemplateInfo{HtmlFieldPrefix = "DocumentFilter"}}) 
    </form>

К статье приложены готовые файлы, в которых нужно внести изменения в местах, помеченных в коде и описанных в статье. Можно не вносить изменений, если создавать тип документа «Документы по контрагенту» с атрибутом «Контрагент» типа Контрагент и не переименовывать файлы разметки.

Можно расширить набор полей поиска. Обратившись по аналогии к другим стандартным атрибутам документа или PKK.