If Possible, please provide Step by Step process to create the Custon Api in module Application it Helps
HI have Did that Still the issue is there
For Your Referance I have added the code
namespace Hon.IFS.SiteManagement.SiteRiskIndices
{
[RemoteService]
public abstract class SiteRiskIndexAppService : SiteManagementAppService ,ITransientDependency
{
#region Initialization and Constructor
private readonly RiskIndexManager _riskIndexManager;
private readonly IRiskIndexRepository _riskIndexRepository; // Add this field
public SiteRiskIndexAppService(IRiskIndexRepository riskIndexRepository, RiskIndexManager riskIndexManager) // Update constructor
{
_riskIndexManager = riskIndexManager;
_riskIndexRepository = riskIndexRepository; // Initialize the repository
}
#endregion
#region BUlK CREATE RISK INDICES
[Authorize(SiteManagementPermissions.RiskIndices.Create)]
public async Task<List<RiskIndexDto>> CreateBulkRiskIndicesAsync(Guid siteId, List<Guid> buildingIds)
{
var random = new Random();
var createdRiskIndices = new List<RiskIndexDto>();
foreach (var buildingId in buildingIds)
{
// Generate random values with 2 decimal places for each field
var communityRiskIndex = Math.Round(random.NextDouble() * 100, 2); // Define communityRiskIndex
var neighbourhoodRiskIndex = Math.Round(random.NextDouble() * 100, 2); // Define neighbourhoodRiskIndex
var buildingRiskIndex = Math.Round(random.NextDouble() * 100, 2);
var buildingRiskIndexPercentage = 20;
var historicalFireIncident = random.Next(0, 11); // Integer between 0-10
var historicalFireIncidentPercentage = 10;
var maintenance = Math.Round(random.NextDouble() * 100, 2);
var maintenancePercentage = 10;
var fireSupression = Math.Round(random.NextDouble() * 100, 2);
var fireSupressionPercentage = 10;
var fireService = Math.Round(random.NextDouble() * 100, 2);
var fireServicePercentage = Math.Round(random.NextDouble() * 100, 2);
var buildingOrg = Math.Round(random.NextDouble() * 100, 2);
var buildingOrgPercentage = 10;
var passiveFire = Math.Round(random.NextDouble() * 100, 2);
var passiveFirePercentage = 10;
var detection = Math.Round(random.NextDouble() * 100, 2);
var detectionPercentage = 10;
var ignition = Math.Round(random.NextDouble() * 100, 2);
var ignitionPercentage = 10; // Ensure ignitionPercentage is included
var riskIndexScore = (buildingRiskIndex * buildingRiskIndexPercentage)
+ (historicalFireIncident * historicalFireIncidentPercentage)
+ (maintenance * maintenancePercentage)
+ (fireSupression * fireSupressionPercentage)
+ (fireService * fireServicePercentage)
+ (buildingOrg * buildingOrgPercentage)
+ (passiveFire * passiveFirePercentage)
+ (detection * detectionPercentage)
+ (ignition * ignitionPercentage);
// Create risk index for the building
var riskIndex = await _riskIndexManager.CreateAsync(
siteId, buildingId,
(decimal)communityRiskIndex, (decimal)neighbourhoodRiskIndex, // Use the defined variables
(decimal)buildingRiskIndex, (decimal)buildingRiskIndexPercentage,
historicalFireIncident, (decimal)historicalFireIncidentPercentage,
(decimal)maintenance, (decimal)maintenancePercentage,
(decimal)fireSupression, (decimal)fireSupressionPercentage,
(decimal)fireService, (decimal)fireServicePercentage,
(decimal)buildingOrg, (decimal)buildingOrgPercentage,
(decimal)passiveFire, (decimal)passiveFirePercentage,
(decimal)detection, (decimal)detectionPercentage,
(decimal)ignition, (decimal)ignitionPercentage, // Pass ignitionPercentage here
(decimal)riskIndexScore
);
createdRiskIndices.Add(ObjectMapper.Map<RiskIndex, RiskIndexDto>(riskIndex));
}
return createdRiskIndices;
}
[Authorize(SiteManagementPermissions.RiskIndices.Default)]
public async Task<List<RiskIndexDto>> GetListBySiteAndBuildingsAsync(Guid siteId, List<Guid> buildingIds)
{
// Create a query to filter by siteId
var query = await _riskIndexRepository.GetQueryableAsync();
query = query.Where(ri => ri.SiteId == siteId);
// Further filter by buildingIds if provided
if (buildingIds != null && buildingIds.Any())
{
query = query.Where(ri => buildingIds.Contains(ri.BuildingId));
}
// Execute the query and retrieve the results
var items = await AsyncExecuter.ToListAsync(query);
// Map the results to DTOs and return
return ObjectMapper.Map<List<RiskIndex>, List<RiskIndexDto>>(items);
}
#endregion
}
}
I have done it like this: Reference Code below
public virtual async Task<SaasTenantDto> CreateSiteTenanatAsync(SaasTenantCreateDto input)
{
input.ConnectionStrings = await NormalizedConnectionStringsAsync(input.ConnectionStrings);
Tenant tenant = null;
async Task CreateTenantAsync()
{
tenant = await TenantManager.CreateAsync(input.Name, input.EditionId);
if (!input.ConnectionStrings.Default.IsNullOrWhiteSpace())
{
tenant.SetDefaultConnectionString(input.ConnectionStrings.Default);
}
if (input.ConnectionStrings.Databases != null)
{
foreach (var database in input.ConnectionStrings.Databases)
{
tenant.SetConnectionString(database.DatabaseName, database.ConnectionString);
}
}
await CheckConnectionStringAsync(tenant);
input.MapExtraPropertiesTo(tenant);
tenant.SetActivationState(input.ActivationState);
if (tenant.ActivationState == TenantActivationState.ActiveWithLimitedTime)
{
tenant.SetActivationEndDate(input.ActivationEndDate);
}
/* Auto saving to ensure TenantCreatedEto handler can get the tenant! */
await TenantRepository.InsertAsync(tenant, autoSave: true);
}
if (input.ConnectionStrings.Default.IsNullOrWhiteSpace() &&
input.ConnectionStrings.Databases.IsNullOrEmpty())
{
/* Creating the tenant in the current UOW */
await CreateTenantAsync();
}
else
{
/* Creating the tenant in a separate UOW to ensure it is created
* before creating the database.
* TODO: We should remove inner UOW once https://github.com/abpframework/abp/issues/6126 is done
*/
using (var uow = UnitOfWorkManager.Begin(requiresNew: true))
{
await CreateTenantAsync();
await uow.CompleteAsync();
}
}
var adminName = "admin"; // default
if (input.ExtraProperties.TryGetValue("adminName", out var nameObj) && nameObj is string nameStr && !string.IsNullOrWhiteSpace(nameStr))
{
adminName = nameStr;
}
await DistributedEventBus.PublishAsync(
new TenantCreatedEto
{
Id = tenant.Id,
Name = tenant.Name,
Properties =
{
{"AdminEmail", input.AdminEmailAddress},
{"AdminPassword", input.AdminPassword},
** { "AdminName", adminName}** Added this line still not working
}
}
);
return ObjectMapper.Map<Tenant, SaasTenantDto>(tenant);
}
How can I Check the blob storage for the file.
We are programmatically creating directories and uploading files from another part of our application. The directories and files appear correctly in the ABP File Management module, confirming successful storage However, we are experiencing issues when trying to download these files from abp file management module.
Reference Code: private async Task<FileDescriptor> UploadFileAsync(SiteFile file, Guid directoryId) { if (file == null) throw new UserFriendlyException("Invalid file provided.");
// Convert the byte array to a Base64 string
string fileContentBase64 = Convert.ToBase64String(file.Content);
byte[] fileBytes = Convert.FromBase64String(fileContentBase64);
var fileDescriptor = new FileDescriptor(
id: GuidGenerator.Create(),
name: file.Name,
mimeType: file.MimeType,
directoryId: directoryId,
size: fileBytes.Length,
tenantId : _currentTenant?.Id
);
await _fileDescriptorRepository.InsertAsync(fileDescriptor);
using var stream = new MemoryStream(fileBytes);
await _blobContainer.SaveAsync(fileDescriptor.Id.ToString(), stream);
return fileDescriptor;
}
public class SiteFile : FullAuditedEntity<Guid> {
public Guid Id { get; set; }
public string? planType { get; set; }
public string Name { get; set; }
public string MimeType { get; set; }
public long Size { get; set; }
public byte[] Content { get; set; }
}
{
"name": "TestingTenant",
"editionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"activationState": 0,
"activationEndDate": "2025-06-09T04:25:34.834Z",
"editionEndDateUtc": "2025-06-09T04:25:34.834Z",
"adminEmailAddress": "TestingTenant@gmail.com",
"adminPassword": "Satya@123",
"connectionStrings": {
"default": "string",
"databases": [
{
"databaseName": "string",
"connectionString": "string"
}
]
}
}