Skip to content

Commit 42e0aee

Browse files
committed
Major code reformatting and adding Sentry logging.
1 parent e090b61 commit 42e0aee

File tree

5 files changed

+292
-350
lines changed

5 files changed

+292
-350
lines changed

eFormAPI/Plugins/Workflow.Pn/Workflow.Pn/EformWorkflowPlugin.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2020

2121

2222
using System.Linq;
23+
using System.Runtime.InteropServices;
2324
using Amazon;
2425
using Amazon.S3;
2526
using Amazon.S3.Model;
@@ -32,6 +33,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3233
using Microting.eFormApi.BasePn.Infrastructure.Helpers.PluginDbOptions;
3334
using Microting.eFormWorkflowBase.Helpers;
3435
using QuestPDF.Infrastructure;
36+
using Sentry;
3537
using Workflow.Pn.Helpers;
3638

3739
namespace Workflow.Pn
@@ -100,6 +102,50 @@ public void ConfigureOptionsServices(IServiceCollection services, IConfiguration
100102

101103
public void ConfigureDbContext(IServiceCollection services, string connectionString)
102104
{
105+
SentrySdk.Init(options =>
106+
{
107+
// A Sentry Data Source Name (DSN) is required.
108+
// See https://docs.sentry.io/product/sentry-basics/dsn-explainer/
109+
// You can set it in the SENTRY_DSN environment variable, or you can set it in code here.
110+
options.Dsn = "https://80b935299e69fe24c21043140b62f2ab@o4506241219428352.ingest.us.sentry.io/4508266849501184";
111+
112+
// When debug is enabled, the Sentry client will emit detailed debugging information to the console.
113+
// This might be helpful, or might interfere with the normal operation of your application.
114+
// We enable it here for demonstration purposes when first trying Sentry.
115+
// You shouldn't do this in your applications unless you're troubleshooting issues with Sentry.
116+
options.Debug = false;
117+
118+
// This option is recommended. It enables Sentry's "Release Health" feature.
119+
options.AutoSessionTracking = true;
120+
121+
// This option is recommended for client applications only. It ensures all threads use the same global scope.
122+
// If you're writing a background service of any kind, you should remove this.
123+
options.IsGlobalModeEnabled = true;
124+
125+
// This option will enable Sentry's tracing features. You still need to start transactions and spans.
126+
options.EnableTracing = true;
127+
});
128+
129+
string pattern = @"Database=(\d+)_eform-angular-workflow-plugin;";
130+
Match match = Regex.Match(connectionString!, pattern);
131+
132+
if (match.Success)
133+
{
134+
string numberString = match.Groups[1].Value;
135+
int number = int.Parse(numberString);
136+
SentrySdk.ConfigureScope(scope =>
137+
{
138+
scope.SetTag("customerNo", number.ToString());
139+
Console.WriteLine("customerNo: " + number);
140+
scope.SetTag("osVersion", Environment.OSVersion.ToString());
141+
Console.WriteLine("osVersion: " + Environment.OSVersion);
142+
scope.SetTag("osArchitecture", RuntimeInformation.OSArchitecture.ToString());
143+
Console.WriteLine("osArchitecture: " + RuntimeInformation.OSArchitecture);
144+
scope.SetTag("osName", RuntimeInformation.OSDescription);
145+
Console.WriteLine("osName: " + RuntimeInformation.OSDescription);
146+
});
147+
}
148+
103149
_connectionString = connectionString;
104150
services.AddDbContext<WorkflowPnDbContext>(o => o.UseMySql(connectionString, new MariaDbServerVersion(
105151
new Version(10, 4, 0)), mySqlOptionsAction: builder =>

eFormAPI/Plugins/Workflow.Pn/Workflow.Pn/Services/WorkflowCasesService/WorkflowCasesService.cs

Lines changed: 33 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2525
using DocumentFormat.OpenXml.Packaging;
2626
using eFormCore;
2727
using ImageMagick;
28+
using Microsoft.Extensions.Logging;
2829
using Microting.eForm.Dto;
2930
using Microting.eForm.Helpers;
3031
using Microting.eForm.Infrastructure.Models;
@@ -35,6 +36,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3536
using QuestPDF.Fluent;
3637
using SendGrid;
3738
using SendGrid.Helpers.Mail;
39+
using Sentry;
3840
using Workflow.Pn.Helpers;
3941
using Workflow.Pn.Infrastructure.Helpers;
4042
using Cell = DocumentFormat.OpenXml.Spreadsheet.Cell;
@@ -75,6 +77,7 @@ public class WorkflowCasesService(
7577
WorkflowPnDbContext workflowPnDbContext,
7678
IWorkflowLocalizationService workflowLocalizationService,
7779
IPluginDbOptions<WorkflowBaseSettings> options,
80+
ILogger<WorkflowCasesService> logger,
7881
BaseDbContext _baseDbContext)
7982
: IWorkflowCasesService
8083
{
@@ -363,16 +366,17 @@ public async Task<OperationResult> UpdateWorkflowCase(WorkflowCasesUpdateModel m
363366
workflowCase.UpdatedByUserId = userService.UserId;
364367
workflowCase.Deadline = string.IsNullOrEmpty(model.Deadline) ? null : DateTime.Parse(model.Deadline);
365368
workflowCase.IncidentPlace = model.IncidentPlace;
366-
if (model.IncidentPlaceId != null) workflowCase.IncidentPlaceId = (int)model.IncidentPlaceId;
369+
if (model.IncidentPlaceId != null)
370+
{
371+
workflowCase.IncidentPlaceId = (int)model.IncidentPlaceId;
372+
}
373+
367374
workflowCase.IncidentType = model.IncidentType;
368-
if (model.IncidentTypeId != null) workflowCase.IncidentTypeId = (int)model.IncidentTypeId;
369-
//if(model.IncidentPlace.HasValue)
370-
// {
371-
// workflowCase.IncidentPlace = await sdkDbContext.FieldOptionTranslations
372-
// .Where(x => x.Id == model.IncidentPlace)
373-
// .Select(x => x.Text)
374-
// .FirstAsync();
375-
// }
375+
if (model.IncidentTypeId != null)
376+
{
377+
workflowCase.IncidentTypeId = (int)model.IncidentTypeId;
378+
}
379+
376380
workflowCase.ActionPlan = model.ActionPlan;
377381
workflowCase.Description = model.Description;
378382
workflowCase.DateOfIncident = DateTime.Parse(model.DateOfIncident);
@@ -392,7 +396,7 @@ public async Task<OperationResult> UpdateWorkflowCase(WorkflowCasesUpdateModel m
392396
Site site = await sdkDbContext.Sites
393397
.Where(x => x.WorkflowState != Constants.WorkflowStates.Removed)
394398
.SingleOrDefaultAsync(x =>
395-
x.Name == workflowCase.SolvedBy);
399+
x.Name == workflowCase.SolvedBy);
396400

397401
if (workflowCase.SolvedBy != createdBySite.Name)
398402
{
@@ -423,14 +427,15 @@ public async Task<OperationResult> UpdateWorkflowCase(WorkflowCasesUpdateModel m
423427
case false when statusClosed:
424428
{
425429
Case _case = await
426-
sdkDbContext.Cases.SingleOrDefaultAsync(x => x.MicrotingCheckUid == workflowCase.CheckMicrotingUid);
430+
sdkDbContext.Cases.SingleOrDefaultAsync(x =>
431+
x.MicrotingCheckUid == workflowCase.CheckMicrotingUid);
427432
Site createdBySite = await sdkDbContext.Sites.SingleOrDefaultAsync(x => x.Id == _case.SiteId);
428433
if (!string.IsNullOrEmpty(workflowCase.SolvedBy))
429434
{
430435
Site site = await sdkDbContext.Sites
431436
.Where(x => x.WorkflowState != Constants.WorkflowStates.Removed)
432437
.SingleOrDefaultAsync(x =>
433-
x.Name == workflowCase.SolvedBy);
438+
x.Name == workflowCase.SolvedBy);
434439

435440
if (workflowCase.SolvedBy != createdBySite.Name)
436441
{
@@ -456,39 +461,6 @@ public async Task<OperationResult> UpdateWorkflowCase(WorkflowCasesUpdateModel m
456461
workflowLocalizationService.GetString("DeadlineIsMissing"));
457462
}
458463

459-
// Docx and PDF files
460-
// string timeStamp = DateTime.UtcNow.ToString("yyyyMMdd") + "_" +
461-
// DateTime.UtcNow.ToString("hhmmss");
462-
// string downloadPath = Path.Combine(Path.GetTempPath(), "pdf");
463-
// string docxFileName = $"{timeStamp}{model.ToBeSolvedById}_temp.docx";
464-
// string tempPDFFileName = $"{timeStamp}{model.ToBeSolvedById}_temp.pdf";
465-
// string tempPDFFilePath = Path.Combine(downloadPath, tempPDFFileName);
466-
467-
// var resourceString = "Workflow.Pn.Resources.Templates.page.html";
468-
// var assembly = Assembly.GetExecutingAssembly();
469-
// string html;
470-
// await using (var resourceStream = assembly.GetManifestResourceStream(resourceString))
471-
// {
472-
// using var reader = new StreamReader(resourceStream ??
473-
// throw new InvalidOperationException(
474-
// $"{nameof(resourceStream)} is null"));
475-
// html = await reader.ReadToEndAsync();
476-
// }
477-
//
478-
// // Read docx stream
479-
// resourceString = "Workflow.Pn.Resources.Templates.file.docx";
480-
// var docxFileResourceStream = assembly.GetManifestResourceStream(resourceString);
481-
// if (docxFileResourceStream == null)
482-
// {
483-
// throw new InvalidOperationException($"{nameof(docxFileResourceStream)} is null");
484-
// }
485-
//
486-
// var docxFileStream = new MemoryStream();
487-
// await docxFileResourceStream.CopyToAsync(docxFileStream);
488-
// await docxFileResourceStream.DisposeAsync();
489-
// string basePicturePath = Path.Combine(Path.GetTempPath(), "pictures");
490-
// var word = new WordProcessor(docxFileStream);
491-
// string imagesHtml = "";
492464
var picturesOfTasks = new List<string>();
493465

494466
var pictures =
@@ -502,50 +474,6 @@ await workflowPnDbContext.PicturesOfTasks.Where(x =>
502474

503475
var hash = await GeneratePdf(picturesOfTasks, (int)model.ToBeSolvedById);
504476

505-
// foreach (var imagesName in picturesOfTasks)
506-
// {
507-
// Console.WriteLine($"Trying to insert image into document : {imagesName}");
508-
// try
509-
// {
510-
// imagesHtml = await InsertImage(core, imagesName, imagesHtml, 700, 650,
511-
// basePicturePath);
512-
// }
513-
// catch (Exception ex)
514-
// {
515-
// Console.WriteLine(ex.Message);
516-
// }
517-
// }
518-
//
519-
// html = html.Replace("{%Content%}", imagesHtml);
520-
//
521-
// word.AddHtml(html);
522-
// word.Dispose();
523-
// docxFileStream.Position = 0;
524-
//
525-
// // Build docx
526-
// await using (var docxFile = new FileStream(docxFileName, FileMode.Create, FileAccess.Write))
527-
// {
528-
// docxFileStream.WriteTo(docxFile);
529-
// }
530-
//
531-
// // Convert to PDF
532-
// ReportHelper.ConvertToPdf(docxFileName, downloadPath);
533-
// File.Delete(docxFileName);
534-
//
535-
// // Upload PDF
536-
// // string pdfFileName = null;
537-
// string hash = await core.PdfUpload(tempPDFFilePath);
538-
// if (hash != null)
539-
// {
540-
// //rename local file
541-
// FileInfo fileInfo = new FileInfo(tempPDFFilePath);
542-
// fileInfo.CopyTo(downloadPath + hash + ".pdf", true);
543-
// fileInfo.Delete();
544-
// await core.PutFileToStorageSystem(Path.Combine(downloadPath, $"{hash}.pdf"), $"{hash}.pdf");
545-
//
546-
// // TODO Remove from file storage?
547-
// }
548-
549477
// eform is deployed to solver device user
550478
Folder folder =
551479
await sdkDbContext.Folders.SingleOrDefaultAsync(x =>
@@ -614,8 +542,9 @@ await sdkDbContext.Folders.SingleOrDefaultAsync(x =>
614542
}
615543
catch (Exception ex)
616544
{
617-
Log.LogException(ex.Message);
618-
Log.LogException(ex.StackTrace);
545+
SentrySdk.CaptureException(ex);
546+
logger.LogError(ex.Message);
547+
logger.LogTrace(ex.StackTrace);
619548
return new OperationResult(false,
620549
$"{workflowLocalizationService.GetString("CaseCouldNotBeUpdated")} Exception: {ex.Message}");
621550
}
@@ -649,6 +578,7 @@ private async Task<string> GeneratePdf(List<string> picturesOfTasks, int sitId)
649578
{
650579
x.Item().PageBreak();
651580
}
581+
652582
i++;
653583
}
654584
});
@@ -712,8 +642,9 @@ public async Task<OperationDataResult<List<WorkflowPlacesModel>>> GetPlaces()
712642
}
713643
catch (Exception ex)
714644
{
715-
Log.LogException(ex.Message);
716-
Log.LogException(ex.StackTrace);
645+
SentrySdk.CaptureException(ex);
646+
logger.LogError(ex.Message);
647+
logger.LogTrace(ex.StackTrace);
717648
return new OperationDataResult<List<WorkflowPlacesModel>>(false,
718649
$"{workflowLocalizationService.GetString("ErrorWhileGetPlaces")} Exception: {ex.Message}");
719650
}
@@ -895,24 +826,6 @@ private async Task<string> InsertImage(Core core, string imageName, string items
895826

896827
using (var image = new MagickImage(stream))
897828
{
898-
// var profile = image.GetExifProfile();
899-
// // Write all values to the console
900-
// foreach (var value in profile.Values)
901-
// {
902-
// Console.WriteLine("{0}({1}): {2}", value.Tag, value.DataType, value.ToString());
903-
// }
904-
905-
//image.AutoOrient();
906-
// decimal currentRation = image.Height / (decimal)image.Width;
907-
// int newWidth = imageSize;
908-
// int newHeight = (int)Math.Round((currentRation * newWidth));
909-
//
910-
// image.Resize(newWidth, newHeight);
911-
// image.Crop(newWidth, newHeight);
912-
// if (newWidth > newHeight)
913-
// {
914-
// image.Rotate(90);
915-
// }
916829
var base64String = image.ToBase64();
917830
itemsHtml +=
918831
$@"<p><img src=""data:image/png;base64,{base64String}"" width=""{imageWidth}px"" alt="""" /></p>";
@@ -969,6 +882,7 @@ private async Task SendFileAsync(
969882
}
970883
catch (Exception ex)
971884
{
885+
SentrySdk.CaptureException(ex);
972886
throw new Exception("Failed to send email message", ex);
973887
}
974888
finally
@@ -979,10 +893,12 @@ private async Task SendFileAsync(
979893

980894
public async Task GenerateReportAndSendEmail(int languageId, string userName, WorkflowCase workflowCase)
981895
{
982-
var emailRecipient = await _baseDbContext.EmailRecipients.SingleOrDefaultAsync(x => x.Name.Replace(" ", "") == userName
983-
.Replace("Mobil", "")
984-
.Replace("Tablet", ""));
985-
WorkflowReportHelper _workflowReportHelper = new WorkflowReportHelper(await coreHelper.GetCore(), workflowPnDbContext);
896+
var emailRecipient = await _baseDbContext.EmailRecipients.SingleOrDefaultAsync(x => x.Name.Replace(" ", "") ==
897+
userName
898+
.Replace("Mobil", "")
899+
.Replace("Tablet", ""));
900+
WorkflowReportHelper _workflowReportHelper =
901+
new WorkflowReportHelper(await coreHelper.GetCore(), workflowPnDbContext);
986902
var filePath = await _workflowReportHelper.GenerateReportAnd(languageId, workflowCase, "pdf");
987903
var assembly = Assembly.GetExecutingAssembly();
988904
var assemblyName = assembly.GetName().Name;
@@ -993,10 +909,12 @@ public async Task GenerateReportAndSendEmail(int languageId, string userName, Wo
993909
{
994910
throw new InvalidOperationException("Resource not found");
995911
}
912+
996913
using (var reader = new StreamReader(stream, Encoding.UTF8))
997914
{
998915
html = await reader.ReadToEndAsync();
999916
}
917+
1000918
html = html
1001919
.Replace(
1002920
"<a href=\"{{link}}\">Link til sag</a>", "")

eFormAPI/Plugins/Workflow.Pn/Workflow.Pn/Services/WorkflowLocalizationService/WorkflowLocalizationService.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,11 @@ namespace Workflow.Pn.Services.WorkflowLocalizationService
2727
using Microsoft.Extensions.Localization;
2828
using Microting.eFormApi.BasePn.Localization.Abstractions;
2929

30-
public class WorkflowLocalizationService : IWorkflowLocalizationService
30+
public class WorkflowLocalizationService(IEformLocalizerFactory factory) : IWorkflowLocalizationService
3131
{
32-
private readonly IStringLocalizer _localizer;
32+
private readonly IStringLocalizer _localizer = factory.Create(typeof(EformWorkflowPlugin));
3333

3434
// ReSharper disable once SuggestBaseTypeForParameter
35-
public WorkflowLocalizationService(IEformLocalizerFactory factory)
36-
{
37-
_localizer = factory.Create(typeof(EformWorkflowPlugin));
38-
}
3935

4036
public string GetString(string key)
4137
{

0 commit comments

Comments
 (0)