initial commit

This commit is contained in:
2026-07-21 15:03:40 +07:00
commit 5c20bb8a9e
2752 changed files with 864209 additions and 0 deletions
@@ -0,0 +1,8 @@
namespace Application.Features.DashboardManager.Queries;
public class BarDataItem
{
public string X { get; set; } = string.Empty;
public int Y { get; set; }
public string TooltipMappingName { get; set; } = string.Empty;
}
@@ -0,0 +1,13 @@
namespace Application.Features.DashboardManager.Queries;
public class BarSeries
{
public string Type { get; set; } = string.Empty;
public string XName { get; set; } = string.Empty;
public int Width { get; set; }
public string YName { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public double ColumnSpacing { get; set; }
public string TooltipMappingName { get; set; } = string.Empty;
public List<BarDataItem> DataSource { get; set; } = new List<BarDataItem>();
}
@@ -0,0 +1,13 @@
namespace Application.Features.DashboardManager.Queries;
public class CardsItem
{
public double? SalesTotal { get; init; }
public double? SalesReturnTotal { get; init; }
public double? PurchaseTotal { get; init; }
public double? PurchaseReturnTotal { get; init; }
public double? DeliveryOrderTotal { get; init; }
public double? GoodsReceiveTotal { get; init; }
public double? TransferOutTotal { get; init; }
public double? TransferInTotal { get; init; }
}
@@ -0,0 +1,106 @@
using Application.Common.CQS.Queries;
using Application.Common.Extensions;
using Domain.Entities;
using Domain.Enums;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace Application.Features.DashboardManager.Queries;
public class GetCardsDashboardDto
{
public CardsItem? CardsDashboard { get; init; }
}
public class GetCardsDashboardResult
{
public GetCardsDashboardDto? Data { get; init; }
}
public class GetCardsDashboardRequest : IRequest<GetCardsDashboardResult>
{
}
public class GetCardsDashboardHandler : IRequestHandler<GetCardsDashboardRequest, GetCardsDashboardResult>
{
private readonly IQueryContext _context;
public GetCardsDashboardHandler(IQueryContext context)
{
_context = context;
}
public async Task<GetCardsDashboardResult> Handle(GetCardsDashboardRequest request, CancellationToken cancellationToken)
{
var salesTotal = await _context.SalesOrderItem
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.SumAsync(x => (double?)x.Quantity, cancellationToken);
var salesReturnTotal = await _context.InventoryTransaction
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Where(x => x.ModuleName == nameof(SalesReturn) && x.Status == InventoryTransactionStatus.Confirmed && x.Warehouse!.SystemWarehouse == false)
.SumAsync(x => (double?)x.Movement, cancellationToken);
var purchaseTotal = await _context.PurchaseOrderItem
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.SumAsync(x => (double?)x.Quantity, cancellationToken);
var purchaseReturnTotal = await _context.InventoryTransaction
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Where(x => x.ModuleName == nameof(PurchaseReturn) && x.Status == InventoryTransactionStatus.Confirmed && x.Warehouse!.SystemWarehouse == false)
.SumAsync(x => (double?)x.Movement, cancellationToken);
var deliveryOrderTotal = await _context.InventoryTransaction
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Where(x => x.ModuleName == nameof(DeliveryOrder) && x.Status == InventoryTransactionStatus.Confirmed && x.Warehouse!.SystemWarehouse == false)
.SumAsync(x => (double?)x.Movement, cancellationToken);
var goodsReceiveTotal = await _context.InventoryTransaction
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Where(x => x.ModuleName == nameof(GoodsReceive) && x.Status == InventoryTransactionStatus.Confirmed && x.Warehouse!.SystemWarehouse == false)
.SumAsync(x => (double?)x.Movement, cancellationToken);
var transferOutTotal = await _context.InventoryTransaction
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Where(x => x.ModuleName == nameof(TransferOut) && x.Status == InventoryTransactionStatus.Confirmed && x.Warehouse!.SystemWarehouse == false)
.SumAsync(x => (double?)x.Movement, cancellationToken);
var transferInTotal = await _context.InventoryTransaction
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Where(x => x.ModuleName == nameof(TransferIn) && x.Status == InventoryTransactionStatus.Confirmed && x.Warehouse!.SystemWarehouse == false)
.SumAsync(x => (double?)x.Movement, cancellationToken);
var cardsDashboardData = new CardsItem
{
SalesTotal = salesTotal,
SalesReturnTotal = salesReturnTotal,
PurchaseTotal = purchaseTotal,
PurchaseReturnTotal = purchaseReturnTotal,
DeliveryOrderTotal = deliveryOrderTotal,
GoodsReceiveTotal = goodsReceiveTotal,
TransferOutTotal = transferOutTotal,
TransferInTotal = transferInTotal
};
var result = new GetCardsDashboardResult
{
Data = new GetCardsDashboardDto
{
CardsDashboard = cardsDashboardData
}
};
return result;
}
}
@@ -0,0 +1,116 @@
using Application.Common.CQS.Queries;
using Application.Common.Extensions;
using Domain.Entities;
using Domain.Enums;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace Application.Features.DashboardManager.Queries;
public class GetInventoryDashboardDto
{
public List<InventoryTransaction>? InventoryTransactionDashboard { get; init; }
public List<BarSeries>? InventoryStockDashboard { get; init; }
}
public class GetInventoryDashboardResult
{
public GetInventoryDashboardDto? Data { get; init; }
}
public class GetInventoryDashboardRequest : IRequest<GetInventoryDashboardResult>
{
}
public class GetInventoryDashboardHandler : IRequestHandler<GetInventoryDashboardRequest, GetInventoryDashboardResult>
{
private readonly IQueryContext _context;
public GetInventoryDashboardHandler(IQueryContext context)
{
_context = context;
}
public async Task<GetInventoryDashboardResult> Handle(GetInventoryDashboardRequest request, CancellationToken cancellationToken)
{
var inventoryTransactionData = await _context.InventoryTransaction
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Include(x => x.Warehouse)
.Include(x => x.Product)
.Include(x => x.WarehouseFrom)
.Include(x => x.WarehouseTo)
.Where(x =>
x.Product!.Physical == true &&
x.Warehouse!.SystemWarehouse == false &&
x.Status == InventoryTransactionStatus.Confirmed
)
.OrderByDescending(x => x.CreatedAtUtc)
.ToListAsync(cancellationToken);
var inventoryStockData = _context.InventoryTransaction
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Include(x => x.Warehouse)
.Include(x => x.Product)
.Where(x =>
x.Status == InventoryTransactionStatus.Confirmed &&
x.Warehouse!.SystemWarehouse == false &&
x.Product!.Physical == true
)
.GroupBy(x => new { x.WarehouseId, x.ProductId })
.Select(group => new
{
WarehouseId = group.Key.WarehouseId,
ProductId = group.Key.ProductId,
Warehouse = group.Max(x => x.Warehouse!.Name),
Product = group.Max(x => x.Product!.Name),
Stock = group.Sum(x => x.Stock),
Id = group.Max(x => x.Id),
CreatedAtUtc = group.Max(x => x.CreatedAtUtc)
})
.ToList();
var warehouseData = _context.Warehouse
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Where(x => x.SystemWarehouse == false)
.Select(x => x.Name)
.ToList();
var result = new GetInventoryDashboardResult
{
Data = new GetInventoryDashboardDto
{
InventoryTransactionDashboard = inventoryTransactionData,
InventoryStockDashboard =
warehouseData
.Select(wh => new BarSeries
{
Type = "Column",
XName = "x",
Width = 2,
YName = "y",
Name = wh ?? "",
ColumnSpacing = 0.1,
TooltipMappingName = "tooltipMappingName",
DataSource = inventoryStockData
.Where(x => x.Warehouse == wh)
.Select(x => new BarDataItem
{
X = x.Product ?? string.Empty,
TooltipMappingName = x.Product ?? string.Empty,
Y = (int)(x.Stock ?? 0.0)
}).ToList()
})
.ToList()
}
};
return result;
}
}
@@ -0,0 +1,150 @@
using Application.Common.CQS.Queries;
using Application.Common.Extensions;
using Domain.Entities;
using Domain.Enums;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace Application.Features.DashboardManager.Queries;
public class GetPurchaseDashboardDto
{
public List<PurchaseOrderItem>? PurchaseOrderDashboard { get; init; }
public List<BarSeries>? PurchaseByVendorGroupDashboard { get; init; }
public List<BarSeries>? PurchaseByVendorCategoryDashboard { get; init; }
}
public class GetPurchaseDashboardResult
{
public GetPurchaseDashboardDto? Data { get; init; }
}
public class GetPurchaseDashboardRequest : IRequest<GetPurchaseDashboardResult>
{
}
public class GetPurchaseDashboardHandler : IRequestHandler<GetPurchaseDashboardRequest, GetPurchaseDashboardResult>
{
private readonly IQueryContext _context;
public GetPurchaseDashboardHandler(IQueryContext context)
{
_context = context;
}
public async Task<GetPurchaseDashboardResult> Handle(GetPurchaseDashboardRequest request, CancellationToken cancellationToken)
{
var purchaseOrderItemData = await _context.PurchaseOrderItem
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Include(x => x.PurchaseOrder)
.Include(x => x.Product)
.Where(x => x.PurchaseOrder!.OrderStatus == PurchaseOrderStatus.Confirmed)
.OrderByDescending(x => x.PurchaseOrder!.OrderDate)
.Take(30)
.ToListAsync(cancellationToken);
var purchaseByVendorGroupData = _context.PurchaseOrderItem
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Include(x => x.PurchaseOrder)
.ThenInclude(x => x!.Vendor)
.ThenInclude(x => x!.VendorGroup)
.Include(x => x.Product)
.Where(x => x.Product!.Physical == true)
.Select(x => new
{
Status = x.PurchaseOrder!.OrderStatus,
VendorGroupName = x.PurchaseOrder!.Vendor!.VendorGroup!.Name,
Quantity = x.Quantity
})
.GroupBy(x => new { x.Status, x.VendorGroupName })
.Select(g => new
{
Status = g.Key.Status,
VendorGroupName = g.Key.VendorGroupName,
Quantity = g.Sum(x => x.Quantity)
})
.ToList();
var purchaseByVendorCategoryDate = _context.PurchaseOrderItem
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Include(x => x.PurchaseOrder)
.ThenInclude(x => x!.Vendor)
.ThenInclude(x => x!.VendorCategory)
.Include(x => x.Product)
.Where(x => x.Product!.Physical == true)
.Select(x => new
{
Status = x.PurchaseOrder!.OrderStatus,
VendorCategoryName = x.PurchaseOrder!.Vendor!.VendorCategory!.Name,
Quantity = x.Quantity
})
.GroupBy(x => new { x.Status, x.VendorCategoryName })
.Select(g => new
{
Status = g.Key.Status,
VendorCategoryName = g.Key.VendorCategoryName,
Quantity = g.Sum(x => x.Quantity)
})
.ToList();
var result = new GetPurchaseDashboardResult
{
Data = new GetPurchaseDashboardDto
{
PurchaseOrderDashboard = purchaseOrderItemData,
PurchaseByVendorGroupDashboard =
Enum.GetValues(typeof(PurchaseOrderStatus))
.Cast<PurchaseOrderStatus>()
.Select(status => new BarSeries
{
Type = "Bar",
XName = "x",
Width = 2,
YName = "y",
Name = Enum.GetName(typeof(PurchaseOrderStatus), status)!,
ColumnSpacing = 0.1,
TooltipMappingName = "tooltipMappingName",
DataSource = purchaseByVendorGroupData
.Where(x => x.Status == status)
.Select(x => new BarDataItem
{
X = x.VendorGroupName ?? "",
TooltipMappingName = x.VendorGroupName ?? "",
Y = (int)x.Quantity!.Value
}).ToList()
})
.ToList(),
PurchaseByVendorCategoryDashboard =
Enum.GetValues(typeof(PurchaseOrderStatus))
.Cast<PurchaseOrderStatus>()
.Select(status => new BarSeries
{
Type = "Column",
XName = "x",
Width = 2,
YName = "y",
Name = Enum.GetName(typeof(PurchaseOrderStatus), status)!,
ColumnSpacing = 0.1,
TooltipMappingName = "tooltipMappingName",
DataSource = purchaseByVendorCategoryDate
.Where(x => x.Status == status)
.Select(x => new BarDataItem
{
X = x.VendorCategoryName ?? "",
TooltipMappingName = x.VendorCategoryName ?? "",
Y = (int)x.Quantity!.Value
}).ToList()
})
.ToList(),
}
};
return result;
}
}
@@ -0,0 +1,150 @@
using Application.Common.CQS.Queries;
using Application.Common.Extensions;
using Domain.Entities;
using Domain.Enums;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace Application.Features.DashboardManager.Queries;
public class GetSalesDashboardDto
{
public List<SalesOrderItem>? SalesOrderDashboard { get; init; }
public List<BarSeries>? SalesByCustomerGroupDashboard { get; init; }
public List<BarSeries>? SalesByCustomerCategoryDashboard { get; init; }
}
public class GetSalesDashboardResult
{
public GetSalesDashboardDto? Data { get; init; }
}
public class GetSalesDashboardRequest : IRequest<GetSalesDashboardResult>
{
}
public class GetSalesDashboardHandler : IRequestHandler<GetSalesDashboardRequest, GetSalesDashboardResult>
{
private readonly IQueryContext _context;
public GetSalesDashboardHandler(IQueryContext context)
{
_context = context;
}
public async Task<GetSalesDashboardResult> Handle(GetSalesDashboardRequest request, CancellationToken cancellationToken)
{
var salesOrderItemData = await _context.SalesOrderItem
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Include(x => x.SalesOrder)
.Include(x => x.Product)
.Where(x => x.SalesOrder!.OrderStatus == SalesOrderStatus.Confirmed)
.OrderByDescending(x => x.SalesOrder!.OrderDate)
.Take(30)
.ToListAsync(cancellationToken);
var salesByCustomerGroupData = _context.SalesOrderItem
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Include(x => x.SalesOrder)
.ThenInclude(x => x!.Customer)
.ThenInclude(x => x!.CustomerGroup)
.Include(x => x.Product)
.Where(x => x.Product!.Physical == true)
.Select(x => new
{
Status = x.SalesOrder!.OrderStatus,
CustomerGroupName = x.SalesOrder!.Customer!.CustomerGroup!.Name,
Quantity = x.Quantity
})
.GroupBy(x => new { x.Status, x.CustomerGroupName })
.Select(g => new
{
Status = g.Key.Status,
CustomerGroupName = g.Key.CustomerGroupName,
Quantity = g.Sum(x => x.Quantity)
})
.ToList();
var salesByCustomerCategoryData = _context.SalesOrderItem
.AsNoTracking()
.ApplyIsDeletedFilter(false)
.Include(x => x.SalesOrder)
.ThenInclude(x => x!.Customer)
.ThenInclude(x => x!.CustomerCategory)
.Include(x => x.Product)
.Where(x => x.Product!.Physical == true)
.Select(x => new
{
Status = x.SalesOrder!.OrderStatus,
CustomerCategoryName = x.SalesOrder!.Customer!.CustomerCategory!.Name,
Quantity = x.Quantity
})
.GroupBy(x => new { x.Status, x.CustomerCategoryName })
.Select(g => new
{
Status = g.Key.Status,
CustomerCategoryName = g.Key.CustomerCategoryName,
Quantity = g.Sum(x => x.Quantity)
})
.ToList();
var result = new GetSalesDashboardResult
{
Data = new GetSalesDashboardDto
{
SalesOrderDashboard = salesOrderItemData,
SalesByCustomerGroupDashboard =
Enum.GetValues(typeof(SalesOrderStatus))
.Cast<SalesOrderStatus>()
.Select(status => new BarSeries
{
Type = "Column",
XName = "x",
Width = 2,
YName = "y",
Name = Enum.GetName(typeof(SalesOrderStatus), status)!,
ColumnSpacing = 0.1,
TooltipMappingName = "tooltipMappingName",
DataSource = salesByCustomerGroupData
.Where(x => x.Status == status)
.Select(x => new BarDataItem
{
X = x.CustomerGroupName ?? "",
TooltipMappingName = x.CustomerGroupName ?? "",
Y = (int)x.Quantity!.Value
}).ToList()
})
.ToList(),
SalesByCustomerCategoryDashboard =
Enum.GetValues(typeof(SalesOrderStatus))
.Cast<SalesOrderStatus>()
.Select(status => new BarSeries
{
Type = "Bar",
XName = "x",
Width = 2,
YName = "y",
Name = Enum.GetName(typeof(SalesOrderStatus), status)!,
ColumnSpacing = 0.1,
TooltipMappingName = "tooltipMappingName",
DataSource = salesByCustomerCategoryData
.Where(x => x.Status == status)
.Select(x => new BarDataItem
{
X = x.CustomerCategoryName ?? "",
TooltipMappingName = x.CustomerCategoryName ?? "",
Y = (int)x.Quantity!.Value
}).ToList()
})
.ToList()
}
};
return result;
}
}