private async Task SendNotificationsAsync(
            Dictionary <string, IReadOnlyList <Timesheet> > timesheets,
            string key,
            string email,
            bool notify,
            TimesheetStates state,
            DateTime scheduleDate,
            GoogleChatAddress address,
            IReadOnlyList <string> customerToExcludes,
            ITimesheetProcessor processor)
        {
            if (!timesheets.TryGetValue(key, out var timesheetValues))
            {
                timesheetValues = await processor.GetTimesheetsAsync(scheduleDate, state, email, true, customerToExcludes);

                timesheets.Add(key, timesheetValues);
            }

            await processor.SendTimesheetNotificationsToUsersAsync(
                timesheetValues,
                email,
                department : null,
                notify : notify,
                notifyByEmail : false,
                state,
                address,
                _hangoutsChatConnector);
        }
        private async Task SaveGlobalStatisticsAsync(
            DateTime scheduleDate,
            IReadOnlyList <string> customerToExcludes,
            IPluginPropertiesAccessor accessor,
            ITimesheetProcessor processor)
        {
            var group = accessor.GetPluginPropertyGroup(TimesheetsProperties.GlobalStatisticsGroup).FirstOrDefault();

            if (group == null)
            {
                return;
            }

            var cron = group.GetValue <string>(TimesheetsProperties.GlobalStatisticsCron);

            if (string.IsNullOrEmpty(cron) ||
                !CronCheck(cron, scheduleDate))
            {
                return;
            }

            const TimesheetStates state = TimesheetStates.Unsubmitted;
            var dateValue  = scheduleDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
            var timeValue  = scheduleDate.ToString("HH:00", CultureInfo.InvariantCulture);
            var email      = group.GetValue <string>(TimesheetsProperties.GlobalStatisticsEmail);
            var timesheets = await processor.GetTimesheetsAsync(scheduleDate, state, email, true, customerToExcludes);

            var statistics = new Statistics <TimesheetStatistics[]>
            {
                Id   = Guid.NewGuid().ToString(),
                Date = dateValue,
                Time = timeValue,
                Type = nameof(TimesheetStatistics),
                Data = timesheets
                       .Select(it =>
                               new TimesheetStatistics
                {
                    UserName       = it.UserName,
                    ManagerName    = it.ManagerName,
                    DepartmentName = it.DepartmentName,
                    State          = state,
                })
                       .ToArray()
            };

            await _storageService.AddOrUpdateStatisticsAsync(statistics);
        }