private async Task CheckAccount(Guid resultId, UploadResult summaryUpdate, UploadCsvRecord record)
        {
            var existingAccount = await _dbContext.GetAccount(record.AccountId);

            if (existingAccount == null)
            {
                summaryUpdate.ReadingsFailed++;
                await _dbContext.AddMessages(resultId, new[]
                {
                    new  Message {
                        RowNumber = record.RowNumber, AccountId = record.AccountId
                    }
                });
            }
            else
            {
                // check for unique data
                var row = _dbContext.MeterReads.Where(x => (x.AccountId == record.AccountId &&
                                                            (x.ReadingDateTime == record.MeterReadingDateTime)) &&
                                                      (x.Reading == record.MeterRead)).FirstOrDefault();
                if (row != null)
                {
                    summaryUpdate.ReadingsFailed++;
                }
                else
                {
                    await AddUsage(resultId, record, existingAccount);

                    summaryUpdate.ReadingsStored++;
                }
            }
        }
        private async Task ProcessRow(Guid resultId, UploadResult summaryUpdate, UploadCsvRecord record)
        {
            var validation = _validator.Validate(record);

            if (!validation.IsValid)
            {
                summaryUpdate.ReadingsFailed++;

                await _dbContext.AddMessages(resultId, validation.Messages.Select(t => new Message {
                    RowNumber = record.RowNumber, Content = t
                }));
            }
            else
            {
                await CheckAccount(resultId, summaryUpdate, record);
            }
        }
        public ValidationResult Validate(UploadCsvRecord record)
        {
            var messages = new List <string>();

            if (record.AccountId < 0 || record.AccountId > 9999)
            {
                messages.Add("Invalid account identifier");
            }
            if (!(record.MeterReadValue?.Length == 5 && record.MeterReadValue.All(char.IsDigit)))
            {
                messages.Add($"Invalid meter read value {record.MeterReadValue}");
            }
            if (record.MeterReadingDateTime > DateTimeOffset.Now)
            {
                messages.Add($"Meter read date {record.MeterReadingDateTime} is in the future");
            }
            return(new ValidationResult
            {
                IsValid = messages.Count == 0,
                Messages = messages
            });
        }
 private async Task AddUsage(Guid resultId, UploadCsvRecord record, Account existingAccount)
 {
     try
     {
         await _dbContext.AddUsage(existingAccount.AccountId,
                                   new MeterRead
         {
             Reading         = record.MeterRead,
             ReadingDateTime = record.MeterReadingDateTime
         }, resultId);
     }
     //  PK violation
     catch (InvalidOperationException)
     {
         await _dbContext.AddMessages(resultId, new[]
         {
             new Message
             {
                 RowNumber   = record.RowNumber, AccountId = record.AccountId,
                 ReadingDate = record.MeterReadingDateTime
             }
         });
     }
 }