Ejemplo n.º 1
0
        private static void SendMessageImpl(Person person, string subject, string message)
        {
            var mailMessage = new MailMessage
            {
                From       = new MailAddress(FirmaWebConfiguration.DoNotReplyEmail),
                Subject    = subject,
                Body       = message,
                IsBodyHtml = true
            };

            var tenantAttribute = MultiTenantHelpers.GetTenantAttributeFromCache();
            var toolLogo        = tenantAttribute.TenantSquareLogoFileResourceInfo ??
                                  tenantAttribute.TenantBannerLogoFileResourceInfo;
            var htmlView = AlternateView.CreateAlternateViewFromString(message, null, "text/html");

            htmlView.LinkedResources.Add(
                new LinkedResource(new MemoryStream(toolLogo.FileResourceData.Data), "img/jpeg")
            {
                ContentId = "tool-logo"
            });
            mailMessage.AlternateViews.Add(htmlView);

            // Reply-To Header
            mailMessage.ReplyToList.Add(person.Email);

            // TO field
            var supportPersons = HttpRequestStorage.DatabaseEntities.People.GetPeopleWhoReceiveSupportEmails();

            foreach (var supportPerson in supportPersons)
            {
                mailMessage.To.Add(supportPerson.Email);
            }

            SitkaSmtpClient.Send(mailMessage);
        }
        public static void SendMessage(SupportRequestLog supportRequestLog, string ipAddress, string userAgent, string currentUrl, SupportRequestType supportRequestType, DatabaseEntities databaseEntities, int defaultSupportPersonID)
        {
            var subject = $"Support Request for Project Firma - {DateTime.Now.ToStringDateTime()}";
            var message = $@"
<div style='font-size: 12px; font-family: Arial'>
    <strong>{subject}</strong><br />
    <br />
    <strong>From:</strong> {supportRequestLog.RequestPersonName} - {supportRequestLog.RequestPersonOrganization ?? "(not provided)"}<br />
    <strong>Email:</strong> {supportRequestLog.RequestPersonEmail}<br />
    <strong>Phone:</strong> {supportRequestLog.RequestPersonPhone ?? "(not provided)"}<br />
    <br />
    <strong>Subject:</strong> {supportRequestType.SupportRequestTypeDisplayName}<br />
    <br />
    <strong>Description:</strong><br />
    {supportRequestLog.RequestDescription.HtmlEncodeWithBreaks()}
    <br />
    <br />
    <br />
    <div style='font-size: 10px; color: gray'>
    OTHER DETAILS:<br />
    LOGIN: {(supportRequestLog.RequestPerson != null ? $"{supportRequestLog.RequestPerson.GetFullNameFirstLast()} (UserID {supportRequestLog.RequestPerson.PersonID})" : "(anonymous user)")}<br />
    IP ADDRESS: {ipAddress}<br />
    USERAGENT: {userAgent}<br />
    URL FROM: {currentUrl}<br />
    <br />
    </div>
    <div>You received this email because you are set up as a point of contact for support - if that's not correct, let us know: {FirmaWebConfiguration.SitkaSupportEmail}.</div>
    <br/><br/><img src=""cid:tool-logo"" width=""160"" />
</div>
";
            // Create Notification
            var mailMessage = new MailMessage {
                From = new MailAddress(FirmaWebConfiguration.DoNotReplyEmail), Subject = subject, Body = message, IsBodyHtml = true
            };

            var tenantAttribute = MultiTenantHelpers.GetTenantAttributeFromCache();
            var toolLogo        = tenantAttribute.TenantSquareLogoFileResourceInfo ??
                                  tenantAttribute.TenantBannerLogoFileResourceInfo;
            var htmlView = AlternateView.CreateAlternateViewFromString(message, null, "text/html");

            htmlView.LinkedResources.Add(
                new LinkedResource(new MemoryStream(toolLogo.FileResourceData.Data), "img/jpeg")
            {
                ContentId = "tool-logo"
            });
            mailMessage.AlternateViews.Add(htmlView);

            // Reply-To Header
            mailMessage.ReplyToList.Add(supportRequestLog.RequestPersonEmail);

            // TO field
            SupportRequestTypeModelExtensions.SetEmailRecipientsOfSupportRequest(databaseEntities, mailMessage, defaultSupportPersonID);

            SitkaSmtpClient.Send(mailMessage);
        }
Ejemplo n.º 3
0
        public void SendMessage(string ipAddress, string userAgent, string currentUrl, SupportRequestType supportRequestType)
        {
            var subject = $"Support Request for Neptune - {DateTime.Now.ToStringDateTime()}";
            var message = string.Format(@"
<div style='font-size: 12px; font-family: Arial'>
    <strong>{0}</strong><br />
    <br />
    <strong>From:</strong> {1} - {2}<br />
    <strong>Email:</strong> {3}<br />
    <strong>Phone:</strong> {4}<br />
    <br />
    <strong>Subject:</strong> {5}<br />
    <br />
    <strong>Description:</strong><br />
    {6}
    <br />
    <br />
    <br />
    <div style='font-size: 10px; color: gray'>
    OTHER DETAILS:<br />
    LOGIN: {7}<br />
    IP ADDRESS: {8}<br />
    USERAGENT: {9}<br />
    URL FROM: {10}<br />
    <br />
    </div>
    <div>You received this email because you are set up as a point of contact for support - if that's not correct, let us know: {11}</div>.
</div>
",
                                        subject,
                                        RequestPersonName,
                                        RequestPersonOrganization ?? "(not provided)",
                                        RequestPersonEmail,
                                        RequestPersonPhone ?? "(not provided)",
                                        supportRequestType.SupportRequestTypeDisplayName,
                                        RequestDescription.HtmlEncodeWithBreaks(),
                                        RequestPerson != null ? $"{RequestPerson.GetFullNameFirstLast()} (UserID {RequestPerson.PersonID})" : "(anonymous user)",
                                        ipAddress,
                                        userAgent,
                                        currentUrl,
                                        Common.NeptuneWebConfiguration.SitkaSupportEmail);
            // Create Notification
            var mailMessage = new MailMessage {
                From = new MailAddress(Common.NeptuneWebConfiguration.DoNotReplyEmail), Subject = subject, Body = message, IsBodyHtml = true
            };

            // Reply-To Header
            mailMessage.ReplyToList.Add(RequestPersonEmail);

            // TO field
            SupportRequestType.SetEmailRecipientsOfSupportRequest(mailMessage);

            SitkaSmtpClient.Send(mailMessage);
        }
Ejemplo n.º 4
0
        private static void SendExistingKeystoneUserCreatedMessage(Person person, Person currentPerson)
        {
            var toolDisplayName = MultiTenantHelpers.GetToolDisplayName();
            var subject         = $"Invitation to {toolDisplayName}";
            var message         = $@"
<div style='font-size: 12px; font-family: Arial'>
    Welcome {person.FirstName},
    <p>
    You have been invited by a colleague, {currentPerson.GetFullNameFirstLast()}, to check out <a href=""{SitkaRoute<HomeController>.BuildAbsoluteUrlHttpsFromExpression(x => x.Index())}\"">{toolDisplayName}</a>.
</p>
    <p>
    Because you have logged into other systems that use the same log in service (Keystone) that {toolDisplayName} uses, you already have an account, but it needs to be activated for {toolDisplayName}.
    </p>
    <p>
    When you have a moment, please activate your account by logging in:
    </p>
    <strong>Log in here:</strong>  <a href=""{FirmaHelpers.GenerateAbsoluteLogInUrl()}"">{toolDisplayName}</a><br />
    <strong>Your user name is:</strong> {person.LoginName}<br />
    <p>
    If you don't remember your password, you will be able to reset it from the link above.
    </p>
    <p>
    Sincerely,<br />
    The {toolDisplayName} team<br/><br/><img src=""cid:tool-logo"" width=""160"" />
    </p>";
            var mailMessage     = new MailMessage
            {
                From       = new MailAddress(FirmaWebConfiguration.DoNotReplyEmail),
                Subject    = subject,
                Body       = message,
                IsBodyHtml = true
            };

            var tenantAttribute = MultiTenantHelpers.GetTenantAttributeFromCache();
            var toolLogo        = tenantAttribute.TenantSquareLogoFileResourceInfo ??
                                  tenantAttribute.TenantBannerLogoFileResourceInfo;
            var htmlView = AlternateView.CreateAlternateViewFromString(message, null, "text/html");

            htmlView.LinkedResources.Add(
                new LinkedResource(new MemoryStream(toolLogo.FileResourceData.Data), "img/jpeg")
            {
                ContentId = "tool-logo"
            });
            mailMessage.AlternateViews.Add(htmlView);

            mailMessage.ReplyToList.Add(currentPerson.Email);
            mailMessage.To.Add(person.Email);
            SitkaSmtpClient.Send(mailMessage);
        }
Ejemplo n.º 5
0
 public static void SendMessage(MailMessage mailMessage, IEnumerable <string> emailsToSendTo, IEnumerable <string> emailsToReplyTo, IEnumerable <string> emailsToCc)
 {
     mailMessage.From = DoNotReplyMailAddress();
     foreach (var email in emailsToSendTo)
     {
         mailMessage.To.Add(email);
     }
     foreach (var email in emailsToReplyTo)
     {
         mailMessage.ReplyToList.Add(email);
     }
     foreach (var emailToCc in emailsToCc)
     {
         mailMessage.CC.Add(emailToCc);
     }
     SitkaSmtpClient.Send(mailMessage);
 }
        public static void SendMessage(SupportRequestLog supportRequestLog, string ipAddress, string userAgent, string currentUrl, SupportRequestType supportRequestType, DatabaseEntities databaseEntities, int defaultSupportPersonID)
        {
            var subject = $"Support Request for Project Firma - {DateTime.Now.ToStringDateTime()}";
            var message = $@"
<div style='font-size: 12px; font-family: Arial'>
    <strong>{subject}</strong><br />
    <br />
    <strong>From:</strong> {supportRequestLog.RequestPersonName} - {supportRequestLog.RequestPersonOrganization ?? "(not provided)"}<br />
    <strong>Email:</strong> {supportRequestLog.RequestPersonEmail}<br />
    <strong>Phone:</strong> {supportRequestLog.RequestPersonPhone ?? "(not provided)"}<br />
    <br />
    <strong>Subject:</strong> {supportRequestType.SupportRequestTypeDisplayName}<br />
    <br />
    <strong>Description:</strong><br />
    {supportRequestLog.RequestDescription.HtmlEncodeWithBreaks()}
    <br />
    <br />
    <br />
    <div style='font-size: 10px; color: gray'>
    OTHER DETAILS:<br />
    LOGIN: {(supportRequestLog.RequestPerson != null ? $"{supportRequestLog.RequestPerson.GetFullNameFirstLast()} (UserID {supportRequestLog.RequestPerson.PersonID})" : "(anonymous user)")}<br />
    IP ADDRESS: {ipAddress}<br />
    USERAGENT: {userAgent}<br />
    URL FROM: {currentUrl}<br />
    <br />
    </div>
    <div>You received this email because you are set up as a point of contact for support - if that's not correct, let us know: {FirmaWebConfiguration.SitkaSupportEmail}</div>.
</div>
";
            // Create Notification
            var mailMessage = new MailMessage {
                From = new MailAddress(FirmaWebConfiguration.DoNotReplyEmail), Subject = subject, Body = message, IsBodyHtml = true
            };

            // Reply-To Header
            mailMessage.ReplyToList.Add(supportRequestLog.RequestPersonEmail);

            // TO field
            SupportRequestTypeModelExtensions.SetEmailRecipientsOfSupportRequest(databaseEntities, mailMessage, defaultSupportPersonID);

            SitkaSmtpClient.Send(mailMessage);
        }
        private static void SendRSBRevisionRequestClosedEmail(Models.Person closingPerson,
                                                              Models.RegionalSubbasinRevisionRequest request)
        {
            var subject           = $"A Regional Subbasin Revision Request was closed";
            var firstName         = closingPerson.FirstName;
            var lastName          = closingPerson.LastName;
            var organizationName  = closingPerson.Organization.OrganizationName;
            var bmpName           = request.TreatmentBMP.TreatmentBMPName;
            var delineationMapUrl = request.TreatmentBMP.GetDelineationMapUrl();
            var message           = $@"
<div style='font-size: 12px; font-family: Arial'>
<strong>{subject}</strong><br />
<br />
The Regional Subbasin Revision Request for BMP {bmpName.Trim()} was just closed by {firstName} {lastName} ({organizationName}).
<br /><br />
The changes resulting from this update will be available for your use next Monday. At that time you will be able to revise the delineation for {bmpName.Trim()}.
<br /><br />
<a href='{delineationMapUrl}'>Revise the delineation for BMP {bmpName.Trim()} on the Delineation map</a>. 
<br/><br />
 <div>Thanks for keeping the Regional Subbasin Network up to date within the Orange County Stormwater Tools.</div>
</div>
";
            // Create Notification
            var mailMessage = new MailMessage
            {
                From       = new MailAddress(Common.NeptuneWebConfiguration.DoNotReplyEmail),
                Subject    = subject,
                Body       = message,
                IsBodyHtml = true
            };

            mailMessage.To.Add(request.RequestPerson.Email);

            foreach (var revisionRequestPeople in HttpRequestStorage.DatabaseEntities.People
                     .GetPeopleWhoReceiveRSBRevisionRequests())
            {
                mailMessage.CC.Add(revisionRequestPeople.Email);
            }

            SitkaSmtpClient.Send(mailMessage);
        }
        private static void SendRSBRevisionRequestSubmittedEmail(Models.Person requestPerson,
                                                                 Models.TreatmentBMP requestBMP, RegionalSubbasinRevisionRequest request)
        {
            var subject            = $"A new Regional Subbasin Revision Request was submitted";
            var firstName          = requestPerson.FirstName;
            var lastName           = requestPerson.LastName;
            var organizationName   = requestPerson.Organization.OrganizationName;
            var bmpName            = requestBMP.TreatmentBMPName;
            var requestDetails     = request.GetDetailUrl();
            var requestPersonEmail = requestPerson.Email;
            var message            = $@"
<div style='font-size: 12px; font-family: Arial'>
<strong>{subject}</strong><br />
<br />
A new Regional Subbasin Revision Request was just submitted by {firstName} {lastName} ({organizationName}) for BMP {bmpName}.
Please review it, make revisions, and close it at your earliest convenience. <a href='{requestDetails}'>View this Request</a>

<div>You received this email because you are assigned to receive Regional Subbasin Revision Request notifications within the Orange County Stormwater Tools. </div>.
</div>
";
            // Create Notification
            var mailMessage = new MailMessage
            {
                From       = new MailAddress(Common.NeptuneWebConfiguration.DoNotReplyEmail),
                Subject    = subject,
                Body       = message,
                IsBodyHtml = true
            };

            mailMessage.CC.Add(requestPersonEmail);

            foreach (var revisionRequestPeople in HttpRequestStorage.DatabaseEntities.People
                     .GetPeopleWhoReceiveRSBRevisionRequests())
            {
                mailMessage.To.Add(revisionRequestPeople.Email);
            }

            SitkaSmtpClient.Send(mailMessage);
        }
Ejemplo n.º 9
0
        private static void SendMessageImpl(Person person, string subject, string message)
        {
            var mailMessage = new MailMessage
            {
                From       = new MailAddress(NeptuneWebConfiguration.DoNotReplyEmail),
                Subject    = subject,
                Body       = message,
                IsBodyHtml = true
            };

            // Reply-To Header
            mailMessage.ReplyToList.Add(person.Email);

            // TO field
            var supportPersons = HttpRequestStorage.DatabaseEntities.People.GetPeopleWhoReceiveSupportEmails();

            foreach (var supportPerson in supportPersons)
            {
                mailMessage.To.Add(supportPerson.Email);
            }

            SitkaSmtpClient.Send(mailMessage);
        }
Ejemplo n.º 10
0
        private static void SendExistingKeystoneUserCreatedMessage(Person person, Person currentPerson)
        {
            var toolDisplayName = MultiTenantHelpers.GetToolDisplayName();
            var subject         = $"Invitation to {toolDisplayName}";
            var message         = $@"
<div style='font-size: 12px; font-family: Arial'>
    Welcome {person.FirstName},
    <p>
    You have been invited by a colleague, {currentPerson.GetFullNameFirstLast()}, to check out <a href=""{SitkaRoute<HomeController>.BuildAbsoluteUrlHttpsFromExpression(x => x.Index())}\"">{toolDisplayName}</a>.
</p>
    <p>
    Because you have logged into other systems that use the same log in service (Keystone) that {toolDisplayName} uses, you already have an account, but it needs to be activated for {toolDisplayName}.
    </p>
    <p>
    When you have a moment, please activate your account by logging in:
    </p>
    <strong>Log in here:</strong>  <a href=""{FirmaHelpers.GenerateAbsoluteLogInUrl()}"">{toolDisplayName}</a><br />
    <strong>Your user name is:</strong> {person.LoginName}<br />
    <p>
    If you don't remember your password, you will be able to reset it from the link above.
    </p>
    <p>
    Sincerely,<br />
    The {toolDisplayName} team
    </p>";
            var mailMessage     = new MailMessage
            {
                From       = new MailAddress(FirmaWebConfiguration.DoNotReplyEmail),
                Subject    = subject,
                Body       = message,
                IsBodyHtml = true
            };

            mailMessage.ReplyToList.Add(currentPerson.Email);
            mailMessage.To.Add(person.Email);
            SitkaSmtpClient.Send(mailMessage);
        }
        protected override void RunJobImplementation()
        {
            var person = DbContext.People.Find(PersonID);

            if (person == null)
            {
                throw new InvalidOperationException("PersonID must be valid!");
            }
            try
            {
                var landUseBlockStagings    = person.LandUseBlockStagingsWhereYouAreTheUploadedByPerson;
                var stormwaterJurisdictions = DbContext.StormwaterJurisdictions.ToList();
                var stormwaterJurisdictionsPersonCanEdit =
                    person.GetStormwaterJurisdictionsPersonCanViewWithContext(DbContext).ToList();

                var allowedStormwaterJurisdictionNames = string.Join(", ",
                                                                     stormwaterJurisdictions.Select(x => x.Organization.OrganizationName).ToList());
                var allowedPermitTypeNames =
                    string.Join(", ", PermitType.All.Select(x => x.PermitTypeDisplayName).ToList());
                var allowedPriorityLandUseTypeNames = string.Join(", ",
                                                                  PriorityLandUseType.All.Select(x => x.PriorityLandUseTypeDisplayName).ToList());

                var count                 = 0;
                var errorList             = new List <string>();
                var landUseBlocksToUpload = new List <LandUseBlock>();

                foreach (var landUseBlockStaging in landUseBlockStagings)
                {
                    var landUseBlock = new LandUseBlock(default(int), default(int), string.Empty, default(DbGeometry),
                                                        default(decimal), string.Empty, default(decimal), default(decimal), default(int), default(int), default(DbGeometry));


                    var landUseBlockPLUType = landUseBlockStaging.PriorityLandUseType;
                    if (!PriorityLandUseType.All.Select(x => x.PriorityLandUseTypeDisplayName)
                        .Contains(landUseBlockPLUType))
                    {
                        errorList.Add(
                            $"The Priority Land Use Type '{landUseBlockPLUType}' at row {count} was not found. Acceptable values are {allowedPriorityLandUseTypeNames}");
                    }
                    else
                    {
                        landUseBlock.PriorityLandUseTypeID = PriorityLandUseType.All
                                                             .Single(x => x.PriorityLandUseTypeDisplayName == landUseBlockPLUType).PriorityLandUseTypeID;
                    }

                    landUseBlock.LandUseDescription = landUseBlockStaging.LandUseDescription;


                    landUseBlock.TrashGenerationRate = landUseBlockStaging.TrashGenerationRate;
                    landUseBlock.LandUseForTGR       = landUseBlockStaging.LandUseForTGR;

                    if (landUseBlockStaging.LandUseForTGR == "Residential")
                    {
                        landUseBlock.MedianHouseholdIncomeResidential = landUseBlockStaging.MedianHouseholdIncome;
                        landUseBlock.MedianHouseholdIncomeRetail      = 0;
                    }
                    else if (landUseBlockStaging.LandUseForTGR == "Retail")
                    {
                        landUseBlock.MedianHouseholdIncomeResidential = 0;
                        landUseBlock.MedianHouseholdIncomeRetail      = landUseBlockStaging.MedianHouseholdIncome;
                    }
                    else
                    {
                        landUseBlock.MedianHouseholdIncomeResidential = 0;
                        landUseBlock.MedianHouseholdIncomeRetail      = 0;
                    }

                    var stormwaterJurisdictionName = landUseBlockStaging.StormwaterJurisdiction;
                    if (string.IsNullOrEmpty(stormwaterJurisdictionName))
                    {
                        errorList.Add(
                            $"The Stormwater Jurisdiction at row {count} is null, empty or whitespace. A value must be provided");
                    }

                    if (!stormwaterJurisdictions.Select(x => x.Organization.OrganizationName)
                        .Contains(stormwaterJurisdictionName))
                    {
                        errorList.Add(
                            $"The Stormwater Jurisdiction '{stormwaterJurisdictionName}' at row {count} was not found. Acceptable values are {allowedStormwaterJurisdictionNames}");
                    }
                    else
                    {
                        var stormwaterJurisdictionToAssign = stormwaterJurisdictions
                                                             .Single(x => x.Organization.OrganizationName == landUseBlockStaging.StormwaterJurisdiction);
                        if (stormwaterJurisdictionsPersonCanEdit.Select(x => x.StormwaterJurisdictionID)
                            .Contains(stormwaterJurisdictionToAssign.StormwaterJurisdictionID))
                        {
                            landUseBlock.StormwaterJurisdictionID =
                                stormwaterJurisdictionToAssign.StormwaterJurisdictionID;
                            if (landUseBlockStaging.LandUseBlockStagingGeometry == null)
                            {
                                errorList.Add(
                                    $"The Land Use Block Geometry at row {count} is null. A value must be provided");
                            }
                            else
                            {
                                var clippedGeometry = landUseBlockStaging.LandUseBlockStagingGeometry.Intersection(
                                    stormwaterJurisdictionToAssign.StormwaterJurisdictionGeometry.GeometryNative);

                                landUseBlock.LandUseBlockGeometry     = clippedGeometry;
                                landUseBlock.LandUseBlockGeometry4326 =
                                    CoordinateSystemHelper.ProjectCaliforniaStatePlaneVIToWebMercator(clippedGeometry);

                                if (clippedGeometry.IsEmpty)
                                {
                                    errorList.Add(
                                        $"The Land Use Block Geometry at row {count} is not in the assigned Stormwater Jurisdiction. Please make sure Land Use Block is in {stormwaterJurisdictionToAssign.Organization.OrganizationName}.");
                                }
                            }
                        }
                        else
                        {
                            errorList.Add(
                                $"You do not have permission to edit Stormwater Jurisdiction {stormwaterJurisdictionToAssign.Organization.OrganizationName}. Please remove all features with this Stormwater Jurisdiction from the upload and try again.");
                        }
                    }



                    var permitType = landUseBlockStaging.PermitType;
                    if (string.IsNullOrEmpty(permitType))
                    {
                        errorList.Add(
                            $"The Permit Type at row {count} is null, empty or whitespace. A value must be provided");
                    }

                    if (!PermitType.All.Select(x => x.PermitTypeDisplayName).Contains(landUseBlockStaging.PermitType))
                    {
                        errorList.Add(
                            $"The Permit Type '{permitType}' at row {count} was not found. Acceptable values are {allowedPermitTypeNames}");
                    }
                    else
                    {
                        landUseBlock.PermitTypeID =
                            PermitType.All.Single(x => x.PermitTypeDisplayName == permitType).PermitTypeID;
                    }

                    landUseBlocksToUpload.Add(landUseBlock);
                    count++;
                }

                if (!errorList.Any())
                {
                    var stormwaterJurisdictionIDsToClear =
                        landUseBlocksToUpload.Select(x => x.StormwaterJurisdictionID).Distinct();
                    var stormwaterJurisdictionToClears = stormwaterJurisdictions
                                                         .Where(x => stormwaterJurisdictionIDsToClear.Contains(x.StormwaterJurisdictionID)).ToList();

                    //foreach (var stormwaterJurisdictionToClear in stormwaterJurisdictionToClears)
                    //{
                    //    var landUseBlocksToClear = stormwaterJurisdictionToClear.LandUseBlocks;
                    //    var trashGeneratingUnitsToUpdateLandUseBlockID = landUseBlocksToClear.SelectMany(x=>x.TrashGeneratingUnits);

                    //    foreach (var trashGeneratingUnit in trashGeneratingUnitsToUpdateLandUseBlockID)
                    //    {
                    //        trashGeneratingUnit.LandUseBlockID = null;
                    //    }
                    //    DbContext.SaveChanges(person);

                    //    DbContext.LandUseBlocks.DeleteLandUseBlock(landUseBlocksToClear);
                    //    DbContext.SaveChanges(person);

                    //}

                    // NP 6/25 SUPER gross to fire plain sql at the db, but trying to use the ORM as above results in exceeding any reasonable timeout
                    var landUseBlockIDsToClear = stormwaterJurisdictionToClears.SelectMany(x => x.LandUseBlocks)
                                                 .Select(x => x.LandUseBlockID).ToList();

                    if (landUseBlockIDsToClear.Any())
                    {
                        var landUseBlockIDsToClearCommaSeparatedString = string.Join(",", landUseBlockIDsToClear);

                        var nullOutTGULandUseBlockIDs =
                            $"UPDATE dbo.TrashGeneratingUnit SET LandUseBlockID = null WHERE LandUseBlockID in ({landUseBlockIDsToClearCommaSeparatedString})";

                        var nullOutTGU4326LandUseBlockIDs =
                            $"UPDATE dbo.TrashGeneratingUnit4326 SET LandUseBlockID = null WHERE LandUseBlockID in ({landUseBlockIDsToClearCommaSeparatedString})";
                        var deleteLandUseBlocks =
                            $"DELETE FROM dbo.LandUseBlock WHERE LandUseBlockID in ({landUseBlockIDsToClearCommaSeparatedString})";

                        DbContext.Database.CommandTimeout = 960;
                        DbContext.Database.ExecuteSqlCommand(nullOutTGULandUseBlockIDs);
                        DbContext.Database.ExecuteSqlCommand(nullOutTGU4326LandUseBlockIDs);
                        DbContext.Database.ExecuteSqlCommand(deleteLandUseBlocks);
                    }

                    DbContext.LandUseBlocks.AddRange(landUseBlocksToUpload);
                    DbContext.SaveChanges(person);

                    var body =
                        "Your Land Use Block Upload has been processed. The updated Land Use Blocks are now in the Orange County Stormwater Tools system. It may take up to 24 hours for updated Trash Results to appear in the system.";

                    var mailMessage = new MailMessage
                    {
                        Subject = "Land Use Block Upload Results",
                        Body    = body,
                        From    = DoNotReplyMailAddress()
                    };

                    mailMessage.To.Add(person.Email);
                    SitkaSmtpClient.Send(mailMessage);
                }
                else
                {
                    var body =
                        "Your Land Use Block upload had errors. Please review the following report, correct the errors, and try again: \n" +
                        string.Join("\n", errorList);

                    var mailMessage = new MailMessage
                    {
                        Subject = "Land Use Block Upload Error",
                        Body    = body,
                        From    = DoNotReplyMailAddress()
                    };

                    mailMessage.To.Add(person.Email);
                    SitkaSmtpClient.Send(mailMessage);
                }

                DbContext.pLandUseBlockStagingDeleteByPersonID(PersonID);
            }
            catch (Exception)
            {
                var body =
                    "There was an unexpected system error during processing of your Land Use Block Upload. The Orange County Stormwater Tools development team will investigate and be in touch when this issue is resolved.";

                var mailMessage = new MailMessage
                {
                    Subject = "Land Use Block Upload Error",
                    Body    = body,
                    From    = DoNotReplyMailAddress()
                };

                mailMessage.To.Add(person.Email);
                SitkaSmtpClient.Send(mailMessage);

                throw;
            }
        }