Отчет по голосованию в задаче согласование по регламенту

28 0

В продолжении статьи «Модификация «Голосование» для задачи согласования по регламенту»

Задача

Создать новый отчет по голосованию по протоколу совещания. Строки отчета должны быть сгруппированы по решению из протокола. В каждой группе выводится ФИО голосующего, дата и результат голосования. В подвале группы – итоговый результат по решению.

Требуемые модификации:

  1. Создать структуру для передачи в SQL-таблицу
  2. Создать константу для хранения имени SQL-таблицы
  3. Написать SQL-запросы
  4. Добавить параметры отчета
  5. Добавить SQL-источник данных
  6. Добавить ресурсы отчета
  7. Настроить дизайн отчета
  8. Написать логику сбора результатов и очистку таблицы после выполнения
  9. Инициализировать SQL-таблицу, выдать права на выполнение отчета
  10. Добавить кнопку экспорта отчета на ленту протокола совещания

 

Постфикс и код компании: centrvd

Имя решение: Solution

Имя модуля: SolutionDatabook

Структура отчета

Создадим отчет MinutesVotingReport . Добавим структуру, которую позже будем передавать в SQL таблицу:

/// <summary>
/// Строчка отчета.
/// </summary>
partial class TableLine
{
  public string ReportSessionId { get; set; }
  public string Decision { get; set; }
  public string VoterName { get; set; }
  public string VoteDate { get; set; }
  public string VoterResult { get; set; }
  public string OverallResult { get; set; }
}

Константы

Добавим константы отчета:

public static class MinutesVotingReport
{
  public const string SourceTableName = "centrvd_Solution1_Reports_MinutesVoting";
}

Запросы

Создадим 2 SQL запроса на создание и получение данные из таблицы:

CreateMinutesVotingReportSourceTable

MSSQL

POSTGRESQL

create table {0}
([ReportSessionId] nvarchar(max) NOT NULL,
[Decision] nvarchar(max) NOT NULL,
[VoterName] nvarchar(max) NOT NULL,
[VoteDate] nvarchar(max),
[VoterResult] nvarchar(max),
[OverallResult] nvarchar(max) NOT NULL)

create table {0}
(ReportSessionId citext NOT NULL,
Decision citext NOT NULL,
VoterName citext NOT NULL,
VoteDate citext,
VoterResult citext,
OverallResult citext NOT NULL)

 

SelectDataFromTable

select *
from centrvd_Solution1_Reports_MinutesVoting temp
where ReportSessionId = @ReportSessionId

Параметры отчета

Добавим 3 параметра для передачи в отчет идентификатора сессии данных, протокола совещания и времени формирования отчета:

Имя

Тип

ReportSessionId

String

Minutes

centrvd.Solution.IMinutes

CurrentDate

DateTime

Источники данных

В дизайнере добавим источник данных на основе SQL-запроса:

Имя запроса: SourceTable

SQL зарос: SelectDataFromTable

Параметр запроса: ReportSessionId (тип string) (Expression = [ReportSessionId])

Поля запроса:

Имя

Тип

Decision

String

VoterName

String

VoteDate

String

VoterResult

String

OverallResult

String

Ресурсы отчета

Создадим ресурсы, которые позже будут использоваться в настройках бендов:

Имя

Английская локализация

Русская локализация

DesignerDate

Date:

Дата:

DesignerDecision

Decision:

Решение:

DesignerDecisionsForVoting

Decisions for voting:

Решений для голосования:

DesignerDocumentStatus

Document status:

Статус документа:

DesignerResults

Results:

Результаты:

DesignerVote

Vote

Голос

DesignerVoteDate

Vote date

Дата голосования

DesignerVoter

Voter

Голосующий

DesignerVotingOnTheDocument

Voting on the document:

Голосование по документу:

DidNotVote

Did not vote

Не проголосовал

ThereWasNoVote

There was no vote

Голосование не проводилось

VotingIsNotCompleted

Voting is not completed.

Голосование не завершено.

Дизайнер отчета

Настроим дизайнер, как показано на скриншоте.

Группировка по полю [SourceTable.Decision]

До выполнения

Перейдем к серверному событию «До выполнения». В статье по модификации «Голосование» для задачи согласования по регламенту результаты голосования попадают в карточку протокола через асинхронный обработчик. Чтобы отчет отображал самую актуальную информацию, необходимо результаты получать из всех заданий на голосование. В том числе, если сотрудник еще не проголосовал. На случай перезапуска задач будем брать последние созданные задания:

public override void BeforeExecute(Sungero.Reporting.Server.BeforeExecuteEventArgs e)
{
  MinutesVotingReport.ReportSessionId = Guid.NewGuid().ToString();
  MinutesVotingReport.CurrentDate = Calendar.UserToday;
      
  var dataTable = new List<Structures.MinutesVotingReport.TableLine>();
      
  // Проход по всем решениям протокола.
  foreach (var decision in MinutesVotingReport.Minutes.Decisionscentrvd.OrderBy(d => d.Number))
  {
    List<Sungero.Company.IEmployee> employees = decision.Matrix.Approvers.Select(a => a.Approver).ToList();
        
    var voteIsOn = string.Empty;
    // Рассчитать итоги по решению.
    var decisionOverallResult = centrvd.Solution.PublicFunctions.Minutes.GetVotingResults(MinutesVotingReport.Minutes, decision);
    var tableLine = Structures.MinutesVotingReport.TableLine.Create();
        
    // Проход по всем голосующим из матрицы.
    foreach (var employee in employees)
    {
      //Находим последнее созданное задание на голосование по протоколу c решением по текущему сотруднику.
      var votingAssignment = centrvd.Solution.ApprovalSimpleAssignments.GetAll()
        .Where(m => m.Task.AttachmentDetails.Any(d => d.EntityId.Value == MinutesVotingReport.Minutes.Id))
        .Where(p => Equals(p.Performer, Users.As(employee)))
        .Where(a => a.Voitingcentrvd.Any(d => d.MinutedDecisionId == decision.Id))
        .OrderByDescending(a => a.Created)
        .FirstOrDefault();
          
      if (votingAssignment == null)
      {
        tableLine.Decision = decision.Decision;
        tableLine.ReportSessionId = MinutesVotingReport.ReportSessionId;
        tableLine.VoteDate = string.Empty;
        tableLine.VoterName = employee.Name;
        tableLine.VoterResult = string.Empty;
        tableLine.OverallResult = centrvd.SolutionDataBook.Reports.Resources.MinutesVotingReport.ThereWasNoVote;
            
        dataTable.Add(tableLine);
      }
      else
      {
        //Находим результат голосования по решению.
        var decisionVote = votingAssignment.Voitingcentrvd.Where(r => r.MinutedDecisionId == decision.Id).FirstOrDefault();
        var decisionVoteResult = string.Empty;
            
        if (votingAssignment.Completed.HasValue && decisionVote.VoteFor.GetValueOrDefault())
          decisionVoteResult = MinutesVotingReport.Minutes.Info.Properties.Decisionscentrvd.Properties.VoteFor.LocalizedName;
        if (votingAssignment.Completed.HasValue && decisionVote.VoteAgainst.GetValueOrDefault())
          decisionVoteResult = MinutesVotingReport.Minutes.Info.Properties.Decisionscentrvd.Properties.VoteAgainst.LocalizedName;
        if (votingAssignment.Completed.HasValue && decisionVote.VoteAbstain.GetValueOrDefault())
          decisionVoteResult = MinutesVotingReport.Minutes.Info.Properties.Decisionscentrvd.Properties.VoteAbstain.LocalizedName;
            
        // Если есть незавершенные задания - то в итоговый результат добавляется текст.
        if (!votingAssignment.Completed.HasValue)
          voteIsOn = centrvd.SolutionDataBook.Reports.Resources.MinutesVotingReport.VotingIsNotCompleted;
            
        tableLine.Decision = decision.Decision;
        tableLine.ReportSessionId = MinutesVotingReport.ReportSessionId;
        tableLine.VoteDate = votingAssignment.Completed.HasValue ? votingAssignment.Completed.Value.ToShortDateString() : centrvd.SolutionDataBook.Reports.Resources.MinutesVotingReport.DidNotVote;
        tableLine.VoterName = employee.Name;
        tableLine.VoterResult = !string.IsNullOrEmpty(decisionVoteResult) ? decisionVoteResult : centrvd.SolutionBook.Reports.Resources.MinutesVotingReport.DidNotVote;
        tableLine.OverallResult = voteIsOn + decisionOverallResult;
            
        dataTable.Add(tableLine);
      }
    }
  }
      Sungero.Docflow.PublicFunctions.Module.WriteStructuresToTable(Constants.MinutesVotingReport.SourceTableName, dataTable);
}

В серверные функции перекрытого протокола (Minutes) добавим функцию GetVotingResults() для вычисления итогов по решению (возможно вычислять итоги по решению и До выполнения отчета, но тогда нужно будет внимательно относиться к выбору данных из таблицы). Эти итоги будут отображаться в подвале группы:

/// <summary>
/// Получить результаты голосования по решению протокола совещания.
/// </summary>
/// <param name="decision">Строка коллекции решений.</param>
/// <returns>Результаты в форме строки: За - х, Против - х, Воздержался - х.</returns>
[Public]
public string GetVotingResults(IMinutesDecisionscentrvd decision)
{
  if (!centrvd.Solution.DocumentKinds.As(_obj.DocumentKind).NeedVoitingcentrvd.GetValueOrDefault() || !_obj.Decisionscentrvd.Any())
    return string.Empty;

  int voteFor = 0;
  int voteAgainst = 0;
  int voteAbstain = 0;
      
  List<Sungero.Company.IEmployee> employees = decision.Matrix.Approvers.Select(a => a.Approver).ToList();
      
  foreach (var employee in employees)
  {
    var votingAssignment = centrvd.Solution.ApprovalSimpleAssignments.GetAll()
      .Where(m => m.Task.AttachmentDetails.Any(d => d.EntityId.Value == _obj.Id))
      .Where(p => Equals(p.Performer, Users.As(employee)))
      .Where(a => a.Voitingcentrvd.Any(d => d.MinutedDecisionId == decision.Id))
      .OrderByDescending(a => a.Created)
      .FirstOrDefault();
        
    if (votingAssignment != null && votingAssignment.Status == centrvd.Solution.ApprovalSimpleAssignment.Status.Completed)
    {
      var assignmentDecision = votingAssignment.Voitingcentrvd.Where(v => v.MinutedDecisionId == decision.Id).FirstOrDefault();
      if (assignmentDecision.VoteFor.GetValueOrDefault())
        voteFor++;
      if (assignmentDecision.VoteAgainst.GetValueOrDefault())
        voteAgainst++;
      if (assignmentDecision.VoteAbstain.GetValueOrDefault())
        voteAbstain++;
    }
  }
      
  return centrvd.SolutionDataBook.Resources.ResultsFormat(voteFor, voteAgainst, voteAbstain);
}

После выполнения

Перейдем к серверному событию «После выполнения» и удалим данные из таблицы:

public override void AfterExecute(Sungero.Reporting.Server.AfterExecuteEventArgs e)
{
  Sungero.Docflow.PublicFunctions.Module.DeleteReportData(centrvd.SolutionDataBook.Constants.MinutesVotingReport.SourceTableName, MinutesVotingReport.ReportSessionId);
}

Инициализация

Добавим удаление и создание SQL таблицы centrvd_Solution1_Reports_MinutesVoting в инициализацию модуля. А также выдачу прав всем пользователям на выполнение отчета:

public override void Initializing(Sungero.Domain.ModuleInitializingEventArgs e)
{
  //Отчеты
  CreateReportsTables();
  GrantingRightsToReports();
}

/// [summary](summary)
/// Создать таблицы для отчетов.
/// </summary>
public static void CreateReportsTables()
{
  var minutesVotingTableName = Constants.MinutesVotingReport.SourceTableName;
  
  Sungero.Docflow.PublicFunctions.Module.DropReportTempTables(new[] {minutesVotingTableName});
  Sungero.Docflow.PublicFunctions.Module.ExecuteSQLCommandFormat(Queries.MinutesVotingReport.CreateMinutesVotingReportSourceTable, new[] {minutesVotingTableName});
}

/// [summary](summary)
/// Выдача прав на выполнение отчетов
/// </summary>
public static void GrantingRightsToReports()
{
  InitializationLogger.Debug("Init: Выдача всем пользователям прав на выполнение отчета Итоги голосования по протоколу совещания.");
  Reports.AccessRights.Grant(Reports.GetMinutesVotingReport().Info, Roles.AllUsers, DefaultReportAccessRightsTypes.Execute);
}

Действие в протоколе совещания

Добавим действие на ленту протокола совещания. Кнопка должна отображаться только для протоколов с видом, требующим голосование. Формат имени формируемого файла: «Итоги голосования по {Имя_протокола}»:

partial class MinutesActions
{
  public virtual void VotingReportcentrvd(Sungero.Domain.Client.ExecuteActionArgs e)
  {
    var votingReport = centrvd.SolutionDataBook.Reports.GetMinutesVotingReport();
    votingReport.Minutes = _obj;
    votingReport.ExportToFile(centrvd.Solution.Minuteses.Resources.VotingReportFileNameFormat(_obj.Name));
  }

  public virtual bool CanVotingReportcentrvd(Sungero.Domain.Client.CanExecuteActionArgs e)
  {
    return !_obj.State.IsInserted && centrvd.Solution.DocumentKinds.As(_obj.DocumentKind).NeedVoitingcentrvd.GetValueOrDefault();
  }
}

 

Пока комментариев нет.

Авторизуйтесь, чтобы написать комментарий