示例#1
0
        private async void ResendMessageIfNeeded()
        {
            DateTime nowLocal = TimeZoneInfo.ConvertTimeFromUtc(SystemTime.Now(), TimeZoneInfo.Local);
            DateTime todayUtc = SystemTime.Now().Date;
            DateTime lastReceivedMessageDateTimeUtc =
                MessageUtils.GetDateTimeFromSecureStorageForKey(SecureStorageKeys.LAST_SENT_NOTIFICATION_UTC_KEY, nameof(ResendMessageIfNeeded));
            DateTime lastReceivedMessageDateTimeLocal = lastReceivedMessageDateTimeUtc.ToLocalTime();

            if (lastReceivedMessageDateTimeUtc < todayUtc &&
                nowLocal.Date.Subtract(lastReceivedMessageDateTimeLocal.Date).TotalHours >= Conf.HOURS_UNTIL_RESEND_MESSAGES)
            {
                if (nowLocal.Hour >= Conf.HOUR_WHEN_MESSAGE_SHOULD_BE_RESEND)
                {
                    List <MessageSQLiteModel> unreadMessages = await MessageUtils.GetAllUnreadMessages();

                    List <MessageSQLiteModel> unreadMessagesNotOlderThanMsgRetentionTime =
                        unreadMessages.FindAll(message =>
                    {
                        double totalMinutes = SystemTime.Now().Subtract(message.TimeStamp).TotalMinutes;
                        return(totalMinutes <
                               Conf.MAX_MESSAGE_RETENTION_TIME_IN_MINUTES);
                    })
                        .ToList();

                    if (unreadMessagesNotOlderThanMsgRetentionTime.Count > 0)
                    {
                        NotificationsHelper.CreateNotification(NotificationsEnum.NewMessageReceived, 0);
                        MessageUtils.SaveDateTimeToSecureStorageForKey(
                            SecureStorageKeys.LAST_SENT_NOTIFICATION_UTC_KEY,
                            SystemTime.Now(),
                            nameof(ResendMessageIfNeeded));
                    }
                }
            }
        }
        public async Task <ActionResult> Create([Bind(Include = "Description,Amount,BudgetItemId,BankAccountId,Created,IncomeExpenseId")] Transaction transaction)
        {
            if (!userHelper.UserHasEverything())
            {
                TempData["Error"] = "You must have a household, budget, and bank account(s) first!";
                return(RedirectToAction("ErrorPage", "Home"));
            }
            if (ModelState.IsValid)
            {
                var user = db.Users.Find(User.Identity.GetUserId());
                transaction.EnteredById = user.Id;
                transaction.Created     = DateTimeOffset.Now;
                db.Transactions.Add(transaction);
                db.SaveChanges();

                //Send emails and notifications
                #region Send Balance Notificationsa and emails
                var account        = db.BankAccounts.FirstOrDefault(a => a.Id == transaction.BankAccountId);
                var recipientEmail = account.AccountOwner.Email;
                var accountBalance = accountHelper.GetAccountBalance(account.Id);
                if (accountBalance <= account.WarningBalance)
                {
                    var callbackUrl = Url.Action("ViewTransactionAlert", "Transactions", new { transId = transaction.Id }, protocol: Request.Url.Scheme);
                    var message     = new IdentityMessage();
                    message.Destination = account.AccountOwner.Email;
                    message.Subject     = "Account Balance Warning";
                    message.Body        = account.Name + " has a balance of $" + accountBalance + ". Please click <a href=\"" + callbackUrl + "\">here</a> to view";
                    var emailSvc = new EmailService();
                    await emailSvc.SendAsync(message);

                    notificationsHelper.CreateNotification(message);
                }

                #endregion
                return(RedirectToAction("Index"));
            }

            ViewBag.BankAccountId   = new SelectList(db.BankAccounts, "Id", "Name", transaction.BankAccountId);
            ViewBag.BudgetItemId    = new SelectList(db.BudgetItems, "Id", "Name", transaction.BudgetItemId);
            ViewBag.EnteredById     = new SelectList(db.Users, "Id", "FirstName", transaction.EnteredById);
            ViewBag.IncomeExpenseId = new SelectList(db.IncomeExpenses, "Id", "Type", transaction.IncomeExpenseId);
            return(View(transaction));
        }
示例#3
0
        public async Task <ActionResult> SaveTransaction([Bind(Include = "Description,Amount,BudgetItemId,BankAccountId,Created,IncomeExpenseId")] Transaction transaction, int UploadedTransactionId)
        //public async Task<ActionResult> SaveTransaction(string Description, decimal Amount, int BudgetItemId, int BankAccountId, DateTimeOffset Created, int IncomeExpenseId, int UploadedTransactionId)
        {
            //var transaction = new Transaction();

            if (!userHelper.UserHasEverything())
            {
                TempData["Error"] = "You must have a household, budget, and bank account(s) first!";
                return(RedirectToAction("ErrorPage", "Home"));
            }

            var upTrans = db.UploadedTransactions.FirstOrDefault(up => up.Id == UploadedTransactionId);
            var user    = db.Users.Find(User.Identity.GetUserId());

            transaction.EnteredById = user.Id;
            //transaction.Description = Description;
            //transaction.Created = Created;
            //transaction.Amount = Amount;
            //transaction.BudgetItemId = BudgetItemId;
            //transaction.BankAccountId = BankAccountId;
            //transaction.IncomeExpenseId = IncomeExpenseId;

            //Add to db and save changes
            upTrans.Saved           = true;
            db.Entry(upTrans).State = EntityState.Modified;
            db.Transactions.Add(transaction);
            db.SaveChanges();

            //Send emails and notifications
            #region Send Balance Notificationsa and emails
            var account        = db.BankAccounts.FirstOrDefault(a => a.Id == transaction.BankAccountId);
            var recipientEmail = account.AccountOwner.Email;
            var accountBalance = accountHelper.GetAccountBalance(account.Id);
            if (accountBalance <= account.WarningBalance)
            {
                var callbackUrl = Url.Action("ViewTransactionAlert", "Transactions", new { transId = transaction.Id }, protocol: Request.Url.Scheme);
                var message     = new IdentityMessage();
                message.Destination = account.AccountOwner.Email;
                message.Subject     = "Account Balance Warning";
                message.Body        = account.Name + " has a balance of $" + accountBalance + ". Please click <a href=\"" + callbackUrl + "\">here</a> to view";
                var emailSvc = new EmailService();
                await emailSvc.SendAsync(message);

                notificationsHelper.CreateNotification(message);
            }

            #endregion

            /*Using RedirectToAction to clear residual SelectList data, so last selection does not appear in all of the
             * Budget Item Lists.*/
            return(RedirectToAction("NextTransaction"));
        }
示例#4
0
        /// <summary>
        /// Fetches the new keys if any.
        /// </summary>
        /// <returns>Paths to the temporary location where the zips are stored</returns>
        public async Task <IEnumerable <string> > PullNewKeys(ExposureNotificationWebService service, CancellationToken cancellationToken)
        {
            PullKeysParams requestParams = PullKeysParams.GenerateParams();

            LocalPreferencesHelper.DidFirstFileOfTheDayEndedWith204 = false;

            List <string> zipLocations      = new List <string>();
            bool          lastPull          = false;
            int?          lastBatchReceived = null;
            int?          lastReceivedStatusCodeFromRequest = null;

            while (!lastPull)
            {
                string requestUrl = requestParams.ToBatchFileRequest();

                ApiResponse <Stream> response = await service.GetDiagnosisKeys(requestUrl, cancellationToken);

                HttpHeaders headers = response.Headers;
                lastReceivedStatusCodeFromRequest = response.StatusCode;
                bool headersAreValid = true;

                if (response == null || (!response.IsSuccessfull))
                {
                    if (response?.StatusCode == 410)
                    {
                        NotificationsHelper.CreateNotification(NotificationsEnum.ApiDeprecated, 0);
                        string warning = "410 Api was deprecated";
                        _developerTools.AddToPullHistoryRecord(warning, requestUrl);
                        LogUtils.LogMessage(LogSeverity.WARNING, $"{_logPrefix}.{nameof(DownloadZips)}: {warning}");
                    }
                    else
                    {
                        //Failed to fetch new keys due to server error. This is already logged in the webservice.
                        _developerTools.AddToPullHistoryRecord($"{response.StatusCode} Server Error", requestUrl);
                    }
                    break; //Abort pulling
                }

                // If the server says 204: No Content, it means that there were no new keys (I.e. the request batch does not exist)
                if (response.StatusCode == 204)
                {
                    if (requestParams.Date.Date < SystemTime.Now().Date)
                    {
                        //If there were no new keys for a day which is not today, then move on to fetch keys for the next date.
                        requestParams.Date        = requestParams.Date.AddDays(1);
                        requestParams.BatchNumber = 1;
                        lastPull = false;
                    }
                    else
                    {
                        //There were no new keys to fetch for today
                        _developerTools.AddToPullHistoryRecord($"204 No Content - No new keys", requestUrl);
                        string warning = $"API {response.Endpoint} returned 204 No Content - No new keys since last pull";
                        LogUtils.LogMessage(LogSeverity.WARNING, $"{_logPrefix}.{nameof(DownloadZips)}: {warning}");
                        lastPull = true;
                    }
                }
                else
                {
                    try
                    {
                        int  lastBatchReceivedValue = int.Parse(headers.GetValues(LastBatchReturnedHeader).First());
                        bool moreBatchesExist       = bool.Parse(headers.GetValues(MoreBatchesExistHeader).First());

                        //If both headers parse (no exceptions), then save lastBatchValue to be persisted
                        lastBatchReceived = lastBatchReceivedValue;

                        if (moreBatchesExist)
                        {
                            //There are still more batches to fetch for the given date
                            requestParams.BatchNumber = (int)lastBatchReceived + 1;
                            lastPull = false;
                        }
                        else if (requestParams.Date.Date < SystemTime.Now().Date)
                        {
                            //If there were no new keys for a day which is not today, then move on to fetch keys for the next date.
                            requestParams.Date        = requestParams.Date.AddDays(1);
                            requestParams.BatchNumber = 1;
                            lastPull = false;
                        }
                        else
                        {
                            //There are no more batches to fetch for today. Try again in some hours.
                            lastPull = true;
                        }
                    }
                    catch (Exception e)
                    {
                        headersAreValid = false;
                        HandleErrorWhenPulling(e, $"Failed to parse {MoreBatchesExistHeader} or {LastBatchReturnedHeader} header.", requestUrl);
                        break; //Abort pulling
                    }
                }

                // Copy the zip stream in the response into a temp file
                if (response.StatusCode == 200 && headersAreValid)
                {
                    try
                    {
                        _developerTools.AddToPullHistoryRecord("200 OK", requestUrl);
                        string tmpFile = Path.Combine(ServiceLocator.Current.GetInstance <IFileSystem>().CacheDirectory, Guid.NewGuid() + ".zip");

                        FileStream tmpFileStream = File.Create(tmpFile);
                        await response.Data.CopyToAsync(tmpFileStream);

                        tmpFileStream.Close();

                        zipLocations.Add(tmpFile);
                    }
                    catch (Exception e)
                    {
                        HandleErrorWhenPulling(e, "Failed to save zip locally", requestUrl);
                        break; //Abort pulling
                    }
                }
            }

            if (zipLocations.Any() && lastBatchReceived != null)
            {
                //Persist the last batch that was fetched, to know which one to fetch next time the background task runs.
                LocalPreferencesHelper.LastPullKeysBatchNumberNotSubmitted = (int)lastBatchReceived;

                //Also save the last batchtype fetched
                LocalPreferencesHelper.LastPulledBatchType = requestParams.BatchType;
            }

            // Edge case for when pulling across multiple days ends up in 204 for the first file
            if (requestParams.Date.Date == SystemTime.Now().Date &&
                requestParams.BatchNumber == 1 &&
                lastReceivedStatusCodeFromRequest == 204)
            {
                LocalPreferencesHelper.DidFirstFileOfTheDayEndedWith204 = true;
            }

            return(zipLocations);
        }