ABP 4.2 .net 5
so i extended tenant entity and added few more fields to it. Its now named Shop this is a single database with more than 200 tenenats , i am trying to display a grid that shows each tenant and Total Transactions done by them .
SHOP TOTAL TRANSACTIONS TOTAL ORDERS
Ravenmart 1222 USD 55
My Invoice entity : <br>
public class Invoice : FullAuditedAggregateRoot, IMultiTenant
{
public Invoice(Guid id, Guid? tenantId, bool isWalkIn, PaymentTypeEnums paymentTypeId,
InvoiceTypeEnum invoiceTypeId) : base(id)
{
TenantId = tenantId;
Total = new decimal(2);
Vat = new decimal(2);
InvoiceNumber = AnGenerator.RandomString(5);
IsWalkIn = isWalkIn;
PaymentTypeId = paymentTypeId;
InvoiceTypeId = invoiceTypeId;
InvoiceStatusId = InvoiceStatusEnum.Unpaid;
InvoiceStatusName = Enum.GetName(InvoiceStatusEnum.Unpaid);
}
public Guid? TenantId { get; }
+ some other fields
This is my Shop Repository : <br>
public class ShopRepository : EfCoreRepository<DukkantekDbContext, Shop, Guid>, IShopRepository
{
public ShopRepository(IDbContextProvider dbContextProvider)
: base(dbContextProvider)
{
}
public async Task<List<ShopWithNavigationProperties>> GetListWithNavigationPropertiesAsync(
bool isOnlineStoreEnabled,
string filter,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0, CancellationToken cancellationToken = default)
{
var query = await GetQueryForNavigationPropertiesAsync();
query = ApplyFilter(query, filter,isOnlineStoreEnabled);
return await query.PageBy(skipCount, maxResultCount).ToListAsync(cancellationToken);
}
public async Task<long> GetCountAsync(
bool isOnlineStoreEnabled,
string filter,
string sorting = null,
CancellationToken cancellationToken = default)
{
var query = ApplyFilter((await GetQueryForNavigationPropertiesAsync()), filter,isOnlineStoreEnabled );
return await query.LongCountAsync(GetCancellationToken(cancellationToken));
}
protected virtual IQueryable<ShopWithNavigationProperties> ApplyFilter(
IQueryable<ShopWithNavigationProperties> query,
string filter,
bool isOnlineStoreEnabled
)
{
return query
.WhereIf(isOnlineStoreEnabled is true, u => u.Shop.IsOnlineStoreEnabled == true)
.WhereIf(isOnlineStoreEnabled is false, u => u.Shop.IsOnlineStoreEnabled == false)
.WhereIf(!filter.IsNullOrWhiteSpace(), u => u.Shop.StoreName.Contains(filter));
}
public virtual async Task<IQueryable<ShopWithNavigationProperties>> GetQueryForNavigationPropertiesAsync()
{
return from shop in (await GetDbSetAsync())
join invoice in (await GetDbContextAsync()).Invoices.DefaultIfEmpty() on shop.Id equals invoice.TenantId into invoices
from invoice in invoices.DefaultIfEmpty()
select new ShopWithNavigationProperties()
{
Shop = shop,
Invoice = invoice,
};
}
}
Heres my issues : in my ShopAppservice , i have the following code : <br>
public async Task<PagedResultDto> GetAllWithDetails(GetShopsInput input)
{
using (_dataFilter.Disable())
{
var shopst = (await _shopRepository.GetListWithNavigationPropertiesAsync(input.IsOnlineStoreEnabled,
input.Filter, input.Sorting, input.MaxResultCount, input.SkipCount)).ToList();
var shops = shopst
.GroupBy(s => s.Shop.Id, (c, i) =>
{
var shopWithNavigationPropertiesList = i.ToList();
return new ShopWithNavigationPropertiesDto()
{
Shop = ObjectMapper.Map<Shop, AppTenantDto>(shopWithNavigationPropertiesList.First().Shop),
TotalOrders = shopWithNavigationPropertiesList.Select(t => t.Request)
?.Count(p => p is {RequestStatusId: RequestStatusEnum.Completed}),
TotalTransactions = shopWithNavigationPropertiesList.Select(t => t.Invoice).ToList()
?.Where(p => p is {InvoiceStatusId: InvoiceStatusEnum.Paid}).Sum(g => g.GrandTotal),
};
}).ToList();
return new PagedResultDto<ShopWithNavigationPropertiesDto>(
await _shopRepository.GetCountAsync(), shops);
}
}
This is not working properly for me as MAXresultcount limits the total records and i end up with wrong values.
How can i show each shop and the total for his invoices knowing that each invoice has a tenantID ?
please please help as i really dont understand how to work around this DDD issue
Edited for better readability.
4 Answer(s)
-
0
to disable tenant filter use ( https://docs.abp.io/en/abp/latest/Data-Filtering )
using (_dataFilter.Disable<IMultiTenant>()) { return await _bookRepository.GetListAsync(); }
and as I understand you created Shop entity via Suite. If so you can write an overload method for
GetListWithNavigationPropertiesAsync
so that you can pass null values toMaxResultCount
andSkipCount
-
0
to disable tenant filter use ( https://docs.abp.io/en/abp/latest/Data-Filtering )
using (_dataFilter.Disable<IMultiTenant>()) { return await _bookRepository.GetListAsync(); }
and as I understand you created Shop entity via Suite. If so you can write an overload method for
GetListWithNavigationPropertiesAsync
so that you can pass null values toMaxResultCount
andSkipCount
Shop Entity is the equivleant of Tenant Like the way AppUser Extends Identity User
I know about disable the multitenant filter , but that is not my question here. .
How do i show a table where i can display for each tenant , the total transactions like the screenshot below .
Invoices is an AUDITEDAGGREGATEROOT and so is TENANT
so how can i do one to many between tenant and Invoice to display sums like this :
-
0
this is more related to EF Core but I'll try to help you. there's a paging so after you get the shop entities you need to write a new query to fill out the total transactions for the results to show
-
1
Hey Albert, appreciate your help and willininges to help me, you are right , this was more of an EFCORE problem, here is how i managed to do it :
public virtual async Task<IQueryable<ShopWithNavigationProperties>> GetQueryForNavigationPropertiesAsync() {
var query = from shop in (await GetDbSetAsync()).DefaultIfEmpty() join invoice in (await GetDbContextAsync()).Invoices.DefaultIfEmpty() on shop.Id equals invoice.TenantId into invoices from invoice in invoices.DefaultIfEmpty() group invoice by new { shop.Id, shop.StoreName, shop.Name, shop.IsOnlineStoreEnabled, shop.ImgUrl, shop.Latitude,shop.Longitude,shop.OpeningHour, shop.ClosingHour,shop.DeliveryProximity } into g select new ShopWithNavigationProperties { Id = g.Key.Id, StoreName = g.Key.StoreName, Name = g.Key.Name, IsOnlineStoreEnabled = g.Key.IsOnlineStoreEnabled, Longitude = g.Key.Longitude, Latitude = g.Key.Latitude, ClosingHour = g.Key.ClosingHour, OpeningHour = g.Key.OpeningHour, DeliveryProximity = g.Key.DeliveryProximity, ImgUrl = g.Key.ImgUrl, TotalOrders = g.Count() , TotalTransactions= g.Sum(c=>c.GrandTotal) } into shops orderby shops.TotalTransactions descending select shops;; return query; }