public async Task <Incidence> AddOrUpdate(SafetyIncidenceDto resourceParameter)
        {
            if (resourceParameter == null)
            {
                throw new ArgumentNullException("resourceParameter cannot be null.");
            }

            var injuryStatus = await _context.InjuryStats
                               .AsNoTracking()
                               .FirstOrDefaultAsync(x => x.InjuryStat1 == resourceParameter.InjuryStatId)
                               .ConfigureAwait(false);

            var injuryStatusName = injuryStatus?.InjuryStat1 ?? "";

            var isClosed  = resourceParameter?.IsClosed ?? false;
            var hasFmTips = !resourceParameter?.IsFmTipsCompleted ?? false;

            if (injuryStatusName.ToLower().Contains("recordable") && isClosed && hasFmTips)
            {
                throw new OperationCanceledException(
                          "FM Tips must be completed first before changing status to close."
                          );
            }

            var data = _mapper.Map <Incidence>(resourceParameter);

            await using var transaction = await _context.Database
                                          .BeginTransactionAsync()
                                          .ConfigureAwait(false);

            try
            {
                var isRecordable =
                    resourceParameter.Id > 0 &&
                    await IsRecordable(resourceParameter.Id).ConfigureAwait(false);

                var entity = _context.Incidences.Update(data);
                await _context.SaveChangesAsync().ConfigureAwait(false);

                await transaction.CommitAsync().ConfigureAwait(false);

                if (isRecordable && resourceParameter.Id > 0)
                {
                    await SendRecordableEmail(entity.Entity).ConfigureAwait(false);
                }

                return(entity.Entity);
            }
            catch (Exception e)
            {
                await transaction.RollbackAsync().ConfigureAwait(false);

                throw new Exception(e.Message);
            }
        }
        public async Task <IActionResult> AddIncident([FromForm] IncidentResourceParameter parameter)
        {
            var baseDir = Path.Combine(Path.GetTempPath(), "Incidents");

            if (!Directory.Exists(baseDir))
            {
                Directory.CreateDirectory(baseDir);
            }

            var incidentId = -1;

            try
            {
                var incident = await _context.Incidences.AddAsync(new Incidence
                {
                    Dept                  = parameter.Dept,
                    Shift                 = parameter.Shift,
                    Fname                 = parameter.Fname,
                    Lname                 = parameter.LName,
                    AccidentDate          = parameter.AccidentDate,
                    InjuryId              = parameter.InjuryID,
                    BodyPartId            = parameter.BodyPartID,
                    InjuryStatId          = parameter.InjuryStatID,
                    Supervisor            = parameter.Supervisor,
                    Description           = parameter.Description,
                    InterimActionTaken    = parameter.InterimActionTaken,
                    FinalCorrectiveAction = parameter.FinalCorrectiveAction,
                    Modifieddate          = DateTime.Now
                }).ConfigureAwait(false);

                await _context.SaveChangesAsync().ConfigureAwait(false);

                incidentId = incident.Entity.Id;

                // add attachments
                var emailAttachments = new List <System.Net.Mail.Attachment>();


                if (parameter.Files.Count > 0)
                {
                    var attachments = new List <Attachment>();
                    foreach (var file in parameter.Files)
                    {
                        await using var memoryStream = new MemoryStream();
                        await file.CopyToAsync(memoryStream).ConfigureAwait(false);

                        attachments.Add(new Attachment
                        {
                            Filename     = file.FileName,
                            ContentType  = file.ContentType,
                            Data         = memoryStream.ToArray(),
                            Incidentid   = incident.Entity.Id,
                            Modifieddate = DateTime.Now
                        });

                        // create temp file
                        var fileName = Path.GetFileNameWithoutExtension(file.FileName);
                        var ext      = Path.GetExtension(file.FileName);

                        var newFileName =
                            $"{fileName}_{incident.Entity.Id}_{Guid.NewGuid().ToString().ToUpper().Replace("-", "")}{ext}";
                        var path = Path.Combine(baseDir, newFileName);
                        await using var fileStream = new FileStream(path, FileMode.Create);
                        await file.CopyToAsync(fileStream).ConfigureAwait(false);

                        await fileStream.DisposeAsync();

                        fileStream.Close();

                        emailAttachments.Add(new System.Net.Mail.Attachment(path));
                    }

                    await _context.Attachments.AddRangeAsync(attachments);

                    await _context.SaveChangesAsync().ConfigureAwait(false);
                }

                //send email
                var recipients = await _context
                                 .EmailsNotiRecipients
                                 .Select(x => x.Email).ToListAsync();

#if DEBUG
                recipients = new List <string> {
                    "*****@*****.**"
                };
#endif

                var sb     = new StringBuilder();
                var entity = await _context.Incidences
                             .Include(x => x.Injury)
                             .Include(x => x.BodyPart)
                             .Include(x => x.DeptNavigation)
                             .Include(x => x.InjuryStat)
                             .FirstOrDefaultAsync(x => x.Id == incident.Entity.Id);

                sb.AppendFormat(
                    $"<h1><a href='http://10.129.224.149/FMSB/Safety/Print/PrintIncident.aspx?id={entity.Id}'>Safety Incident Report</a></h1>");
                sb.AppendFormat($"<p><b>Department: </b> {entity.Dept} </p>");
                sb.AppendFormat($"<p><b>Employee Name: </b> {entity.Lname}, {incident.Entity.Fname} </p>");
                sb.AppendFormat($"<p><b>Shift: </b> {entity.Shift} </p>");
                sb.AppendFormat($"<p><b>Incident Date: </b> {entity.AccidentDate} </p>");
                sb.AppendFormat($"<p><b>Injury Type: </b> {entity.Injury?.InjuryName} </p>");
                sb.AppendFormat($"<p><b>Body Type: </b> {entity.BodyPart?.BodyPart1} </p>");
                sb.AppendFormat($"<p><b>Supervisor: </b> {entity.Supervisor} </p>");
                sb.AppendFormat($"<p><b>Injury Status: </b> {entity.InjuryStatId} </p>");
                sb.AppendFormat($"<p><b>Description: </b> {entity.Description} </p>");
                sb.AppendFormat($"<p><b>Interim Action Taken: </b> {entity.InterimActionTaken} </p>");
                sb.AppendFormat($"<p><b>Final Corrective Action: </b> {entity.FinalCorrectiveAction} </p>");
                sb.AppendFormat($"</div>");

                var smtpAddress = "smtp.tenneco.com";

#if DEBUG
                smtpAddress = "smtp.federalmogul.com";
#endif

                const int port = 25;

                using var smtp = new SmtpClient(smtpAddress, port);
                var from = "*****@*****.**";
                var mm   = new MailMessage(from, string.Join(",", recipients))
                {
                    Subject    = "Incident Report",
                    Body       = sb.ToString(),
                    IsBodyHtml = true
                };

                mm.From = new MailAddress(from, "Safety Incident Report");

                mm.Attachments.AddRange(emailAttachments);
                await smtp.SendMailAsync(mm);

                mm.Attachments.Clear();
                mm.Attachments.Dispose();

                mm.Attachments.ForEach(a => { a.Dispose(); });

                smtp.Dispose();
                return(Ok(incident.Entity));
            }
            catch (Exception e)
            {
                return(BadRequest(e.Message));
            }
            finally
            {
                //todo: delete attachments files in temp
            }
        }