From 9712148d394bc351cdb4a237be2b1a360633fe71 Mon Sep 17 00:00:00 2001 From: barhen Date: Wed, 7 Jun 2023 22:41:38 -0500 Subject: [PATCH] Dashboard commit 4 --- Client/Biskilog Accounting.Client.csproj | 1 + Client/Layouts/MainLayout.razor.cs | 17 +- Client/Pages/Dashboard/Dashboard.razor | 277 +----------------- Client/Pages/Dashboard/Dashboard.razor.cs | 145 ++++++++- .../Elements/AnalyticsItemSmall.razor | 14 - .../Dashboard/Elements/ChartElement.razor | 14 +- .../Dashboard/Elements/ChartElement.razor.cs | 47 ++- .../Dashboard/Elements/LowStockItems.razor | 30 ++ .../Dashboard/Elements/LowStockItems.razor.cs | 11 + .../Elements/MostPurchasedElement.razor | 80 +++++ .../Elements/MostPurchasedElement.razor.cs | 33 +++ .../Dashboard/Elements/TransactionCard.razor | 31 ++ .../Elements/TransactionCard.razor.cs | 24 ++ .../Dashboard/Elements/WelcomeCard.razor | 2 +- .../Dashboard/Elements/WelcomeCard.razor.cs | 39 ++- Client/_Imports.razor | 4 +- Client/wwwroot/index.html | 2 + Server/Controllers/AnalyticsController.cs | 3 +- Server/Services/AnalyticalService.cs | 37 ++- Shared/Interfaces/IAnalytics.cs | 8 +- Shared/Interfaces/ICalculator.cs | 1 + Shared/ServiceRepo/CalculatorService.cs | 26 +- 22 files changed, 527 insertions(+), 319 deletions(-) create mode 100644 Client/Pages/Dashboard/Elements/LowStockItems.razor create mode 100644 Client/Pages/Dashboard/Elements/LowStockItems.razor.cs create mode 100644 Client/Pages/Dashboard/Elements/MostPurchasedElement.razor create mode 100644 Client/Pages/Dashboard/Elements/MostPurchasedElement.razor.cs create mode 100644 Client/Pages/Dashboard/Elements/TransactionCard.razor create mode 100644 Client/Pages/Dashboard/Elements/TransactionCard.razor.cs diff --git a/Client/Biskilog Accounting.Client.csproj b/Client/Biskilog Accounting.Client.csproj index 2c81af8..7b814f8 100644 --- a/Client/Biskilog Accounting.Client.csproj +++ b/Client/Biskilog Accounting.Client.csproj @@ -20,6 +20,7 @@ + diff --git a/Client/Layouts/MainLayout.razor.cs b/Client/Layouts/MainLayout.razor.cs index 86898b9..1bd6316 100644 --- a/Client/Layouts/MainLayout.razor.cs +++ b/Client/Layouts/MainLayout.razor.cs @@ -4,8 +4,20 @@ namespace Biskilog_Accounting.Client.Layouts { public partial class MainLayout { - - protected override async Task OnInitializedAsync() + protected override Task OnInitializedAsync() + { + CheckPermission(); + return base.OnInitializedAsync(); + } + protected override void OnAfterRender(bool firstRender) + { + if (firstRender) + { + CheckPermission(); + } + base.OnAfterRender(firstRender); + } + private async void CheckPermission() { //Checks if user token is set else redirect user to login page if (!await m_tokenService.IsTokenSet()) @@ -18,7 +30,6 @@ namespace Biskilog_Accounting.Client.Layouts var authHeader = new AuthenticationHeaderValue("Bearer", token.Substring(6).Trim()); m_http.DefaultRequestHeaders.Authorization = authHeader; } - return; } } } diff --git a/Client/Pages/Dashboard/Dashboard.razor b/Client/Pages/Dashboard/Dashboard.razor index 58e7963..5fc6670 100644 --- a/Client/Pages/Dashboard/Dashboard.razor +++ b/Client/Pages/Dashboard/Dashboard.razor @@ -7,7 +7,7 @@
- +
@@ -15,13 +15,13 @@
- +
- +
@@ -30,7 +30,7 @@
- +
@@ -57,278 +57,21 @@
- +
-
-
-
-
Order Statistics
- 42.82k Total Sales -
- -
-
-
-
-

8,258

- Total Orders -
-
-
-
    -
  • -
    - - - -
    -
    -
    -
    Electronic
    - Mobile, Earbuds, TV -
    -
    - 82.5k -
    -
    -
  • -
  • -
    - -
    -
    -
    -
    Fashion
    - T-shirt, Jeans, Shoes -
    -
    - 23.8k -
    -
    -
  • -
  • -
    - -
    -
    -
    -
    Decor
    - Fine Art, Dining -
    -
    - 849k -
    -
    -
  • -
  • -
    - - - -
    -
    -
    -
    Sports
    - Football, Cricket Kit -
    -
    - 99 -
    -
    -
  • -
-
-
+
-
-
- -
-
-
- -
-
-
+
-
-
-
Transactions
- -
-
-
    -
  • -
    - User -
    -
    -
    - Paypal -
    Send money
    -
    -
    -
    +82.6
    - USD -
    -
    -
  • -
  • -
    - User -
    -
    -
    - Wallet -
    Mac'D
    -
    -
    -
    +270.69
    - USD -
    -
    -
  • -
  • -
    - User -
    -
    -
    - Transfer -
    Refund
    -
    -
    -
    +637.91
    - USD -
    -
    -
  • -
  • -
    - User -
    -
    -
    - Credit Card -
    Ordered Food
    -
    -
    -
    -838.71
    - USD -
    -
    -
  • -
  • -
    - User -
    -
    -
    - Wallet -
    Starbucks
    -
    -
    -
    +203.33
    - USD -
    -
    -
  • -
  • -
    - User -
    -
    -
    - Mastercard -
    Ordered Food
    -
    -
    -
    -92.45
    - USD -
    -
    -
  • -
-
-
+ + +
diff --git a/Client/Pages/Dashboard/Dashboard.razor.cs b/Client/Pages/Dashboard/Dashboard.razor.cs index cde908a..8e6c70c 100644 --- a/Client/Pages/Dashboard/Dashboard.razor.cs +++ b/Client/Pages/Dashboard/Dashboard.razor.cs @@ -8,18 +8,32 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard { private TradeSummary m_tradeSummary { get; set; } = new TradeSummary(); private List m_weeklySaleItems { get; set; } = new List { }; + private List m_weeklyCancelledSales { get; set; } = new List { }; + private List m_recentTransaction { get; set; } = new List { }; + private List m_mostPurchased { get; set; } = new List { }; + private List m_lowstock { get; set; } = new List { }; + private double m_cancelledWeeklySale { get; set; } = 0; + private double m_cancelledPercentage { get; set; } = 0; + private double m_totalDebt { get; set; } = 0; private string m_username { get; set; } = string.Empty; private bool loadWeeklySales = true; + private bool m_loadingMostPurchased { get; set; } = true; protected override async Task OnInitializedAsync() { m_username = m_tokenService.GetUserNameFromToken(await m_tokenService.GetToken())!; await GetTradeSummary(); await GetWeeklySales(); + await GetCancelledSales(); + await GetDebtSummary(); + await GetRecentTransactions(); + await GetMostPurchased(); + await GetLowStockItems(); return; } - + // {a_limit + //} /// - /// Gets the tade summary + /// Gets the trade summary /// /// async Task GetTradeSummary() @@ -42,7 +56,30 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard } } /// - /// Gets the tade summary + /// Gets the debt summary + /// + /// + async Task GetDebtSummary() + { + try + { + var response = await m_http.GetAsync("api/analytics/debtors"); + if (response.IsSuccessStatusCode) + { + var jsonContent = await response.Content.ReadAsStringAsync(); + var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; + var debt = JsonSerializer.Deserialize>(jsonContent, options); + m_totalDebt = (double)debt.Sum(c => c.Debt); + StateHasChanged(); + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } + } + /// + /// Gets the weekly sales /// /// async Task GetWeeklySales() @@ -65,5 +102,107 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard Console.WriteLine(ex.Message); } } + /// + /// Gets the summary of cancelled sales for the past week + /// + /// + async Task GetCancelledSales() + { + try + { + DateTime start = DateTime.Now.AddDays(-7).Date; + DateTime end = DateTime.Now.Date; + var response = await m_http.GetAsync($"api/analytics/cancelledsales/{start}/{end}"); + if (response.IsSuccessStatusCode) + { + var jsonContent = await response.Content.ReadAsStringAsync(); + var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; + var weekly = JsonSerializer.Deserialize>(jsonContent, options); + m_weeklyCancelledSales = weekly; + + var loadCancelledSales = m_weeklyCancelledSales.OrderByDescending(t => t.CancelledTransaction.DateCancelled); + if (loadCancelledSales.Count() > 1) + { + m_cancelledWeeklySale = (double)loadCancelledSales.ToList()[0].Value; + m_cancelledPercentage = (((double)loadCancelledSales.ToList()[0].Value - (double)loadCancelledSales.ToList()[1].Value) / (double)loadCancelledSales.ToList()[0].Value) * 100; + } + else + { + m_cancelledWeeklySale = (double)loadCancelledSales.FirstOrDefault().Value; + m_cancelledPercentage = 0; + } + + StateHasChanged(); + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } + } + /// + /// Gets the recent transaction + /// + /// + async Task GetRecentTransactions() + { + try + { + var response = await m_http.GetAsync($"api/analytics/sales/recent/{50}"); + if (response.IsSuccessStatusCode) + { + var jsonContent = await response.Content.ReadAsStringAsync(); + var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; + var recent = JsonSerializer.Deserialize>(jsonContent, options); + m_recentTransaction = recent; + StateHasChanged(); + } + } + catch { } + } + /// + /// Gets a collection of most purchased items within the past + /// + /// + async Task GetMostPurchased() + { + try + { + string start = m_tradeSummary.LastTradeDate.ToString("yyyy-MM-dd"); + string end = m_tradeSummary.CurrentTradeDate.ToString("yyyy-MM-dd"); + var response = await m_http.GetAsync($"api/analytics/mostpurchaseditem/{start}/{end}"); + if (response.IsSuccessStatusCode) + { + var jsonContent = await response.Content.ReadAsStringAsync(); + var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; + var recent = JsonSerializer.Deserialize>(jsonContent, options); + m_mostPurchased = recent; + m_loadingMostPurchased = false; + StateHasChanged(); + } + } + catch { } + } + /// + /// Gets a collection of items that are low on stock + /// + /// + async Task GetLowStockItems() + { + try + { + var response = await m_http.GetAsync($"api/analytics/lowonstock"); + if (response.IsSuccessStatusCode) + { + var jsonContent = await response.Content.ReadAsStringAsync(); + var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; + var recent = JsonSerializer.Deserialize>(jsonContent, options); + m_lowstock = recent; + StateHasChanged(); + } + } + catch (Exception ex) { + } + } } } diff --git a/Client/Pages/Dashboard/Elements/AnalyticsItemSmall.razor b/Client/Pages/Dashboard/Elements/AnalyticsItemSmall.razor index fd23ef1..361d842 100644 --- a/Client/Pages/Dashboard/Elements/AnalyticsItemSmall.razor +++ b/Client/Pages/Dashboard/Elements/AnalyticsItemSmall.razor @@ -9,20 +9,6 @@ alt="chart success" class="rounded" /> - @Title
@(m_calculator.FormatMoneyWithCurrency(Value))
diff --git a/Client/Pages/Dashboard/Elements/ChartElement.razor b/Client/Pages/Dashboard/Elements/ChartElement.razor index 4f032ec..8f94414 100644 --- a/Client/Pages/Dashboard/Elements/ChartElement.razor +++ b/Client/Pages/Dashboard/Elements/ChartElement.razor @@ -6,7 +6,7 @@ {
-
+
@Title
@@ -14,18 +14,14 @@ Items="@Series" Name="Sales" YValue="@(e => e.Total)" - XValue="@(e => e.Date.ToShortDateString())" + XValue="@(e => e.Date.ToString("dd MMM"))" SeriesType="SeriesType.Bar" />
-
+
@SubTitle
- - +
diff --git a/Client/Pages/Dashboard/Elements/ChartElement.razor.cs b/Client/Pages/Dashboard/Elements/ChartElement.razor.cs index bf52f3d..5fa3923 100644 --- a/Client/Pages/Dashboard/Elements/ChartElement.razor.cs +++ b/Client/Pages/Dashboard/Elements/ChartElement.razor.cs @@ -1,6 +1,7 @@ using ApexCharts; using Biskilog_Accounting.Shared.CustomModels; using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Options; namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements { @@ -15,6 +16,7 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements [Parameter] public List Series { get; set; } = new List(); private ApexChartOptions m_options; + private ApexChartOptions options = new ApexChartOptions(); private string m_bestDay { get; set; } = string.Empty; private string m_worstDay { get; set; } = string.Empty; @@ -28,17 +30,54 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements { Bar = new PlotOptionsBar { - ColumnWidth = "7", - + ColumnWidth = "20", + + } + }, + Colors = new List { "#11726d" }, + Yaxis = new List + { + new YAxis + { + Labels = new YAxisLabels + { + Formatter = @"function (value, index, w) { + return Number(value).toLocaleString();}" + } + } + }, + }; + options.Colors = new List { "#11726d" }; + + options.Fill = new Fill + { + Type = new List { FillType.Gradient, FillType.Gradient }, + Gradient = new FillGradient + { + ShadeIntensity = 1, + OpacityFrom = 0.2, + OpacityTo = 0.9, + } + }; + + options.Yaxis = new List + { + new YAxis + { + Labels = new YAxisLabels + { + Formatter = @"function (value, index, w) { + return Number(value).toLocaleString();}" } } }; + if (Series.Count > 1) { m_bestDay = Series.OrderByDescending(t => t.Total).First().Date.ToShortDateString(); - m_bestSales = m_calculator.FormatMoneyWithCurrency((double)Series.OrderByDescending(t => t.Total).First().Total); + m_bestSales = m_calculator.FormatMoneyWithCurrencyKilo((double)Series.OrderByDescending(t => t.Total).First().Total); m_worstDay = Series.OrderByDescending(t => t.Total).Last().Date.ToShortDateString(); - m_worstSales = m_calculator.FormatMoneyWithCurrency((double)Series.OrderByDescending(t => t.Total).Last().Total); + m_worstSales = m_calculator.FormatMoneyWithCurrencyKilo((double)Series.OrderByDescending(t => t.Total).Last().Total); } base.OnParametersSet(); } diff --git a/Client/Pages/Dashboard/Elements/LowStockItems.razor b/Client/Pages/Dashboard/Elements/LowStockItems.razor new file mode 100644 index 0000000..4124868 --- /dev/null +++ b/Client/Pages/Dashboard/Elements/LowStockItems.razor @@ -0,0 +1,30 @@ +@using Biskilog_Accounting.Shared.CustomModels; +@using Biskilog_Accounting.Shared.Interfaces; +@inject ICalculator m_calculator + +
+
+
+
Low Stock Items
+
+
+
+ + + + + + + +
+
diff --git a/Client/Pages/Dashboard/Elements/LowStockItems.razor.cs b/Client/Pages/Dashboard/Elements/LowStockItems.razor.cs new file mode 100644 index 0000000..e0734d4 --- /dev/null +++ b/Client/Pages/Dashboard/Elements/LowStockItems.razor.cs @@ -0,0 +1,11 @@ +using Biskilog_Accounting.Shared.CustomModels; +using Microsoft.AspNetCore.Components; + +namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements +{ + public partial class LowStockItems + { + [Parameter] + public IEnumerable LowStockProducts { get;set; } = new List(); + } +} diff --git a/Client/Pages/Dashboard/Elements/MostPurchasedElement.razor b/Client/Pages/Dashboard/Elements/MostPurchasedElement.razor new file mode 100644 index 0000000..f5156cd --- /dev/null +++ b/Client/Pages/Dashboard/Elements/MostPurchasedElement.razor @@ -0,0 +1,80 @@ +@using Biskilog_Accounting.Shared.CustomModels; +@using Biskilog_Accounting.Shared.Interfaces; +@inject ICalculator m_calculator + +@if (!IsLoading) +{ + @if (MostPurchasedItems.Count() > 5) + { +
+
+
+
+
+
Top 50 most purchased items
+
+
+ @foreach (MostPurchasedItem purchasedItem in m_items.Take(5)) + { + + @($"{purchasedItem.ProductName} x{purchasedItem.NbrTimesSold}") +
+ } +
+
+ + + + +
+
+ + + + + + + +
+
+
+ } +} +else +{ +
+
+
+
+} + \ No newline at end of file diff --git a/Client/Pages/Dashboard/Elements/MostPurchasedElement.razor.cs b/Client/Pages/Dashboard/Elements/MostPurchasedElement.razor.cs new file mode 100644 index 0000000..2fc3813 --- /dev/null +++ b/Client/Pages/Dashboard/Elements/MostPurchasedElement.razor.cs @@ -0,0 +1,33 @@ +using ApexCharts; +using Biskilog_Accounting.Shared.CustomModels; +using Microsoft.AspNetCore.Components; +using Radzen.Blazor.Rendering; +using Legend = ApexCharts.Legend; + +namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements +{ + public partial class MostPurchasedElement + { + [Parameter] + public IEnumerable MostPurchasedItems { get; set; } = new List(); + + [Parameter] + public bool IsLoading { get; set; } = true; + private ApexChartOptions m_options { get; set; } = new(); + private IEnumerable m_items { get; set; } = new List(); + + protected override void OnInitialized() + { + m_options.Legend = new Legend() + { + Show = false, + }; + } + protected override void OnParametersSet() + { + m_items = MostPurchasedItems.OrderByDescending(t => t.NbrTimesSold); + IsLoading = false; + base.OnParametersSet(); + } + } +} diff --git a/Client/Pages/Dashboard/Elements/TransactionCard.razor b/Client/Pages/Dashboard/Elements/TransactionCard.razor new file mode 100644 index 0000000..dc0c1c6 --- /dev/null +++ b/Client/Pages/Dashboard/Elements/TransactionCard.razor @@ -0,0 +1,31 @@ +@using Biskilog_Accounting.Shared.CustomModels; +@using Biskilog_Accounting.Shared.Interfaces; +@inject ICalculator m_calculator + +
+
+
Last 50 Transactions
+
+
+ + + + + + + + + + +
+
+ + \ No newline at end of file diff --git a/Client/Pages/Dashboard/Elements/TransactionCard.razor.cs b/Client/Pages/Dashboard/Elements/TransactionCard.razor.cs new file mode 100644 index 0000000..cbb3579 --- /dev/null +++ b/Client/Pages/Dashboard/Elements/TransactionCard.razor.cs @@ -0,0 +1,24 @@ +using Biskilog_Accounting.Shared.CustomModels; +using Microsoft.AspNetCore.Components; + +namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements +{ + public partial class TransactionCard + { + [Parameter] + public List Sales { get; set; } = new List { }; + [Parameter] + public bool IsLoading { get; set; } = true; + + protected override Task OnInitializedAsync() + { + IsLoading = true; + return base.OnInitializedAsync(); + } + protected override void OnParametersSet() + { + IsLoading = false; + base.OnParametersSet(); + } + } +} diff --git a/Client/Pages/Dashboard/Elements/WelcomeCard.razor b/Client/Pages/Dashboard/Elements/WelcomeCard.razor index 55c9ddf..969e02b 100644 --- a/Client/Pages/Dashboard/Elements/WelcomeCard.razor +++ b/Client/Pages/Dashboard/Elements/WelcomeCard.razor @@ -5,7 +5,7 @@
-
@(CurrentTradeSales > PreviousTradeSales ? "Congratulations 🎉" : PreviousTradeSales > CurrentTradeSales ? "Tough shift there" : "Well Done") @Username!
+
@(TradeSummary.CurrentTradeSales > TradeSummary.LastTradeSales ? "Congratulations 🎉" : TradeSummary.LastTradeSales > TradeSummary.CurrentTradeSales ? "Tough shift there" : "Well Done") @Username!

@m_remarks

diff --git a/Client/Pages/Dashboard/Elements/WelcomeCard.razor.cs b/Client/Pages/Dashboard/Elements/WelcomeCard.razor.cs index ee38ea2..4982050 100644 --- a/Client/Pages/Dashboard/Elements/WelcomeCard.razor.cs +++ b/Client/Pages/Dashboard/Elements/WelcomeCard.razor.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Components; +using Biskilog_Accounting.Shared.CustomModels; +using Microsoft.AspNetCore.Components; namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements { @@ -8,11 +9,11 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements public string Username { get; set; } = string.Empty; [Parameter] - public double CurrentTradeSales { get; set; } = 0; - [Parameter] - public double PreviousTradeSales { get; set; } = 0; + public TradeSummary TradeSummary { get; set; } = new TradeSummary(); private string m_remarks { get; set; } = ""; + private string m_currentTrade { get; set; } = string.Empty; + private string m_previousTrade { get; set; } = string.Empty; protected override void OnParametersSet() { @@ -20,20 +21,38 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements } private void CalculateStatistic() { - double change = ((CurrentTradeSales - PreviousTradeSales) / PreviousTradeSales) * 100; - if (CurrentTradeSales > PreviousTradeSales) + if(TradeSummary.CurrentTradeDate != DateTime.Today) + { + m_currentTrade = $"most recent trade date ({TradeSummary.CurrentTradeDate.ToString("dd MMM,yyy")})"; + } + else + { + m_currentTrade = "current trade"; + } + + if (TradeSummary.LastTradeDate != DateTime.Today.AddDays(-1)) + { + m_previousTrade = $"previous trade date ({TradeSummary.LastTradeDate.ToString("dd MMM,yyy")})"; + } + else + { + m_previousTrade = "previous trade"; + } + + double change = ((TradeSummary.CurrentTradeSales - TradeSummary.LastTradeSales) / TradeSummary.LastTradeSales) * 100; + if (TradeSummary.CurrentTradeSales > TradeSummary.LastTradeSales) { string changePercent = change.ToString("0.00") + "%"; - m_remarks = $"You made a total of {m_calculator.FormatMoneyWithCurrency(CurrentTradeSales)} in the current trade, {changePercent} more than the previous trade sales"; + m_remarks = $"You made a total of {m_calculator.FormatMoneyWithCurrency(TradeSummary.CurrentTradeSales)} in the {m_currentTrade}, {changePercent} more than the sales in the {m_previousTrade}"; } - else if (PreviousTradeSales > CurrentTradeSales) + else if (TradeSummary.LastTradeSales > TradeSummary.CurrentTradeSales) { string changePercent = (change * -1).ToString("0.00") + "%"; - m_remarks = $"You made a total of {m_calculator.FormatMoneyWithCurrency(CurrentTradeSales)} in the current trade, {changePercent} less than the previous trade sales"; + m_remarks = $"You made a total of {m_calculator.FormatMoneyWithCurrency(TradeSummary.CurrentTradeSales)} in the {m_currentTrade}, {changePercent} less than the sales in the {m_previousTrade}"; } else { - m_remarks = $"You made a total of {m_calculator.FormatMoneyWithCurrency(CurrentTradeSales)} in the current trade, same as the previous trade sales"; + m_remarks = $"You made a total of {m_calculator.FormatMoneyWithCurrency(TradeSummary.CurrentTradeSales)} in the {m_currentTrade}, same as the sales in the {m_previousTrade}"; } StateHasChanged(); } diff --git a/Client/_Imports.razor b/Client/_Imports.razor index bb5b0c1..80ed857 100644 --- a/Client/_Imports.razor +++ b/Client/_Imports.razor @@ -5,4 +5,6 @@ @using Microsoft.AspNetCore.Components.WebAssembly.Http @using Microsoft.JSInterop @using Biskilog_Accounting.Client -@using ApexCharts; \ No newline at end of file +@using ApexCharts; +@using Radzen +@using Radzen.Blazor diff --git a/Client/wwwroot/index.html b/Client/wwwroot/index.html index 5cc4985..b7d2405 100644 --- a/Client/wwwroot/index.html +++ b/Client/wwwroot/index.html @@ -7,6 +7,7 @@ + @@ -49,6 +50,7 @@ + diff --git a/Server/Controllers/AnalyticsController.cs b/Server/Controllers/AnalyticsController.cs index 14dd1c8..a51a433 100644 --- a/Server/Controllers/AnalyticsController.cs +++ b/Server/Controllers/AnalyticsController.cs @@ -91,7 +91,6 @@ namespace Biskilog_Accounting.Server.Controllers [HttpGet, Route("lowonstock")] public IEnumerable GetLowOnStockItems() { - string token = Request.Headers[HeaderNames.Authorization]!; return m_analyticService.GetOutOfStockItems(); } @@ -120,7 +119,7 @@ namespace Biskilog_Accounting.Server.Controllers /// [Authorize] [HttpGet, Route("sales/recent/{a_limit}")] - public IEnumerable GetRecentTransactions(int a_limit) + public IEnumerable GetRecentTransactions(int a_limit) { return m_analyticService.GetRecentSales(a_limit); } diff --git a/Server/Services/AnalyticalService.cs b/Server/Services/AnalyticalService.cs index 66ff71b..82a1fe9 100644 --- a/Server/Services/AnalyticalService.cs +++ b/Server/Services/AnalyticalService.cs @@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Net.Http.Headers; using MySqlConnector; using System.Collections.Generic; +using System.Data; using System.Data.Entity; using System.Drawing.Drawing2D; @@ -145,6 +146,7 @@ namespace Biskilog_Accounting.Server.Services from au in AltUnit.DefaultIfEmpty() join rs in m_context.Restocklevels on item.Pcode equals rs.ProductId join un in m_context.Unitofmeasures on p.BaseUnit equals un.UnitCode + orderby item.Quantity where p.Status!.ToLower() != "inactive" && accessiblebranches.Contains(item.BranchId) && ((rs.WarnLevel >= item.Quantity && rs.Unit == p.BaseUnit) || (rs.WarnLevel >= (item.Quantity / au.QuantityUnit) && rs.Unit == au.UnitCode) @@ -177,6 +179,11 @@ namespace Biskilog_Accounting.Server.Services }; } + public IEnumerable GetProductPriceChangeHistory(int a_limit) + { + throw new NotImplementedException(); + } + public IEnumerable GetRecentPriceChanges(int a_limit) { string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!; @@ -198,16 +205,40 @@ namespace Biskilog_Accounting.Server.Services }).Take(a_limit); } - public IEnumerable GetRecentSales(int a_limit) + public IEnumerable GetRecentSales(int a_limit) { string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!; if (AuthEnums.Valid == m_tokenService.ValidateToken(token)) { IEnumerable accessiblebranches = m_tokenService.BranchIds(token); - return m_context.Tblcarts.Where(t => accessiblebranches.Contains(t.BranchId)).OrderByDescending(t => t.Date).Take(a_limit); + + using (var command = m_context.Database.GetDbConnection().CreateCommand()) + { + command.CommandText = "CALL GetRecentTransactions(@p0,@p1)"; + command.Parameters.Add(new MySqlParameter("@p0", string.Join(", ", accessiblebranches.ToArray()))); + command.Parameters.Add(new MySqlParameter("@p1", a_limit)); + + m_context.Database.OpenConnection(); + + using (var reader = command.ExecuteReader()) + { + while (reader.Read()) + { + yield return new SaleItem + { + Transno = reader.GetString(0), + Total = (decimal)reader.GetDouble(1), + Date = reader.GetDateTime(2), + Cashier = reader.GetString(3), + BranchId = reader.GetString(4), + Customer = reader.GetString(5), + Status = reader.GetString(6), + }; + } + } + } } - return new List(); } public IEnumerable GetSalesTransaction(DateTime a_start, DateTime a_end) diff --git a/Shared/Interfaces/IAnalytics.cs b/Shared/Interfaces/IAnalytics.cs index f2b07ca..913a9bc 100644 --- a/Shared/Interfaces/IAnalytics.cs +++ b/Shared/Interfaces/IAnalytics.cs @@ -64,12 +64,18 @@ namespace Biskilog_Accounting.Shared.Interfaces /// /// The number of rows to return /// - IEnumerable GetRecentSales(int a_limit); + IEnumerable GetRecentSales(int a_limit); /// /// Fetches a collection of product price changes recently made /// /// the number of rows to return /// IEnumerable GetRecentPriceChanges(int a_limit); + /// + /// Fetches a collection of price change history per product + /// + /// the number of products to fetch history + /// + IEnumerable GetProductPriceChangeHistory(int a_limit); } } diff --git a/Shared/Interfaces/ICalculator.cs b/Shared/Interfaces/ICalculator.cs index d23d93d..13825fb 100644 --- a/Shared/Interfaces/ICalculator.cs +++ b/Shared/Interfaces/ICalculator.cs @@ -11,6 +11,7 @@ namespace Biskilog_Accounting.Shared.Interfaces { double CalculatePercentage(); string FormatMoneyWithCurrency(double a_amount); + string FormatMoneyWithCurrencyKilo(double a_amount); NumberFormatInfo GetCurrencyCode(); } } diff --git a/Shared/ServiceRepo/CalculatorService.cs b/Shared/ServiceRepo/CalculatorService.cs index e312e95..a9d5486 100644 --- a/Shared/ServiceRepo/CalculatorService.cs +++ b/Shared/ServiceRepo/CalculatorService.cs @@ -19,7 +19,10 @@ namespace Biskilog_Accounting.Shared.ServiceRepo { return string.Format(GetCurrencyCode(), " {0:C2}", a_amount); } - + public string FormatMoneyWithCurrencyKilo(double a_amount) + { + return GetCurrencyCode().CurrencySymbol + FormatNumber(a_amount); + } public NumberFormatInfo GetCurrencyCode() { //TODO have a better implementation @@ -35,5 +38,26 @@ namespace Biskilog_Accounting.Shared.ServiceRepo return numberFormatInfo; } + private string FormatNumber(double a_amount) + { + if (a_amount >= 100000000) + { + return (a_amount / 1000000D).ToString("0.#M"); + } + if (a_amount >= 1000000) + { + return (a_amount / 1000000D).ToString("0.##M"); + } + if (a_amount >= 100000) + { + return (a_amount / 1000D).ToString("0.#k"); + } + if (a_amount >= 10000) + { + return (a_amount / 1000D).ToString("0.##k"); + } + + return a_amount.ToString("#,0"); + } } }