Procházet zdrojové kódy

Minor changes to report look and report generator logic.

Added logic for sending email using Mailkit library.
master
NikolaJovanovic před 3 roky
rodič
revize
f1bb84c4c6

+ 1
- 0
BlackRockReportFunction/BlackRockReportFunction.csproj Zobrazit soubor

@@ -11,6 +11,7 @@
<PackageReference Include="Azure.Storage.Blobs" Version="12.12.0" />
<PackageReference Include="Azure.Storage.Queues" Version="12.10.0" />
<PackageReference Include="GemBox.Spreadsheet" Version="37.3.30.1110" />
<PackageReference Include="MailKit" Version="3.3.0" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />

+ 66
- 28
BlackRockReportFunction/Bussines/ReportGenerator.cs Zobrazit soubor

@@ -6,7 +6,10 @@ namespace BlackRockReportFunction.Bussines
{
internal class ReportGenerator
{
public static async Task<ExcelFile> GenerateReportContent()
public const string DefaultFontName = "Calibri";
public const int DefaultFontSize = 20;

public static ExcelFile GenerateReportContent()
{
string licenseKey = Environment.GetEnvironmentVariable("GemBoxLicenseKey");
SpreadsheetInfo.SetLicense(licenseKey);
@@ -24,13 +27,13 @@ namespace BlackRockReportFunction.Bussines
{
new ClockifyRecord
{
recordDescription = "Description1",
recordDescription = "massa placerat duis ultricies lacus sed turpis tincidunt id aliquet risus feugiat in ante metus dictum at tempor commodo ullamcorper",
recordTime = new TimeOnly(3,15,44),
amount = 200
},
new ClockifyRecord
{
recordDescription = "Description1",
recordDescription = "et tortor at risus viverra adipiscing at in tellus integer feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit",
recordTime = new TimeOnly(3,15,44),
amount = 150
}
@@ -43,19 +46,19 @@ namespace BlackRockReportFunction.Bussines
{
new ClockifyRecord
{
recordDescription = "Description1",
recordDescription = "iaculis urna id volutpat lacus laoreet non curabitur gravida arcu ac tortor dignissim convallis aenean et tortor at risus viverra",
recordTime = new TimeOnly(3,15,44),
amount = 300
},
new ClockifyRecord
{
recordDescription = "Description1",
recordDescription = "gravida arcu ac tortor dignissim convallis aenean et tortor at risus viverra adipiscing at in tellus integer feugiat scelerisque varius",
recordTime = new TimeOnly(3,15,44),
amount = 100
},
new ClockifyRecord
{
recordDescription = "Description1",
recordDescription = "sit amet massa vitae tortor condimentum lacinia quis vel eros donec ac odio tempor orci dapibus ultrices in iaculis nunc",
recordTime = new TimeOnly(3,15,44),
amount = 120
}
@@ -68,13 +71,13 @@ namespace BlackRockReportFunction.Bussines
{
new ClockifyRecord
{
recordDescription = "Description1",
recordDescription = "vulputate mi sit amet mauris commodo quis imperdiet massa tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada proin libero nunc",
recordTime = new TimeOnly(3,15,44),
amount = 50
},
new ClockifyRecord
{
recordDescription = "Description1",
recordDescription = "senectus et netus et malesuada fames ac turpis egestas maecenas pharetra convallis posuere morbi leo urna molestie at elementum eu",
recordTime = new TimeOnly(3,15,44),
amount = 500
}
@@ -84,48 +87,65 @@ namespace BlackRockReportFunction.Bussines
};

var excelFile = new ExcelFile();

var ws = excelFile.Worksheets.Add("Content");

var sectionStyle = new CellStyle
{
Font =
{
Name = DefaultFontName,
Weight = ExcelFont.BoldWeight,
Size = 250,
Size = DefaultFontSize * 12,
},
VerticalAlignment = VerticalAlignmentStyle.Center,
HorizontalAlignment = HorizontalAlignmentStyle.Center,
HorizontalAlignment = HorizontalAlignmentStyle.Left,
};

var mainDetailsStyle = new CellStyle
{
Font =
{
Name = DefaultFontName,
Weight = ExcelFont.BoldWeight,
Size = 200,
}
Size = DefaultFontSize * 11,
},
VerticalAlignment = VerticalAlignmentStyle.Center,
};

var normalDetailsStyle = new CellStyle
{
Font =
{
Name = DefaultFontName,
Weight = ExcelFont.NormalWeight,
Size = DefaultFontSize * 10,
},
VerticalAlignment = VerticalAlignmentStyle.Center,
};

await AddReportItems(testObject, ws, sectionStyle, mainDetailsStyle);
AddReportItems(testObject, ws, sectionStyle, mainDetailsStyle, normalDetailsStyle);

// Autofit
excelFile = await AutoFitReport(excelFile);
AutoFitReport(excelFile);

return excelFile;
}

public static async Task AddReportItems(ClockifyReport reportObject, ExcelWorksheet ws, CellStyle sectionStyle, CellStyle mainDetailsStyle)
public static void AddReportItems(ClockifyReport reportObject, ExcelWorksheet ws, CellStyle sectionStyle, CellStyle mainDetailsStyle, CellStyle normalDetailsStyle)
{
int row = 0;
string[] sectionNames = { "User", "Description", "Time (h)", "Time (decimal)", "Amount (USD)" };
string[] sectionNames = { "User ", "Description ", "Time (h) ", "Time (decimal) ", "Amount (USD) " };
decimal totalAmountSum = 0;
List<string> usersDecimalHours = new List<string>();

for (int i = 0; i < sectionNames.Length; i++)
{
ws.Cells[row, i].Style = sectionStyle;
ws.Cells[row, i].Value = sectionNames[i];
ws.Cells[row, i].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Medium;
ws.Cells[row, i].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;
ws.Cells[row, i].Style.Borders[IndividualBorder.Bottom].LineStyle = LineStyle.Thick;
ws.Cells[row, i].Style.Borders[IndividualBorder.Bottom].LineColor = System.Drawing.Color.LightGray;
}

row++;
@@ -133,19 +153,27 @@ namespace BlackRockReportFunction.Bussines
foreach (var reportPerson in reportObject.reportPeople)
{
ws.Cells[row, 0].Style = mainDetailsStyle;
ws.Cells[row, 0].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;
ws.Cells[row, 0].Value = reportPerson.fullName;

ws.Cells[row, 1].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;

var sumOfRecordHours = Formaters.getSumOfRecordTimes(reportPerson.records.Select(record => record.recordTime).ToList());
ws.Cells[row, 2].Style = mainDetailsStyle;
ws.Cells[row, 2].Style.HorizontalAlignment = HorizontalAlignmentStyle.Right;
ws.Cells[row, 2].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;
ws.Cells[row, 2].Value = sumOfRecordHours;

ws.Cells[row, 3].Style = mainDetailsStyle;
ws.Cells[row, 3].Style.HorizontalAlignment = HorizontalAlignmentStyle.Right;
ws.Cells[row, 3].Value = Formaters.getDecimalHours(sumOfRecordHours);
ws.Cells[row, 3].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;
var userDecimalHours = Formaters.getDecimalHours(sumOfRecordHours);
ws.Cells[row, 3].Value = userDecimalHours;
usersDecimalHours.Add(userDecimalHours);

ws.Cells[row, 4].Style = mainDetailsStyle;
ws.Cells[row, 4].Style.HorizontalAlignment = HorizontalAlignmentStyle.Right;
ws.Cells[row, 4].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;
ws.Cells[row, 4].Value = string.Format("{0} USD", reportPerson.records.Sum(record => record.amount).ToString("0.00"));
totalAmountSum += reportPerson.records.Sum(record => record.amount);

@@ -153,16 +181,26 @@ namespace BlackRockReportFunction.Bussines

foreach (var personRecord in reportPerson.records)
{
ws.Cells[row, 0].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;

ws.Cells[row, 1].Style = normalDetailsStyle;
ws.Cells[row, 1].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;
ws.Cells[row, 1].Value = personRecord.recordDescription;

ws.Cells[row, 2].Value = Formaters.getRecordTime(personRecord.recordTime);
ws.Cells[row, 2].Style = normalDetailsStyle;
ws.Cells[row, 2].Style.HorizontalAlignment = HorizontalAlignmentStyle.Right;
ws.Cells[row, 2].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;
ws.Cells[row, 2].Value = Formaters.getRecordTime(personRecord.recordTime);

ws.Cells[row, 3].Value = Formaters.getDecimalHours(personRecord.recordTime);
ws.Cells[row, 3].Style = normalDetailsStyle;
ws.Cells[row, 3].Style.HorizontalAlignment = HorizontalAlignmentStyle.Right;
ws.Cells[row, 3].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;
ws.Cells[row, 3].Value = Formaters.getDecimalHours(personRecord.recordTime);

ws.Cells[row, 4].Value = string.Format("{0} USD", personRecord.amount.ToString("0.00"));
ws.Cells[row, 4].Style = normalDetailsStyle;
ws.Cells[row, 4].Style.HorizontalAlignment = HorizontalAlignmentStyle.Right;
ws.Cells[row, 4].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;
ws.Cells[row, 4].Value = string.Format("{0} USD", personRecord.amount.ToString("0.00"));

row++;
}
@@ -170,6 +208,7 @@ namespace BlackRockReportFunction.Bussines

ws.Cells.GetSubrangeAbsolute(row, 0, row, 1).Merged = true;
ws.Cells.GetSubrangeAbsolute(row, 0, row, 1).Style = mainDetailsStyle;
ws.Cells.GetSubrangeAbsolute(row, 0, row, 1).Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;
ws.Cells.GetSubrangeAbsolute(row, 0, row, 1).Value = reportObject.reportDescription;

var totalSum = Formaters.getTotalSum(
@@ -182,22 +221,23 @@ namespace BlackRockReportFunction.Bussines

ws.Cells[row, 2].Style = mainDetailsStyle;
ws.Cells[row, 2].Style.HorizontalAlignment = HorizontalAlignmentStyle.Right;
ws.Cells[row, 2].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;
ws.Cells[row, 2].Value = totalSum;

ws.Cells[row, 3].Style = mainDetailsStyle;
ws.Cells[row, 3].Style.HorizontalAlignment = HorizontalAlignmentStyle.Right;
ws.Cells[row, 3].Value = Formaters.getDecimalHours(totalSum);
ws.Cells[row, 3].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;
ws.Cells[row, 3].Value = Formaters.getTotalDecimalHours(usersDecimalHours);

ws.Cells[row, 4].Style = mainDetailsStyle;
ws.Cells[row, 4].Style.HorizontalAlignment = HorizontalAlignmentStyle.Right;
ws.Cells[row, 4].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin;
ws.Cells[row, 4].Value = string.Format("{0} USD", totalAmountSum.ToString("0.00"));
}

public static async Task<ExcelFile> AutoFitReport(ExcelFile excelFile)
public static void AutoFitReport(ExcelFile excelFile)
{
var localFile = excelFile;

foreach (var sheet in localFile.Worksheets)
foreach (var sheet in excelFile.Worksheets)
{
var columnCount = sheet.CalculateMaxUsedColumns();

@@ -206,8 +246,6 @@ namespace BlackRockReportFunction.Bussines
sheet.Columns[i].AutoFit(1, sheet.Rows[0], sheet.Rows[sheet.Rows.Count - 1]);
}
}

return localFile;
}
}
}

+ 1
- 1
BlackRockReportFunction/ClockifyApiIntegrationFunction.cs Zobrazit soubor

@@ -17,7 +17,7 @@ namespace BlackRockReportFunction
}

[Function("ClockifyApiIntegrationFunction")]
public void Run([TimerTrigger("*/5 * * * * *")] MyInfo myTimer)
public void Run([TimerTrigger("* * * */5 * *")] MyInfo myTimer)
{
ClockifyReports.InitializeClockifyIntegration();


+ 20
- 1
BlackRockReportFunction/Helpers/Formaters.cs Zobrazit soubor

@@ -44,7 +44,9 @@ namespace BlackRockReportFunction.Helpers
? components[0].ToCharArray()[1].ToString()
: components[0];

var minutesPercent = (Convert.ToInt32(components[1]) * 100 / 60).ToString();
var totalMinutes = Convert.ToDecimal(components[1]) + (Convert.ToDecimal(components[2]) / 60);

var minutesPercent = Convert.ToInt32(Math.Floor(totalMinutes * 100 / 60)).ToString();
if (minutesPercent.Length == 1)
{
minutesPercent = string.Format("0{0}", minutesPercent);
@@ -98,5 +100,22 @@ namespace BlackRockReportFunction.Helpers
totalMinutes > 9 ? totalMinutes : string.Format("0{0}", totalMinutes),
totalSeconds > 9 ? totalSeconds : string.Format("0{0}", totalSeconds));
}

public static string getTotalDecimalHours(List<string> usersDecimalHours)
{
var minutesPercent = 0;
var hours = 0;
foreach(var userDecimalHours in usersDecimalHours)
{
var components = userDecimalHours.Split(':');
minutesPercent += Convert.ToInt32(components[1]);
hours += Convert.ToInt32(components[0]);
}

hours += minutesPercent / 100;
minutesPercent = minutesPercent % 100;

return string.Format("{0}:{1}", hours, minutesPercent);
}
}
}

+ 39
- 5
BlackRockReportFunction/MailSenderFunction.cs Zobrazit soubor

@@ -2,8 +2,14 @@ using System;
using System.IO;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using SendGrid.Helpers.Mail;
//using SendGrid.Helpers.Mail;
using Microsoft.Azure.WebJobs;
using MailKit;
using MimeKit;
using MimeKit.Text;
using MailKit.Net.Smtp;
using MailKit.Security;
using GemBox.Spreadsheet;

namespace BlackRockReportFunction
{
@@ -18,11 +24,8 @@ namespace BlackRockReportFunction
//http://127.0.0.1:10000/devstoreaccount1/report-container

[Function("MailSenderFunction")]
public SendGridMessage Run([BlobTrigger("report-container/{name}", Connection = "AzureWebJobsStorage")] string fileData, string fileName)
public void Run([BlobTrigger("report-container/{name}", Connection = "AzureWebJobsStorage")] byte[] fileData)
{
_logger.LogInformation($"C# Blob trigger function Processed blob\n New file detected with name: {fileName}");

return null;
//var msg = new SendGridMessage()
//{
// From = new EmailAddress("nikola.jovanovic@dilig.net", "Nikola Jovanovic"),
@@ -34,6 +37,37 @@ namespace BlackRockReportFunction
//msg.AddTo(new EmailAddress("nikolajovanovic3579@gmail.com", "Nikola Jovanovic"));

//return msg;
string fileName = string.Format($"BlackRockReport_{DateTime.Now.ToString("f")}.xlsx");

var email = new MimeMessage();
email.From.Add(MailboxAddress.Parse("nikola.jovanovic@dilig.net"));
email.To.Add(MailboxAddress.Parse("justine.tromp31@ethereal.email"));
email.Subject = "BlackRock Report";
var body = new TextPart(TextFormat.Html) { Text = string.Format("Here is yours report for last week. {0}", fileName) };

MemoryStream memoryStream = new MemoryStream(fileData);
memoryStream.Position = 0;

var attachment = new MimePart(" application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
Content = new MimeContent(memoryStream),
ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
ContentTransferEncoding = ContentEncoding.Base64,
FileName = fileName
};

var multipart = new Multipart("mixed");
multipart.Add(body);
multipart.Add(attachment);
email.Body = multipart;

using var smtp = new SmtpClient();
smtp.Connect("smtp.ethereal.email", 587, SecureSocketOptions.StartTls);
smtp.Authenticate("justine.tromp31@ethereal.email", "ztbDPEp9gEfPetwZFY");
smtp.Send(email);
smtp.Disconnect(true);

_logger.LogInformation("Email sent successfully!");
}
}
}

+ 7
- 2
BlackRockReportFunction/ReportGeneratorFunction.cs Zobrazit soubor

@@ -8,6 +8,11 @@ using BlackRockReportFunction.Models;
using BlackRockReportFunction.Helpers;
using Azure.Storage.Blobs;
using BlackRockReportFunction.Bussines;
using MailKit;
using MimeKit;
using MimeKit.Text;
using MailKit.Net.Smtp;
using MailKit.Security;

namespace BlackRockReportFunction
{
@@ -26,7 +31,7 @@ namespace BlackRockReportFunction
{
_logger.LogInformation($"C# Queue trigger function processed: {myQueueItem}, gemboxKey: {"E0YU - JKLB - WFCE - N52P"}");

var reportFile = await ReportGenerator.GenerateReportContent();
var reportFile = ReportGenerator.GenerateReportContent();

string connection = Environment.GetEnvironmentVariable("AzureWebJobsStorage");
string containerName = "report-container";
@@ -46,6 +51,6 @@ namespace BlackRockReportFunction
await blob.UploadAsync(memoryStream);

_logger.LogInformation("File uploaded successfully!");
}
}
}
}

Načítá se…
Zrušit
Uložit