Довольно подробно механизм регистрации описан в статье про добавление нового элемента номера в журнале регистрации. Продолжу эту тему и подробнее рассмотрю добавление нового разреза нумерации.
Цель: добавить новый разрез нумерации по категориям для договоров и доп. соглашений.
Коробочный механизм предоставляет всего три разреза, в рамках которых нумерация ведется отдельно, а именно: Ведущий документ/Подразделение/Наша организация. Например, нумерация дополнительных соглашений ведется в рамках договоров, для которых они оформлены. Постараюсь наглядно объяснить, каким образом можно обойти данное ограничение.
В общем и целом задачу можно разбить на 3 этапа:
Прежде чем перейти к основным доработкам, перекрываем справочник «Журнал регистрации» и добавляем новый элемент NumberingSection (разрез нумерации)
После чего, добавляем фильтрацию по документопотоку для свойства NumberingSection (разрез нумерации), так как в нашем случае необходимо чтобы данный разрез был доступен только для договорных документов.
public override IEnumerable<Enumeration> NumberingSectionFiltering(IEnumerable<Enumeration> query)
{
if (_obj.DocumentFlow != DocumentFlow.Contracts)
return query.Where(s => s != finex.MotivContracts.DocumentRegister.NumberingSection.Category);
return base.NumberingSectionFiltering(query);
}
Для хранения очередного номера при регистрации или нумерации в базе данных используется таблица «Sungero_Docregister_Currentnumbers». Данная таблица, кроме очередного номера документа хранит информацию о ID сущностей, используемых при определении разреза нумерации (в коробочной версии доступно три варианта: наши организации, подразделения, ведущий документ). Следовательно, если мы хотим добавить свой разрез, нам необходимо провести следующие манипуляции:
Для добавления нового столбца в таблице «Sungero_Docregister_Currentnumbers», где будет хранится ID категории создаем следующий SQL запрос:
ALTER TABLE {0} ADD COLUMN IF NOT EXISTS {1} {2} NOT NULL DEFAULT {3};
Вызываем этот запрос в событии инициализации.
/// <summary>
/// Добавление колонок в таблицы
/// </summary>
public static void AlterTables()
{
var query = string.Format(Queries.Module.AlterTables,
Constants.Module.TablesNames.docRegisterTableName,
"category",
"integer",
"(0)");
InitializationLogger.Debug(query);
Sungero.Docflow.PublicFunctions.Module.ExecuteSQLCommand(query);
}
Переписываем SQL-запросы GetCurrentNumber, SetCurrentNumber в перекрытом журнале регистрации на получение и установку индекса, добавляя новый параметр Category:
-- GetCurrentNymber
select
CurrentNumber
from
Sungero_DocRegister_CurrentNumbers
where
DocRegisterId = {0}
and Month = {1}
and Year = {2}
and LeadDocument = {3}
and Quarter = {4}
and Department = {5}
and BUnit = {6}
and Category = {7}
-- SetCurrentNumber
if exists (select
*
from
Sungero_DocRegister_CurrentNumbers
where
DocRegisterId = {0}
and Month = {2}
and Year = {3}
and LeadDocument = {4}
and Quarter = {5}
and Department = {6}
and BUnit = {7}
and Category = {8})
update
Sungero_DocRegister_CurrentNumbers
set
CurrentNumber = {1}
where
DocRegisterId = {0}
and Month = {2}
and Year = {3}
and LeadDocument = {4}
and Quarter = {5}
and Department = {6}
and BUnit = {7}
and Category = {8}
else
insert into
Sungero_DocRegister_CurrentNumbers (DocRegisterId, CurrentNumber, Month, Year, LeadDocument, Quarter, Department, BUnit, Category)
values
({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7},{8})
Присвоение нового номера производится в функции GetNextRegistrationNumber(), вызываемой в событии до сохранения (в транзакции) ТД OfficialDocument с использованием механизма хранимых процедур (далее ХП). Таким образом необходимо переопределить их с параметром «Category». ХП описаны в SQL запросах модуля Docflow, нас интересует «Sungero_DocRegister_GetNextNumber».
-- Удалить процедуру получения очередных номеров
DROP FUNCTION IF EXISTS Sungero_DocRegister_GetNextNumber();
-- Создать функцию для получения очередных номеров
CREATE OR REPLACE FUNCTION Sungero_DocRegister_GetNextNumber(
basevalue int,
docregid int,
newmonth int,
newyear int,
leaddoc int,
newquarter int,
newdep int,
newbusinessunit int,
newcategory int)
RETURNS int AS $$
BEGIN
IF NOT EXISTS(SELECT *
FROM sungero_docregister_currentnumbers
WHERE docregisterid = docregid
AND month = newmonth
AND year = newyear
AND leaddocument = leaddoc
AND quarter = newquarter
AND department = newdep
AND bunit = newbusinessunit
AND category = newcategory)
THEN
INSERT INTO sungero_docregister_currentnumbers(docregisterid, currentnumber, month, year, leaddocument, quarter, department, bunit, category)
VALUES (docregid, basevalue, newmonth, newyear, leaddoc, newquarter, newdep, newbusinessunit, newcategory);
RETURN basevalue;
ELSE
UPDATE sungero_docregister_currentnumbers
SET currentnumber = currentnumber + 1
WHERE docregisterid = docregid
AND month = newmonth
AND year = newyear
AND leaddocument = leaddoc
AND quarter = newquarter
AND department = newdep
AND bunit = newbusinessunit
AND category = newcategory;
RETURN (SELECT currentnumber
FROM sungero_docregister_currentnumbers
WHERE docregisterid = docregid
AND month = newmonth
AND year = newyear
AND leaddocument = leaddoc
AND quarter = newquarter
AND department = newdep
AND bunit = newbusinessunit
AND category = newcategory);
END IF;
END;
$$
LANGUAGE plpgsql;
В довершении к вышесказанному в событии инициализации удаляем прежний запрос и создаем свой.
//Изменение хранимых процедур таблицы очередных номеров журналов регистрации
public static void ChangeDocumentRegisterNumberTable()
{
var dropGetNextNumberProcedure = Queries.Module.DropProcedureSungeroDocRegisterGetNextNumber;
var createGetNextNumberProcedure = Queries.Module.CreateProcedureSungeroDocRegisterGetNextNumber;
Sungero.Docflow.PublicFunctions.Module.ExecuteSQLCommand(dropGetNextNumberProcedure);
Sungero.Docflow.PublicFunctions.Module.ExecuteSQLCommand(createGetNextNumberProcedure);
}
Первый этап завершен, переходим к самому нудному. При получении или изменении очередного номера вызываются серверные функции журнала регистрации:
Для понимания взаимодействия этих функций ниже представлена схема их вызова в разных событиях.
Как видно из схемы, получение номера происходит:
Таким образом нам нужно создать перегрузки для серверных функций журнала регистрации, с добавлением обработки категории договоров и добавить передачу нового параметра во всех местах вызова этих функций.
Код перегруженных серверных функций журнала регистрации (т. к. весомая часть кода копируется из коробки, для наглядности участки кода с обработкой категории вынесены в регионы) приведен ниже:
/// <summary>
/// Получить следующий регистрационный номер.
/// </summary>
/// <param name="date">Дата регистрации.</param>
/// <param name="leadDocumentId">ID ведущего документа.</param>
/// <param name="document">Документ.</param>
/// <param name="leadingDocumentNumber">Номер ведущего документа.</param>
/// <param name="departmentId">ИД подразделения.</param>
/// <param name="businessUnitId">ID НОР.</param>
/// <param name="categoryId">ID категории.</param>
/// <param name="caseFileIndex">Индекс дела.</param>
/// <param name="docKindCode">Код вида документа.</param>
/// <param name="indexLeadingSymbol">Ведущий символ индекса.</param>
/// <returns>Регистрационный номер.</returns>
[Public, Remote(IsPure = true)]
public virtual string GetNextNumber(DateTime date, int leadDocumentId, IOfficialDocument document, string leadingDocumentNumber,
int departmentId, int businessUnitId, int categoryId, string caseFileIndex, string docKindCode, string indexLeadingSymbol)
{
#region CUSTOM
var index = this.GetNextIndex(date, leadDocumentId, departmentId, businessUnitId, categoryId, document).ToString();
#endregion
var departmentCode = string.Empty;
if (departmentId != 0)
{
var department = Sungero.Company.Departments.Get(departmentId);
if (department != null)
departmentCode = department.Code ?? string.Empty;
}
var businessUnitCode = string.Empty;
if (businessUnitId != 0)
{
var businessUnit = Sungero.Company.BusinessUnits.Get(businessUnitId);
if (businessUnit != null)
businessUnitCode = businessUnit.Code ?? string.Empty;
}
var counterpartyCode = Sungero.Docflow.PublicFunctions.OfficialDocument.GetCounterpartyCode(document);
var number = Sungero.Docflow.PublicFunctions.DocumentRegister.GenerateRegistrationNumber(_obj, date, index, leadingDocumentNumber, departmentCode,
businessUnitCode, caseFileIndex, docKindCode, counterpartyCode,
indexLeadingSymbol);
var contract = Contracts.As(document);
if (contract == null)
return number;
var replaceCode = contract.DocumentGroup != null
? contract.DocumentGroup.Codefinex
: "";
var replaceCSCode = contract.Subjectfinex != null
? contract.Subjectfinex.Code
: replaceCode;
string codeFinex = Constants.Docflow.DocumentRegister.CodeFinex;
string csCodeFinex = Constants.Docflow.DocumentRegister.CSCodeFinex;
return number.Replace(codeFinex, replaceCode).Replace(csCodeFinex, replaceCSCode);
}
/// <summary>
/// Получить следующий порядковый номер для журнала.
/// </summary>
/// <param name="date">Дата.</param>
/// <param name="leadDocumentId">Ведущий документ.</param>
/// <param name="departmentId">Подразделение.</param>
/// <param name="businessUnitId">НОР.</param>
/// <param name="document">Текущий документ.</param>
/// <returns>Порядковый номер.</returns>
public virtual int? GetNextIndex(DateTime date, int leadDocumentId, int departmentId, int businessUnitId, int categoryId, IOfficialDocument document)
{
#region CUSTOM
var index = this.GetCurrentNumber(date, leadDocumentId, departmentId, businessUnitId, categoryId) + 1;
var documents = GetOtherDocumentsInPeriodBySections(document, date)
.Where(l => l.Index >= index)
.Where(l => leadDocumentId == 0 || l.LeadingDocument != null && Equals(l.LeadingDocument.Id, leadDocumentId))
.Where(l => departmentId == 0 || l.Department != null && Equals(l.Department.Id, departmentId))
.Where(l => businessUnitId == 0 || l.BusinessUnit != null && Equals(l.BusinessUnit.Id, businessUnitId));
// Условие для категорий договоров и доп. соглашений.
if (Contracts.Is(document))
documents = documents.Where(l => categoryId == 0 || Contracts.Is(l) && Contracts.As(l).DocumentGroup != null && Contracts.As(l).DocumentGroup.Id == categoryId);
else if (SupAgreements.Is(document))
documents = documents.Where(l => categoryId == 0 || SupAgreements.Is(l) && SupAgreements.As(l).DocumentGroup != null && SupAgreements.As(l).DocumentGroup.Id == categoryId);
#endregion
var documentslist = documents.Select(i => i.Index).ToList();
// Вернуть следующий номер, если он не занят.
if (!documentslist.Contains(index))
return index;
// Найти следующий незанятый номер.
index = documentslist.Where(d => !documentslist.Contains(d.Value + 1)).Min(d => d.Value) + 1;
return index;
}
/// <summary>
/// Получить документы, зарегистрированные в журнале в тот же период по тем же разрезам.
/// </summary>
/// <param name="doc">Документ.</param>
/// <param name="registrationDate">Дата регистрации.</param>
/// <returns>Документы, зарегистрированные в журнале в тот же период по тем же разрезам.</returns>
[Public]
public override IQueryable<IOfficialDocument> GetOtherDocumentsInPeriodBySections(IOfficialDocument doc, DateTime registrationDate)
{
var documents = base.GetOtherDocumentsInPeriodBySections(doc, registrationDate);
#region CUSTOM
if (_obj.NumberingSection == finex.MotivContracts.DocumentRegister.NumberingSection.Category)
{
if (Contracts.Is(doc))
documents = documents.Where(d => Contracts.Is(d) && Equals(Contracts.As(d).DocumentGroup, Contracts.As(doc).DocumentGroup));
else if (SupAgreements.Is(doc))
documents = documents.Where(d => SupAgreements.Is(d) && Equals(SupAgreements.As(d).DocumentGroup, SupAgreements.As(doc).DocumentGroup));
}
#endregion
return documents;
}
/// <summary>
/// Получить текущий порядковый номер для журнала.
/// </summary>
/// <param name="date">Дата.</param>
/// <param name="leadDocumentId">ID ведущего документа.</param>
/// <param name="departmentId">ID подразделения.</param>
/// <param name="businessUnitId">ID НОР.</param>
/// <param name="categoryId">ID категории.</param>
/// <returns>Порядковый номер.</returns>
[Public, Remote(IsPure = true)]
public virtual int GetCurrentNumber(DateTime date, int leadDocumentId, int departmentId, int businessUnitId, int categoryId)
{
var month = Sungero.Docflow.PublicFunctions.DocumentRegister.GetCurrentMonth(_obj, date);
var year = Sungero.Docflow.PublicFunctions.DocumentRegister.GetCurrentYear(_obj, date);
var quarter = Sungero.Docflow.PublicFunctions.DocumentRegister.GetCurrentQuarter(_obj, date);
if (_obj.NumberingSection != Sungero.Docflow.DocumentRegister.NumberingSection.LeadingDocument)
leadDocumentId = 0;
if (_obj.NumberingSection != Sungero.Docflow.DocumentRegister.NumberingSection.Department)
departmentId = 0;
if (_obj.NumberingSection != Sungero.Docflow.DocumentRegister.NumberingSection.BusinessUnit)
businessUnitId = 0;
#region CUSTOM
if (_obj.NumberingSection != finex.MotivContracts.DocumentRegister.NumberingSection.Category)
categoryId = 0;
// Вызываем свою реализацию запроса GetCurrentNumber
var command = string.Format(finex.MotivContracts.Queries.DocumentRegister.GetCurrentNumber,
_obj.Id, month, year, leadDocumentId, quarter, departmentId, businessUnitId, categoryId);
#endregion
var executionResult = Sungero.Docflow.PublicFunctions.Module.ExecuteScalarSQLCommand(command);
var result = 0;
if (!(executionResult is DBNull) && executionResult != null)
int.TryParse(executionResult.ToString(), out result);
return result;
}
/// <summary>
/// Установить текущий номер документа для журнала.
/// </summary>
/// <param name="index">Текущий номер.</param>
/// <param name="leadDocumentId">ID ведущего документа.</param>
/// <param name="departmentId">ID подразделения.</param>
/// <param name="businessUnitId">ID НОР.</param>
/// <param name="categoryId">ID категории.</param>
/// <param name="date">Дата регистрации документа.</param>
[Public, Remote]
public virtual void SetCurrentNumber(int index, int leadDocumentId, int departmentId, int businessUnitId, int categoryId, DateTime date)
{
var month = Sungero.Docflow.PublicFunctions.DocumentRegister.GetCurrentMonth(_obj, date);
var year = Sungero.Docflow.PublicFunctions.DocumentRegister.GetCurrentYear(_obj, date);
var quarter = Sungero.Docflow.PublicFunctions.DocumentRegister.GetCurrentQuarter(_obj, date);
if (_obj.NumberingSection != Sungero.Docflow.DocumentRegister.NumberingSection.LeadingDocument)
leadDocumentId = 0;
if (_obj.NumberingSection != Sungero.Docflow.DocumentRegister.NumberingSection.Department)
departmentId = 0;
if (_obj.NumberingSection != Sungero.Docflow.DocumentRegister.NumberingSection.BusinessUnit)
businessUnitId = 0;
#region CUSTOM
if (_obj.NumberingSection != finex.MotivContracts.DocumentRegister.NumberingSection.Category)
categoryId = 0;
// Вызываем свою реализацию запроса SetCurrentNumber
var commandText = string.Format(finex.MotivContracts.Queries.DocumentRegister.SetCurrentNumber,
_obj.Id, index, month, year, leadDocumentId, quarter, departmentId, businessUnitId, categoryId);
#endregion
Sungero.Docflow.PublicFunctions.Module.ExecuteSQLCommand(commandText);
}
/// <summary>
/// Получить следующий регистрационный номер.
/// </summary>
/// <param name="registrationDate">Дата регистрации.</param>
/// <param name="leadDocument">Ведущий документ.</param>
/// <param name="department">Подразделение.</param>
/// <param name="businessUnit">НОР.</param>
/// <param name="category">Категория.</param>
/// <returns>Следующий регистрационный номер.</returns>
[Public]
public virtual int GetNextRegistrationNumber(DateTime registrationDate, int leadDocument = 0, int department = 0, int businessUnit = 0, int category = 0)
{
if (_obj.NumberingSection != Sungero.Docflow.DocumentRegister.NumberingSection.LeadingDocument)
leadDocument = 0;
if (_obj.NumberingSection != Sungero.Docflow.DocumentRegister.NumberingSection.Department)
department = 0;
if (_obj.NumberingSection != Sungero.Docflow.DocumentRegister.NumberingSection.BusinessUnit)
businessUnit = 0;
#region CUSTOM
if (_obj.NumberingSection != finex.MotivContracts.DocumentRegister.NumberingSection.Category)
category = 0;
#endregion
using (var command = SQL.GetCurrentConnection().CreateCommand())
{
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = "Sungero_DocRegister_GetNextNumber";
Sungero.Docflow.PublicFunctions.Module.AddIntegerParameterToCommand(command, "@basevalue", 1);
Sungero.Docflow.PublicFunctions.Module.AddIntegerParameterToCommand(command, "@docregid", _obj.Id);
Sungero.Docflow.PublicFunctions.Module.AddIntegerParameterToCommand(command, "@newmonth", Sungero.Docflow.PublicFunctions.DocumentRegister.GetCurrentMonth(_obj, registrationDate));
Sungero.Docflow.PublicFunctions.Module.AddIntegerParameterToCommand(command, "@newyear", Sungero.Docflow.PublicFunctions.DocumentRegister.GetCurrentYear(_obj, registrationDate));
Sungero.Docflow.PublicFunctions.Module.AddIntegerParameterToCommand(command, "@leaddoc", leadDocument);
Sungero.Docflow.PublicFunctions.Module.AddIntegerParameterToCommand(command, "@newquarter", Sungero.Docflow.PublicFunctions.DocumentRegister.GetCurrentQuarter(_obj, registrationDate));
Sungero.Docflow.PublicFunctions.Module.AddIntegerParameterToCommand(command, "@newdep", department);
Sungero.Docflow.PublicFunctions.Module.AddIntegerParameterToCommand(command, "@newbusinessunit", businessUnit);
// CUSTOM Передача нового параметра Id категории в обновленную процедуру GeNextNumber
Sungero.Docflow.PublicFunctions.Module.AddIntegerParameterToCommand(command, "@newcategory", category);
var code = Sungero.Docflow.PublicFunctions.Module.AddIntegerOutputParameterToCommand(command, "@result");
command.ExecuteNonQuery();
var registrationIndex = 0;
int.TryParse(code.Value.ToString(), out registrationIndex);
return registrationIndex;
}
}
Что бы базовый механизм регистрации продолжал исправно работать во всех других ТД, переопределяем все вышеуказанные функции. Вместо базовой логики вызываем свои перегрузки с передачей параметра Id категории равным 0. Таким образом при вызове базовых функций код неизбежно придет в наши перегрузки.
/// <summary>
/// Получить следующий регистрационный номер.
/// </summary>
[Remote(IsPure = true)]
public override string GetNextNumber(DateTime date, int leadDocumentId, IOfficialDocument document, string leadingDocumentNumber,
int departmentId, int businessUnitId, string caseFileIndex, string docKindCode, string indexLeadingSymbol)
{
return this.GetNextNumber(date, leadDocumentId, document, leadingDocumentNumber, departmentId, businessUnitId, 0, caseFileIndex, docKindCode, indexLeadingSymbol);
}
/// <summary>
/// Получить следующий порядковый номер для журнала.
/// </summary>
public override int? GetNextIndex(DateTime date, int leadDocumentId, int departmentId, int businessUnitId, IOfficialDocument document)
{
return this.GetNextIndex(date, leadDocumentId, departmentId, businessUnitId, 0, document);
}
/// <summary>
/// Получить текущий порядковый номер для журнала.
/// </summary>
[Remote(IsPure = true)]
public override int GetCurrentNumber(DateTime date, int leadDocumentId, int departmentId, int businessUnitId)
{
return Functions.DocumentRegister.GetCurrentNumber(_obj, date, leadDocumentId, departmentId, businessUnitId, 0);
}
/// <summary>
/// Установить текущий номер документа для журнала.
/// </summary>
[Public, Remote]
public override void SetCurrentNumber(int index, int leadDocumentId, int departmentId, int businessUnitId, DateTime date)
{
this.SetCurrentNumber(index, leadDocumentId, departmentId, businessUnitId, 0, date);
}
/// <summary>
/// Получить следующий регистрационный номер.
/// </summary>
[Public]
public override int GetNextRegistrationNumber(DateTime registrationDate, int leadDocument, int department, int businessUnit)
{
return this.GetNextRegistrationNumber(registrationDate, leadDocument, department, businessUnit, 0);
}
Последним действием осталось передаваемый параметр во всех событиях, где вызываются эти функции:
Так как обработчики последних двух пунктов зашиты в OfficialDocument, нужно учитывать, что в версиях ниже 4.0 придется перекрывать все ТД, в которых нумерация может идти по новому разрезу (в нашем случае это договоры и доп. соглашения).
Что бы нумерация проходила в новом разрезе, необходимо заменить функцию Functions.OfficialDocument.Register(), вызываемую в обработчике действия «регистрация» ТД OfficialDocument, т.к. она не является виртуальной.
public override void Register(Sungero.Domain.Client.ExecuteActionArgs e)
{
var originalNumber = _obj.State.Properties.RegistrationNumber.OriginalValue;
var originalDate = _obj.State.Properties.RegistrationDate.OriginalValue;
// Если документ в процессе верификации, то игнорировать изменение полей регистрационных данных.
if (_obj.VerificationState == Sungero.Docflow.OfficialDocument.VerificationState.InProcess)
e.Params.Remove(Sungero.Docflow.Constants.OfficialDocument.NeedValidateRegisterFormat);
#region Custom Вызов функции для регистрации.
finex.MotivContracts.Module.Docflow.Functions.Module.CustomContractsRegister(_obj, e);
#endregion
if (_obj.RegistrationNumber != originalNumber)
_obj.State.Properties.RegistrationNumber.HighlightColor = Colors.Empty;
if (_obj.RegistrationDate != originalDate)
_obj.State.Properties.RegistrationDate.HighlightColor = Colors.Empty;
}
/// <summary>
/// Зарегистрировать документ.
/// </summary>
public virtual void CustomContractsRegister(Sungero.Docflow.IOfficialDocument document, Sungero.Domain.Client.ExecuteActionArgs e)
{
if (!e.Validate())
return;
var officalDocumentsClientFunctions = new Sungero.Docflow.Client.OfficialDocumentFunctions(document);
// Регистрация документа с зарезервированным номером.
if (document.RegistrationState == Sungero.Docflow.OfficialDocument.RegistrationState.Reserved)
{
officalDocumentsClientFunctions.RegisterWithReservedNumber(e);
return;
}
#region Custom Список доступных журналов (свой вариант реализации).
var dialogParams = CustomContracts.PublicFunctions.Module.Remote.GetRegistrationDialogParams(document, Sungero.Docflow.RegistrationSetting.SettingType.Registration);
#endregion
if (dialogParams.Registers == null || !dialogParams.Registers.Any())
{
e.AddError(Sungero.Docflow.Resources.NoDocumentRegistersAvailable);
return;
}
#region Custom Вызвать диалог (свой вариант реализации).
var result = RunRegistrationDialog(document, dialogParams);
#endregion
if (result != null)
{
Sungero.Docflow.PublicFunctions.OfficialDocument.RegisterDocument(document, result.Register, result.Date, result.Number, false, true);
Dialogs.NotifyMessage(Sungero.Docflow.Resources.SuccessRegisterNotice);
}
return;
}
Здесь нам потребуется заменить статические функции GetRegistrationDialogParams и RunRegistrationDialog, а весь остальной функционал берется из базовой логики. Так же стоит учесть, что функция GetRegistrationDialogParams возвращает параметры диалога в виде структуры DialogParams модуля Docflow, следовательно необходимо создать новую структуру в своем модуле с добавлением нового свойства для категории договора.
/// <summary>
/// Получить все данные для отображения диалога регистрации.
/// </summary>
/// <param name="document">Документ.</param>
/// <param name="operation">Операция.</param>
/// <returns>Параметры диалога.</returns>
[Public, Remote(IsPure = true)]
public virtual CustomContracts.Structures.Module.IDialogParams GetRegistrationDialogParams(Sungero.Docflow.IOfficialDocument document, Enumeration operation)
{
// Получить функции разделяемого и серверного слоя OfficialDocument.
var officialDocumentSharedFunctions = new Sungero.Docflow.Shared.OfficialDocumentFunctions(document);
var officialDocumentServerFunctions = new Sungero.Docflow.Server.OfficialDocumentFunctions(document);
var leadDocumentId = officialDocumentSharedFunctions.GetLeadDocumentId();
var leadDocumentNumber = officialDocumentSharedFunctions.GetLeadDocumentNumber();
var numberValidationDisabled = officialDocumentServerFunctions.IsNumberValidationDisabled();
var departmentId = document.Department != null ? document.Department.Id : 0;
var departmentCode = document.Department != null ? document.Department.Code : string.Empty;
var businessUnitId = document.BusinessUnit != null ? document.BusinessUnit.Id : 0;
var businessUnitCode = document.BusinessUnit != null ? document.BusinessUnit.Code : string.Empty;
var docKindCode = document.DocumentKind != null ? document.DocumentKind.Code : string.Empty;
var caseFileIndex = document.CaseFile != null ? document.CaseFile.Index : string.Empty;
var isClerk = document.AccessRights.CanRegister();
var counterpartyCode = Sungero.Docflow.PublicFunctions.OfficialDocument.GetCounterpartyCode(document);
var currentRegistrationDate = document.RegistrationDate ?? Calendar.UserToday;
#region Custom вычисляем id записи категории для получения очередного номера.
var categoryId = 0;
if (Contracts.Is(document))
categoryId = Contracts.As(document).DocumentGroup.Id;
else if (SupAgreements.Is(document))
categoryId = SupAgreements.As(document).DocumentGroup.Id;
#endregion
var registers = Sungero.Docflow.PublicFunctions.OfficialDocument.GetDocumentRegistersByDocument(document, operation);
var defaultDocumentRegister = MotivContracts.PublicFunctions.DocumentRegister.MotivGetDefaultDocRegister(document, registers, operation);
string nextNumber = string.Empty;
#region Custom заменяем вызов базового запроса GetNextNumber
if (defaultDocumentRegister != null)
nextNumber = MotivContracts.PublicFunctions.DocumentRegister.Remote.GetNextNumber(MotivContracts.DocumentRegisters.As(defaultDocumentRegister), currentRegistrationDate, leadDocumentId, document,
leadDocumentNumber, departmentId, businessUnitId, categoryId, caseFileIndex, docKindCode,
Sungero.Docflow.Constants.OfficialDocument.DefaultIndexLeadingSymbol);
// Функция должна возвращать структуру с учетом новых элементов в нашем случае categoryId.
return Structures.Module.DialogParams.Create(registers.Select(r => MotivContracts.DocumentRegisters.As(r)).ToList(),
operation, MotivContracts.DocumentRegisters.As(defaultDocumentRegister),
document.RegistrationNumber, currentRegistrationDate, nextNumber,
leadDocumentId, leadDocumentNumber, numberValidationDisabled,
departmentId, departmentCode, businessUnitCode, businessUnitId,
caseFileIndex, docKindCode, counterpartyCode, isClerk, categoryId);
#endregion
}
Функция RunRegistrationDialog , запускающая обработчик диалога регистрации, на входе принимает структуру с данными для отображения диалога. В событиях диалога, функции RunRegistrationDialog, вызывается функция GetNextNumber, соответственно переписываем ее с добавлением нового параметра. Например событие изменения значения журнала регистрации:
register.SetOnValueChanged((e) =>
{
hyperlink.IsEnabled = e.NewValue != null && date.Value.HasValue;
number.IsEnabled = isManual.Value.Value && e.NewValue != null && date.Value.HasValue;
if (e.NewValue != null)
{
var previewDate = date.Value ?? Calendar.UserToday;
#region Custom Заменяем вызов базового запроса GetNextNumber
var previewNumber = MotivContracts.PublicFunctions.DocumentRegister.Remote
.GetNextNumber(e.NewValue, previewDate, leadDocumentId, document, leadDocumentNumber, departmentId,
businessUnitId, categoryId, caseFileIndex, docKindCode, Sungero.Docflow.Constants.OfficialDocument.DefaultIndexLeadingSymbol);
#endregion
number.Value = previewNumber;
}
else
number.Value = string.Empty;
});
Как итог демонстрация присвоения номера регистрации в разрезе категории договора.
Спасибо за статью! Может быть, я что-то не то сделал, но только мне пришлось перекрыть модуль Docflow и до базовой инициализации удалить хранимую процедуру. Иначе базовая инициализация Docflow завершается с ошибкой, связанной с уникальностью имени процедуры.
Авторизуйтесь, чтобы написать комментарий