| @@ -38,4 +38,7 @@ | |||
| <ItemGroup> | |||
| <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <Folder Include="Helpers\" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1,59 +0,0 @@ | |||
| using BlackRockReportFunction.Models; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| using System.Net; | |||
| using System.Net.Http; | |||
| using System.Net.Http.Headers; | |||
| using GemBox.Spreadsheet; | |||
| using Microsoft.AspNetCore.Mvc; | |||
| using Microsoft.AspNetCore.Http; | |||
| using Microsoft.Build.Tasks.Deployment.Bootstrapper; | |||
| namespace BlackRockReportFunction.Bussines | |||
| { | |||
| public class ClockifyReports | |||
| { | |||
| public static string? clockifyApiKey = Environment.GetEnvironmentVariable("ClockifyApiKey"); | |||
| static HttpClient client = new HttpClient(); | |||
| public static async Task InitializeClockifyIntegration() | |||
| { | |||
| client.DefaultRequestHeaders.Add("X-API-Key", clockifyApiKey); | |||
| client.BaseAddress = new Uri("https://reports.api.clockify.me/v1"); | |||
| client.DefaultRequestHeaders.Accept.Clear(); | |||
| client.DefaultRequestHeaders.Accept | |||
| .Add(new MediaTypeWithQualityHeaderValue("application/json")); | |||
| } | |||
| public static async Task<Uri> CreateClockifyReport(ClockifyReport clockifyReport) | |||
| { | |||
| HttpResponseMessage httpResponseMessage = await client | |||
| .PostAsJsonAsync("api/clockifyreport", clockifyReport); | |||
| httpResponseMessage.EnsureSuccessStatusCode(); | |||
| return httpResponseMessage.Headers.Location; | |||
| } | |||
| public static async Task<ClockifyReport> GetClockifyReportAsync(string path) | |||
| { | |||
| ClockifyReport clockifyReport = null; | |||
| HttpResponseMessage httpResponseMessage= await client.GetAsync(path); | |||
| if (httpResponseMessage.IsSuccessStatusCode) | |||
| { | |||
| clockifyReport = await httpResponseMessage.Content.ReadAsAsync<ClockifyReport>(); | |||
| } | |||
| return clockifyReport; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,15 +1,15 @@ | |||
| using GemBox.Spreadsheet; | |||
| using BlackRockReportFunction.Models; | |||
| using BlackRockReportFunction.Helpers; | |||
| namespace BlackRockReportFunction.Bussines | |||
| { | |||
| internal class ReportGenerator | |||
| { | |||
| public const string DefaultFontName = "Calibri"; | |||
| public const string DefaultFontName = "DejaVu Sans"; | |||
| public const int DefaultFontSize = 20; | |||
| public static ExcelFile GenerateReportContent(ClockifyReport reportObject) | |||
| public static ExcelFile GenerateReportContent(Root reportObject) | |||
| { | |||
| string licenseKey = Environment.GetEnvironmentVariable("GemBoxLicenseKey"); | |||
| SpreadsheetInfo.SetLicense(licenseKey); | |||
| @@ -47,7 +47,7 @@ namespace BlackRockReportFunction.Bussines | |||
| { | |||
| Name = DefaultFontName, | |||
| Weight = ExcelFont.NormalWeight, | |||
| Size = DefaultFontSize * 10, | |||
| Size = DefaultFontSize * 11, | |||
| }, | |||
| VerticalAlignment = VerticalAlignmentStyle.Center, | |||
| }; | |||
| @@ -60,10 +60,12 @@ namespace BlackRockReportFunction.Bussines | |||
| return excelFile; | |||
| } | |||
| public static void AddReportItems(ClockifyReport reportObject, ExcelWorksheet ws, CellStyle sectionStyle, CellStyle mainDetailsStyle, CellStyle normalDetailsStyle) | |||
| public static void AddReportItems(Root reportObject, ExcelWorksheet ws, CellStyle sectionStyle, CellStyle mainDetailsStyle, CellStyle normalDetailsStyle) | |||
| { | |||
| TimeSpan t, time,time1; | |||
| int row = 0; | |||
| string[] sectionNames = { "User ", "Description ", "Time (h) ", "Time (decimal) ", "Amount (USD) " }; | |||
| string[] sectionNames = { "User ", "Description ", "Time (h) ", "Time (decimal) "}; | |||
| decimal totalAmountSum = 0; | |||
| List<string> usersDecimalHours = new List<string>(); | |||
| @@ -78,15 +80,16 @@ namespace BlackRockReportFunction.Bussines | |||
| row++; | |||
| foreach (var reportPerson in reportObject.reportPeople) | |||
| foreach (var reportPerson in reportObject.groupOne) | |||
| { | |||
| 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, 0].Value = reportPerson.name; | |||
| ws.Cells[row, 1].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin; | |||
| var sumOfRecordHours = Formaters.getSumOfRecordTimes(reportPerson.records.Select(record => record.recordTime).ToList()); | |||
| time = TimeSpan.FromSeconds(reportPerson.duration); | |||
| var sumOfRecordHours = string.Format("{0:00}:{1:D2}:{2:D2}", Math.Floor(time.TotalHours), time.Minutes, time.Seconds); | |||
| 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; | |||
| @@ -95,72 +98,58 @@ namespace BlackRockReportFunction.Bussines | |||
| ws.Cells[row, 3].Style = mainDetailsStyle; | |||
| ws.Cells[row, 3].Style.HorizontalAlignment = HorizontalAlignmentStyle.Right; | |||
| ws.Cells[row, 3].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin; | |||
| var userDecimalHours = Formaters.getDecimalHours(sumOfRecordHours); | |||
| var userDecimalHours = Convert.ToDecimal(TimeSpan.FromSeconds(reportPerson.duration).TotalHours).ToString("0.00"); ; | |||
| 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); | |||
| row++; | |||
| foreach (var personRecord in reportPerson.records) | |||
| foreach (var personRecord in reportPerson.children) | |||
| { | |||
| 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, 1].Value = personRecord.name; | |||
| 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); | |||
| t = TimeSpan.FromSeconds(personRecord.duration); | |||
| ws.Cells[row, 2].Value = string.Format("{0:00}:{1:D2}:{2:D2}", Math.Floor(t.TotalHours), t.Minutes,t.Seconds) ; | |||
| 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, 3].Value = Convert.ToDecimal(TimeSpan.FromSeconds(personRecord.duration).TotalHours).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++; | |||
| } | |||
| } | |||
| 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( | |||
| reportObject.reportPeople.Select( | |||
| person => Formaters.getSumOfRecordTimes( | |||
| person.records.Select(record => record.recordTime).ToList() | |||
| ) | |||
| ).ToList() | |||
| ); | |||
| var totalSum = reportObject.totals.Select(total => total.totalTime).FirstOrDefault(); | |||
| ws.Cells[row, 0].Style = mainDetailsStyle; | |||
| ws.Cells[row, 0].Style.Borders[IndividualBorder.Right].LineStyle = LineStyle.Thin; | |||
| ws.Cells[row, 0].Value = "Total"; | |||
| 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; | |||
| time1= t = TimeSpan.FromSeconds(totalSum); | |||
| ws.Cells[row, 2].Value = string.Format("{0:00}:{1:D2}:{2:D2}", Math.Floor(time1.TotalHours), time1.Minutes, time1.Seconds); | |||
| ws.Cells[row, 3].Style = mainDetailsStyle; | |||
| 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.getTotalDecimalHours(usersDecimalHours); | |||
| ws.Cells[row, 3].Value = Convert.ToDecimal(TimeSpan.FromSeconds(totalSum).TotalHours).ToString("0.00"); ; | |||
| 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 void AutoFitReport(ExcelFile excelFile) | |||
| @@ -6,13 +6,32 @@ using Microsoft.Azure.Functions.Worker; | |||
| using Microsoft.Extensions.Logging; | |||
| using BlackRockReportFunction.Models; | |||
| using Newtonsoft.Json; | |||
| using System.Net.Http; | |||
| using System.Net.Http.Headers; | |||
| using System.Text; | |||
| namespace BlackRockReportFunction | |||
| { | |||
| public class ClockifyApiIntegrationFunction | |||
| { | |||
| private readonly ILogger _logger; | |||
| public static string? clockifyApiKey = Environment.GetEnvironmentVariable("ClockifyApiKey"); | |||
| static HttpClient client = new HttpClient(); | |||
| public static async Task InitializeClockifyIntegration() | |||
| { | |||
| //client.DefaultRequestHeaders.Add("X-API-Key", clockifyApiKey); /// | |||
| client.DefaultRequestHeaders.Add("X-API-Key", "MmU2ZTA2MGItMTM1ZS00ZTg1LTkwMjAtMDkzYThiZmNmYmIy"); | |||
| client.BaseAddress = new Uri("https://reports.api.clockify.me/v1"); | |||
| client.DefaultRequestHeaders.Accept.Clear(); | |||
| client.DefaultRequestHeaders.Accept | |||
| .Add(new MediaTypeWithQualityHeaderValue("application/json")); | |||
| } | |||
| public ClockifyApiIntegrationFunction(ILoggerFactory loggerFactory) | |||
| { | |||
| _logger = loggerFactory.CreateLogger<ClockifyApiIntegrationFunction>(); | |||
| @@ -20,85 +39,31 @@ namespace BlackRockReportFunction | |||
| [Function("ClockifyApiIntegrationFunction")] | |||
| [QueueOutput("queue1")] | |||
| public string Run([TimerTrigger("*/15 * * * * *")] MyInfo myTimer) | |||
| public string Run([TimerTrigger("*/15 * * * * *" )] MyInfo myTimer) //TODO: Set on Friday at 20 o'clock | |||
| { | |||
| ClockifyReports.InitializeClockifyIntegration(); | |||
| InitializeClockifyIntegration(); // Clockify API Integration | |||
| var json = "{\"dateRangeStart\":\"2022-05-30T00:00:00.000\",\"dateRangeEnd\":\"2022-06-05T23:59:59.000\",\"summaryFilter\":{\"groups\":[\"USER\",\"TIMEENTRY\"]},\"clients\":{\"ids\":[\"61488f8d9eb0753d0e40d761\"]},\"projects\":{\"ids\":[\"6242f015f6fe850b94cd0c64\"]},\"amountShown\":\"HIDE_AMOUNT\"}"; | |||
| HttpContent httpContent = new StringContent(json, Encoding.UTF8, "application/json"); | |||
| var testObject = new ClockifyReport | |||
| HttpResponseMessage response = client.PostAsync(client.BaseAddress + "/workspaces/5eb44340ef0f6c66fc88732a/reports/summary", httpContent).Result; | |||
| //TO DO: Clear code!!! | |||
| if (response.IsSuccessStatusCode) | |||
| { | |||
| reportName = "BlackRockReport_20220615", | |||
| reportDescription = "Total (13/06/2022 - 15/06/2022)", | |||
| reportPeople = new List<Person> | |||
| { | |||
| new Person | |||
| { | |||
| fullName = "Nikola Jovanovic", | |||
| records = new List<ClockifyRecord> | |||
| { | |||
| new ClockifyRecord | |||
| { | |||
| 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 = "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 | |||
| } | |||
| } | |||
| }, | |||
| new Person | |||
| { | |||
| fullName = "Boris Stevanovic", | |||
| records = new List<ClockifyRecord> | |||
| { | |||
| new ClockifyRecord | |||
| { | |||
| 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 = "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 = "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 | |||
| } | |||
| } | |||
| }, | |||
| new Person | |||
| { | |||
| fullName = "Dunja Stevanovic", | |||
| records = new List<ClockifyRecord> | |||
| { | |||
| new ClockifyRecord | |||
| { | |||
| 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 = "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 | |||
| } | |||
| } | |||
| } | |||
| } | |||
| }; | |||
| _logger.LogInformation($"Data collection successfull!"); | |||
| return JsonConvert.SerializeObject(testObject); | |||
| _logger.LogInformation($"Data collection successfull!"); | |||
| return JsonConvert.SerializeObject(JsonConvert.DeserializeObject<object>(response.Content.ReadAsStringAsync().Result), Formatting.Indented); | |||
| //var responseContent = JsonConvert.DeserializeObject<object>(response.Content.ReadAsStringAsync().Result); // TO DO: Convert JSON to csv | |||
| } | |||
| else | |||
| { | |||
| return JsonConvert.SerializeObject(JsonConvert.DeserializeObject<object>(response.Content.ReadAsStringAsync().Result), Formatting.Indented); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,15 +0,0 @@ | |||
| //using System; | |||
| //using Microsoft.Azure.Functions.Worker; | |||
| //using Microsoft.Extensions.Logging; | |||
| //namespace BlackRockReportFunction | |||
| //{ | |||
| // public class Function1 | |||
| // { | |||
| // [Function("Function1")] | |||
| // public void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log) | |||
| // { | |||
| // log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); | |||
| // } | |||
| // } | |||
| //} | |||
| @@ -1,121 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| using Microsoft.Extensions.Logging; | |||
| namespace BlackRockReportFunction.Helpers | |||
| { | |||
| public static class Formaters | |||
| { | |||
| public static string getSumOfRecordTimes(List<TimeOnly> recordTimes) | |||
| { | |||
| int totalHours = 0; | |||
| int totalMinutes = 0; | |||
| int totalSeconds = 0; | |||
| // Calculate Seconds | |||
| int totalRecordsSeconds = recordTimes.Sum(record => record.Second); | |||
| totalSeconds = totalRecordsSeconds % 60; | |||
| totalMinutes += totalRecordsSeconds / 60; | |||
| // Calculate Minutes | |||
| int totalRecordsMinutes = recordTimes.Sum(record => record.Minute); | |||
| totalMinutes = totalMinutes + (totalRecordsMinutes % 60); | |||
| totalHours += totalRecordsMinutes / 60; | |||
| // Calculate Hours | |||
| int totalRecordHours = recordTimes.Sum(record => record.Hour); | |||
| totalHours += totalRecordHours; | |||
| return string.Format("{0}:{1}:{2}", | |||
| totalHours > 9 ? totalHours : string.Format("0{0}", totalHours), | |||
| totalMinutes > 9 ? totalMinutes : string.Format("0{0}", totalMinutes), | |||
| totalSeconds > 9 ? totalSeconds : string.Format("0{0}", totalSeconds)); | |||
| } | |||
| public static string getDecimalHours(string recordHoursSum) | |||
| { | |||
| var components = recordHoursSum.Split(':').ToList(); | |||
| var hours = (components[0].Length == 2 && components[0].First() == '0') | |||
| ? components[0].ToCharArray()[1].ToString() | |||
| : components[0]; | |||
| 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); | |||
| } | |||
| return string.Format("{0}:{1}", hours, minutesPercent); | |||
| } | |||
| public static string getDecimalHours(TimeOnly recordTime) | |||
| { | |||
| return getDecimalHours(string.Format("{0}:{1}:{2}", recordTime.Hour, recordTime.Minute, recordTime.Second)); | |||
| } | |||
| public static string getRecordTime(TimeOnly recordTime) | |||
| { | |||
| return string.Format("{0}:{1}:{2}", recordTime.Hour, recordTime.Minute, recordTime.Second); | |||
| } | |||
| public static string getTotalSum(List<string> personsSums) | |||
| { | |||
| var totalHours = 0; | |||
| var totalMinutes = 0; | |||
| var totalSeconds = 0; | |||
| foreach(var personSum in personsSums) | |||
| { | |||
| var components = personSum.Split(':').Select(Int32.Parse).ToList(); | |||
| //add new person time | |||
| totalSeconds += components[2] % 60; | |||
| totalMinutes += components[2] / 60; | |||
| //clean up new sum | |||
| totalMinutes += totalSeconds / 60; | |||
| totalSeconds = totalSeconds % 60; | |||
| //add new person time | |||
| totalMinutes += components[1] % 60; | |||
| totalHours += components[1] / 60; | |||
| //clean up new time | |||
| totalHours += totalMinutes / 60; | |||
| totalMinutes = totalMinutes % 60; | |||
| //add new person time | |||
| totalHours += components[0]; | |||
| } | |||
| return string.Format("{0}:{1}:{2}", | |||
| totalHours > 9 ? totalHours : string.Format("0{0}", totalHours), | |||
| 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); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,25 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Globalization; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| using Newtonsoft.Json; | |||
| namespace BlackRockReportFunction.Helpers | |||
| { | |||
| public class TimeOnlyConverter : JsonConverter<TimeOnly> | |||
| { | |||
| private const string Format = "hh:mm:ss"; | |||
| public override TimeOnly ReadJson(JsonReader reader, | |||
| Type objectType, | |||
| TimeOnly existingValue, | |||
| bool hasExistingValue, | |||
| JsonSerializer serializer) => | |||
| TimeOnly.ParseExact((string)reader.Value, Format, CultureInfo.InvariantCulture); | |||
| public override void WriteJson(JsonWriter writer, TimeOnly value, JsonSerializer serializer) => | |||
| writer.WriteValue(value.ToString(Format, CultureInfo.InvariantCulture)); | |||
| } | |||
| } | |||
| @@ -40,7 +40,7 @@ namespace BlackRockReportFunction | |||
| var email = new MimeMessage(); | |||
| email.From.Add(MailboxAddress.Parse("[email protected]")); | |||
| email.To.Add(MailboxAddress.Parse("shaniya.blick76@ethereal.email")); | |||
| email.To.Add(MailboxAddress.Parse("greta.bartoletti@ethereal.email")); | |||
| email.Subject = "BlackRock Report"; | |||
| var body = new TextPart(TextFormat.Html) { Text = string.Format("Here is yours report for last week. {0}", fileName) }; | |||
| @@ -62,7 +62,7 @@ namespace BlackRockReportFunction | |||
| using var smtp = new SmtpClient(); | |||
| smtp.Connect("smtp.ethereal.email", 587, SecureSocketOptions.StartTls); | |||
| smtp.Authenticate("[email protected]", "8pPsjCbwCFMrEeKNef"); | |||
| smtp.Authenticate("[email protected]", "ecsdGZxWHk4yfjZpD5"); //"[email protected]", "8pPsjCbwCFMrEeKNef" | |||
| smtp.Send(email); | |||
| smtp.Disconnect(true); | |||
| @@ -0,0 +1,18 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Text.Json.Serialization; | |||
| using System.Threading.Tasks; | |||
| namespace BlackRockReportFunction.Models | |||
| { | |||
| internal class Child | |||
| { | |||
| public int duration { get; set; } | |||
| public string _id { get; set; } | |||
| public string name { get; set; } //description | |||
| public List<object> amounts { get; set; } | |||
| } | |||
| } | |||
| @@ -1,18 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| using Newtonsoft.Json; | |||
| using BlackRockReportFunction.Helpers; | |||
| namespace BlackRockReportFunction.Models | |||
| { | |||
| public class ClockifyRecord | |||
| { | |||
| public string recordDescription { get; set; } | |||
| [JsonConverter(typeof(TimeOnlyConverter))] | |||
| public TimeOnly recordTime { get; set; } | |||
| public decimal amount { get; set; } | |||
| } | |||
| } | |||
| @@ -1,15 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace BlackRockReportFunction.Models | |||
| { | |||
| public class ClockifyReport | |||
| { | |||
| public string reportName { get; set; } | |||
| public string reportDescription { get; set; } | |||
| public List<Person> reportPeople { get; set; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,18 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace BlackRockReportFunction.Models | |||
| { | |||
| internal class GroupOne | |||
| { | |||
| public int duration { get; set; } | |||
| public string _id { get; set; } | |||
| public string name { get; set; } | |||
| public string nameLowerCase { get; set; } | |||
| public List<Child> children { get; set; } | |||
| public List<object> amounts { get; set; } | |||
| } | |||
| } | |||
| @@ -6,9 +6,10 @@ using System.Threading.Tasks; | |||
| namespace BlackRockReportFunction.Models | |||
| { | |||
| public class Person | |||
| internal class Root | |||
| { | |||
| public string fullName { get; set; } | |||
| public List<ClockifyRecord> records { get; set; } | |||
| public List<Total> totals { get; set; } | |||
| public List<GroupOne> groupOne { get; set; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,17 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace BlackRockReportFunction.Models | |||
| { | |||
| internal class Total | |||
| { | |||
| public string _id { get; set; } | |||
| public int totalTime { get; set; } | |||
| public int entriesCount { get; set; } | |||
| public object totalAmount { get; set; } | |||
| public List<object> amounts { get; set; } | |||
| } | |||
| } | |||
| @@ -5,7 +5,6 @@ using Microsoft.Extensions.Logging; | |||
| using Microsoft.Azure.WebJobs; | |||
| using GemBox.Spreadsheet; | |||
| using BlackRockReportFunction.Models; | |||
| using BlackRockReportFunction.Helpers; | |||
| using Azure.Storage.Blobs; | |||
| using BlackRockReportFunction.Bussines; | |||
| using MailKit; | |||
| @@ -30,7 +29,9 @@ namespace BlackRockReportFunction | |||
| [BlobOutput("report-container/BlackRock_Report.xslx", Connection = "AzureWebJobsStorage")] | |||
| public async Task Run([QueueTrigger("queue1")] string myQueueItem) | |||
| { | |||
| var reportObject = JsonConvert.DeserializeObject<ClockifyReport>(myQueueItem); | |||
| //Console.WriteLine("Run function debugging"); | |||
| //var reportObject = JsonConvert.DeserializeObject<ClockifyReport>(myQueueItem); | |||
| var reportObject = JsonConvert.DeserializeObject<Root>(myQueueItem); | |||
| var reportFile = ReportGenerator.GenerateReportContent(reportObject); | |||
| string connection = Environment.GetEnvironmentVariable("AzureWebJobsStorage"); | |||
| @@ -46,7 +47,7 @@ namespace BlackRockReportFunction | |||
| { | |||
| Type = XlsxType.Xlsx | |||
| }); | |||
| memoryStream.Position = 0; | |||
| await blob.UploadAsync(memoryStream); | |||