Devexpress Report Viewer

This commit is contained in:
Sedat ÖZTÜRK 2026-01-06 14:33:39 +03:00
parent 56a35c2e73
commit 233d97c2ec
57 changed files with 2890 additions and 10 deletions

View file

@ -92,6 +92,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Erp.SqlQueryManager.Applica
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Erp.SqlQueryManager.EntityFrameworkCore", "modules\Erp.SqlQueryManager\Erp.SqlQueryManager.EntityFrameworkCore\Erp.SqlQueryManager.EntityFrameworkCore.csproj", "{1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Erp.SqlQueryManager.EntityFrameworkCore", "modules\Erp.SqlQueryManager\Erp.SqlQueryManager.EntityFrameworkCore\Erp.SqlQueryManager.EntityFrameworkCore.csproj", "{1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Erp.Reports", "Erp.Reports", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Erp.Reports.Application", "modules\Erp.Reports\Erp.Reports.Application\Erp.Reports.Application.csproj", "{3E1C9BC6-90C2-20F1-567F-2BA043D81721}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Erp.Reports.Application.Contracts", "modules\Erp.Reports\Erp.Reports.Application.Contracts\Erp.Reports.Application.Contracts.csproj", "{6E1A7691-CD09-860C-C6B3-86FDFDD3E372}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Erp.Reports.Domain", "modules\Erp.Reports\Erp.Reports.Domain\Erp.Reports.Domain.csproj", "{0924ACE7-6A32-F683-9F4D-A15B07D14A5E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Erp.Reports.Domain.Shared", "modules\Erp.Reports\Erp.Reports.Domain.Shared\Erp.Reports.Domain.Shared.csproj", "{E65E10EE-41CC-B0E2-1004-E40D0CD26011}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Erp.Reports.EntityFrameworkCore", "modules\Erp.Reports\Erp.Reports.EntityFrameworkCore\Erp.Reports.EntityFrameworkCore.csproj", "{02E91CDA-E54C-9D5C-76AB-B07BE6D3E7FF}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -230,6 +242,26 @@ Global
{1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6}.Debug|Any CPU.Build.0 = Debug|Any CPU {1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6}.Release|Any CPU.ActiveCfg = Release|Any CPU {1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6}.Release|Any CPU.Build.0 = Release|Any CPU {1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6}.Release|Any CPU.Build.0 = Release|Any CPU
{3E1C9BC6-90C2-20F1-567F-2BA043D81721}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E1C9BC6-90C2-20F1-567F-2BA043D81721}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E1C9BC6-90C2-20F1-567F-2BA043D81721}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E1C9BC6-90C2-20F1-567F-2BA043D81721}.Release|Any CPU.Build.0 = Release|Any CPU
{6E1A7691-CD09-860C-C6B3-86FDFDD3E372}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6E1A7691-CD09-860C-C6B3-86FDFDD3E372}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6E1A7691-CD09-860C-C6B3-86FDFDD3E372}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6E1A7691-CD09-860C-C6B3-86FDFDD3E372}.Release|Any CPU.Build.0 = Release|Any CPU
{0924ACE7-6A32-F683-9F4D-A15B07D14A5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0924ACE7-6A32-F683-9F4D-A15B07D14A5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0924ACE7-6A32-F683-9F4D-A15B07D14A5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0924ACE7-6A32-F683-9F4D-A15B07D14A5E}.Release|Any CPU.Build.0 = Release|Any CPU
{E65E10EE-41CC-B0E2-1004-E40D0CD26011}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E65E10EE-41CC-B0E2-1004-E40D0CD26011}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E65E10EE-41CC-B0E2-1004-E40D0CD26011}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E65E10EE-41CC-B0E2-1004-E40D0CD26011}.Release|Any CPU.Build.0 = Release|Any CPU
{02E91CDA-E54C-9D5C-76AB-B07BE6D3E7FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{02E91CDA-E54C-9D5C-76AB-B07BE6D3E7FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{02E91CDA-E54C-9D5C-76AB-B07BE6D3E7FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{02E91CDA-E54C-9D5C-76AB-B07BE6D3E7FF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -274,6 +306,12 @@ Global
{B45A3E8B-286B-4A74-9602-FC192ACEE8C4} = {2889482E-64CA-4A25-91D8-5B963D83681B} {B45A3E8B-286B-4A74-9602-FC192ACEE8C4} = {2889482E-64CA-4A25-91D8-5B963D83681B}
{ED9C639A-A706-4ECB-9638-A15B3681BDEC} = {2889482E-64CA-4A25-91D8-5B963D83681B} {ED9C639A-A706-4ECB-9638-A15B3681BDEC} = {2889482E-64CA-4A25-91D8-5B963D83681B}
{1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6} = {2889482E-64CA-4A25-91D8-5B963D83681B} {1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6} = {2889482E-64CA-4A25-91D8-5B963D83681B}
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {03E1C8DA-035E-4882-AF81-F392139FCF38}
{3E1C9BC6-90C2-20F1-567F-2BA043D81721} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{6E1A7691-CD09-860C-C6B3-86FDFDD3E372} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{0924ACE7-6A32-F683-9F4D-A15B07D14A5E} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{E65E10EE-41CC-B0E2-1004-E40D0CD26011} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{02E91CDA-E54C-9D5C-76AB-B07BE6D3E7FF} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F}

View file

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>Erp.Reports</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="9.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Erp.Reports.Domain.Shared\Erp.Reports.Domain.Shared.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,12 @@
using Volo.Abp.Application;
using Volo.Abp.Modularity;
namespace Erp.Reports;
[DependsOn(
typeof(ErpReportsDomainSharedModule),
typeof(AbpDddApplicationContractsModule)
)]
public class ErpReportsApplicationContractsModule : AbpModule
{
}

View file

@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations;
namespace Erp.Reports.ReportDefinitions;
public class CreateReportDefinitionDto
{
[Required]
[StringLength(256)]
public string Name { get; set; }
[Required]
[StringLength(512)]
public string DisplayName { get; set; }
[Required]
public byte[] Content { get; set; }
}

View file

@ -0,0 +1,13 @@
using Volo.Abp.Application.Services;
namespace Erp.Reports.ReportDefinitions;
public interface IReportDefinitionAppService : IApplicationService
{
Task<ReportDefinitionDto> GetAsync(Guid id);
Task<ReportDefinitionDto> GetByNameAsync(string name);
Task<byte[]> GetContentAsync(string name);
Task<ReportDefinitionDto> CreateAsync(CreateReportDefinitionDto input);
Task<ReportDefinitionDto> UpdateAsync(Guid id, UpdateReportDefinitionDto input);
Task DeleteAsync(Guid id);
}

View file

@ -0,0 +1,9 @@
using Volo.Abp.Application.Dtos;
namespace Erp.Reports.ReportDefinitions;
public class ReportDefinitionDto : FullAuditedEntityDto<Guid>
{
public string Name { get; set; }
public string DisplayName { get; set; }
}

View file

@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations;
namespace Erp.Reports.ReportDefinitions;
public class UpdateReportDefinitionDto
{
[StringLength(512)]
public string DisplayName { get; set; }
public byte[] Content { get; set; }
}

View file

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>Erp.Reports</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application" Version="9.0.2" />
<PackageReference Include="Volo.Abp.AutoMapper" Version="9.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Erp.Reports.Application.Contracts\Erp.Reports.Application.Contracts.csproj" />
<ProjectReference Include="..\Erp.Reports.Domain\Erp.Reports.Domain.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,12 @@
using AutoMapper;
using Erp.Reports.ReportDefinitions;
namespace Erp.Reports;
public class ErpReportsApplicationAutoMapperProfile : Profile
{
public ErpReportsApplicationAutoMapperProfile()
{
CreateMap<ReportDefinition, ReportDefinitionDto>();
}
}

View file

@ -0,0 +1,22 @@
using Volo.Abp.Application;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
namespace Erp.Reports;
[DependsOn(
typeof(ErpReportsDomainModule),
typeof(ErpReportsApplicationContractsModule),
typeof(AbpDddApplicationModule),
typeof(AbpAutoMapperModule)
)]
public class ErpReportsApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<ErpReportsApplicationModule>();
});
}
}

View file

@ -0,0 +1,76 @@
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Erp.Reports.ReportDefinitions;
public class ReportDefinitionAppService : ApplicationService, IReportDefinitionAppService
{
private readonly IRepository<ReportDefinition, Guid> _reportDefinitionRepository;
public ReportDefinitionAppService(IRepository<ReportDefinition, Guid> reportDefinitionRepository)
{
_reportDefinitionRepository = reportDefinitionRepository;
}
public async Task<ReportDefinitionDto> GetAsync(Guid id)
{
var report = await _reportDefinitionRepository.GetAsync(id);
return ObjectMapper.Map<ReportDefinition, ReportDefinitionDto>(report);
}
public async Task<ReportDefinitionDto> GetByNameAsync(string name)
{
var report = await _reportDefinitionRepository.FirstOrDefaultAsync(x => x.Name == name);
if (report == null)
{
throw new Volo.Abp.UserFriendlyException($"Report '{name}' not found");
}
return ObjectMapper.Map<ReportDefinition, ReportDefinitionDto>(report);
}
public async Task<byte[]> GetContentAsync(string name)
{
var report = await _reportDefinitionRepository.FirstOrDefaultAsync(x => x.Name == name);
if (report == null)
{
throw new Volo.Abp.UserFriendlyException($"Report '{name}' not found");
}
return report.Content;
}
public async Task<ReportDefinitionDto> CreateAsync(CreateReportDefinitionDto input)
{
var report = new ReportDefinition(
GuidGenerator.Create(),
input.Name,
input.DisplayName,
input.Content
);
await _reportDefinitionRepository.InsertAsync(report);
return ObjectMapper.Map<ReportDefinition, ReportDefinitionDto>(report);
}
public async Task<ReportDefinitionDto> UpdateAsync(Guid id, UpdateReportDefinitionDto input)
{
var report = await _reportDefinitionRepository.GetAsync(id);
if (!string.IsNullOrEmpty(input.DisplayName))
{
report.DisplayName = input.DisplayName;
}
if (input.Content != null && input.Content.Length > 0)
{
report.UpdateContent(input.Content);
}
await _reportDefinitionRepository.UpdateAsync(report);
return ObjectMapper.Map<ReportDefinition, ReportDefinitionDto>(report);
}
public async Task DeleteAsync(Guid id)
{
await _reportDefinitionRepository.DeleteAsync(id);
}
}

View file

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>Erp.Reports</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Core" Version="9.0.2" />
<PackageReference Include="Volo.Abp.VirtualFileSystem" Version="9.0.2" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,15 @@
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace Erp.Reports;
public class ErpReportsDomainSharedModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<ErpReportsDomainSharedModule>();
});
}
}

View file

@ -0,0 +1,7 @@
namespace Erp.Reports;
public static class ReportsConsts
{
public const string DbTablePrefix = "Erp";
public const string DbSchema = null;
}

View file

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>Erp.Reports</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="9.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Erp.Reports.Domain.Shared\Erp.Reports.Domain.Shared.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,18 @@
namespace Erp.Reports.Domain;
public static class Prefix
{
public static string MenuPrefix { get; set; } = "Plat";
public static string HostPrefix { get; set; } = "H";
public static string? DbSchema { get; set; } = null;
public const string ConnectionStringName = "Reports";
}
public static class TablePrefix
{
public static string ByName(string tableName)
{
return $"{Prefix.MenuPrefix}_{Prefix.HostPrefix}_{tableName}";
}
}

View file

@ -0,0 +1,16 @@
using Volo.Abp.Domain;
using Volo.Abp.Modularity;
namespace Erp.Reports;
[DependsOn(
typeof(AbpDddDomainModule),
typeof(ErpReportsDomainSharedModule)
)]
public class ErpReportsDomainModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
// Domain services configuration can be added here
}
}

View file

@ -0,0 +1,23 @@
using Volo.Abp.Domain.Entities.Auditing;
namespace Erp.Reports.ReportDefinitions;
public class ReportDefinition : FullAuditedEntity<Guid>
{
public string Name { get; set; }
public string DisplayName { get; set; }
public byte[] Content { get; set; }
public ReportDefinition(Guid id, string name, string displayName, byte[] content)
: base(id)
{
Name = name;
DisplayName = displayName;
Content = content;
}
public void UpdateContent(byte[] content)
{
Content = content;
}
}

View file

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>Erp.Reports.EntityFrameworkCore</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="9.0.2" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.SqlServer" Version="9.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Erp.Reports.Domain\Erp.Reports.Domain.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,25 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Erp.Reports.ReportDefinitions;
using Erp.Reports.Domain;
namespace Erp.Reports.EntityFrameworkCore;
[ConnectionStringName(Prefix.ConnectionStringName)]
public class ErpReportsDbContext : AbpDbContext<ErpReportsDbContext>
{
public DbSet<ReportDefinition> ReportDefinitions { get; set; }
public ErpReportsDbContext(DbContextOptions<ErpReportsDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ConfigureReports();
}
}

View file

@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
namespace Erp.Reports.EntityFrameworkCore;
public class ErpReportsDbContextFactory : IDesignTimeDbContextFactory<ErpReportsDbContext>
{
public ErpReportsDbContext CreateDbContext(string[] args)
{
var configuration = BuildConfiguration();
var builder = new DbContextOptionsBuilder<ErpReportsDbContext>()
.UseSqlServer(configuration.GetConnectionString("SqlServer"));
return new ErpReportsDbContext(builder.Options);
}
private static IConfigurationRoot BuildConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../Erp.Reports.HttpApi.Host/"))
.AddJsonFile("appsettings.json", optional: false);
return builder.Build();
}
}

View file

@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Erp.Reports.ReportDefinitions;
using Erp.Reports.Domain;
namespace Erp.Reports.EntityFrameworkCore;
public static class ErpReportsDbContextModelCreatingExtensions
{
public static void ConfigureReports(
this ModelBuilder builder)
{
Check.NotNull(builder, nameof(builder));
builder.Entity<ReportDefinition>(b =>
{
b.ToTable(TablePrefix.ByName(nameof(ReportDefinition)), Prefix.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.Name).IsRequired().HasMaxLength(256);
b.Property(x => x.DisplayName).IsRequired().HasMaxLength(512);
b.Property(x => x.Content).IsRequired();
b.HasIndex(x => x.Name);
});
}
}

View file

@ -0,0 +1,26 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.SqlServer;
using Volo.Abp.Modularity;
namespace Erp.Reports.EntityFrameworkCore;
[DependsOn(
typeof(ErpReportsDomainModule),
typeof(AbpEntityFrameworkCoreSqlServerModule)
)]
public class ErpReportsEntityFrameworkCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<ErpReportsDbContext>(options =>
{
options.AddDefaultRepositories(includeAllEntities: true);
});
Configure<AbpDbContextOptions>(options =>
{
options.UseSqlServer();
});
}
}

View file

@ -11,6 +11,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\modules\Erp.Languages\Erp.Languages.Application.Contracts\Erp.Languages.Application.Contracts.csproj" /> <ProjectReference Include="..\..\modules\Erp.Languages\Erp.Languages.Application.Contracts\Erp.Languages.Application.Contracts.csproj" />
<ProjectReference Include="..\..\modules\Erp.Notifications\Erp.Notifications.Application.Contracts\Erp.Notifications.Application.Contracts.csproj" /> <ProjectReference Include="..\..\modules\Erp.Notifications\Erp.Notifications.Application.Contracts\Erp.Notifications.Application.Contracts.csproj" />
<ProjectReference Include="..\..\modules\Erp.Reports\Erp.Reports.Application.Contracts\Erp.Reports.Application.Contracts.csproj" />
<ProjectReference Include="..\..\modules\Erp.Settings\Erp.Settings.Application.Contracts\Erp.Settings.Application.Contracts.csproj" /> <ProjectReference Include="..\..\modules\Erp.Settings\Erp.Settings.Application.Contracts\Erp.Settings.Application.Contracts.csproj" />
<ProjectReference Include="..\Erp.Platform.Domain.Shared\Erp.Platform.Domain.Shared.csproj" /> <ProjectReference Include="..\Erp.Platform.Domain.Shared\Erp.Platform.Domain.Shared.csproj" />
</ItemGroup> </ItemGroup>

View file

@ -1,5 +1,6 @@
using Erp.Languages; using Erp.Languages;
using Erp.Notifications.Application; using Erp.Notifications.Application;
using Erp.Reports;
using Erp.Settings; using Erp.Settings;
using Volo.Abp.Account; using Volo.Abp.Account;
using Volo.Abp.FeatureManagement; using Volo.Abp.FeatureManagement;
@ -21,7 +22,8 @@ namespace Erp.Platform;
typeof(AbpObjectExtendingModule), typeof(AbpObjectExtendingModule),
typeof(LanguagesApplicationContractsModule), typeof(LanguagesApplicationContractsModule),
typeof(SettingsApplicationContractsModule), typeof(SettingsApplicationContractsModule),
typeof(NotificationApplicationContractsModule) typeof(NotificationApplicationContractsModule),
typeof(ErpReportsApplicationContractsModule)
)] )]
public class PlatformApplicationContractsModule : AbpModule public class PlatformApplicationContractsModule : AbpModule
{ {

View file

@ -15,6 +15,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\modules\Erp.Languages\Erp.Languages.Application\Erp.Languages.Application.csproj" /> <ProjectReference Include="..\..\modules\Erp.Languages\Erp.Languages.Application\Erp.Languages.Application.csproj" />
<ProjectReference Include="..\..\modules\Erp.Notifications\Erp.Notifications.Application\Erp.Notifications.Application.csproj" /> <ProjectReference Include="..\..\modules\Erp.Notifications\Erp.Notifications.Application\Erp.Notifications.Application.csproj" />
<ProjectReference Include="..\..\modules\Erp.Reports\Erp.Reports.Application\Erp.Reports.Application.csproj" />
<ProjectReference Include="..\..\modules\Erp.Settings\Erp.Settings.Application\Erp.Settings.Application.csproj" /> <ProjectReference Include="..\..\modules\Erp.Settings\Erp.Settings.Application\Erp.Settings.Application.csproj" />
<ProjectReference Include="..\Erp.Platform.Domain\Erp.Platform.Domain.csproj" /> <ProjectReference Include="..\Erp.Platform.Domain\Erp.Platform.Domain.csproj" />
<ProjectReference Include="..\Erp.Platform.Application.Contracts\Erp.Platform.Application.Contracts.csproj" /> <ProjectReference Include="..\Erp.Platform.Application.Contracts\Erp.Platform.Application.Contracts.csproj" />

View file

@ -1,5 +1,6 @@
using Erp.Languages; using Erp.Languages;
using Erp.Notifications.Application; using Erp.Notifications.Application;
using Erp.Reports;
using Erp.Settings; using Erp.Settings;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Account; using Volo.Abp.Account;
@ -23,7 +24,8 @@ namespace Erp.Platform;
typeof(AbpFeatureManagementApplicationModule), typeof(AbpFeatureManagementApplicationModule),
typeof(LanguagesApplicationModule), typeof(LanguagesApplicationModule),
typeof(SettingsApplicationModule), typeof(SettingsApplicationModule),
typeof(NotificationApplicationModule) typeof(NotificationApplicationModule),
typeof(ErpReportsApplicationModule)
)] )]
public class PlatformApplicationModule : AbpModule public class PlatformApplicationModule : AbpModule
{ {

View file

@ -454,6 +454,13 @@
"componentPath": "@/views/coordinator/ExamInterface/PDFTestInterface", "componentPath": "@/views/coordinator/ExamInterface/PDFTestInterface",
"routeType": "protected", "routeType": "protected",
"authority": ["App.Coordinator.Tests"] "authority": ["App.Coordinator.Tests"]
},
{
"key": "admin.devexpressReportView",
"path": "/admin/reports/reportviewer",
"componentPath": "@/views/report/DevexpressReportViewer",
"routeType": "protected",
"authority": []
} }
], ],
"Menus": [ "Menus": [

View file

@ -30,6 +30,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\modules\Erp.Languages\Erp.Languages.Domain.Shared\Erp.Languages.Domain.Shared.csproj" /> <ProjectReference Include="..\..\modules\Erp.Languages\Erp.Languages.Domain.Shared\Erp.Languages.Domain.Shared.csproj" />
<ProjectReference Include="..\..\modules\Erp.Notifications\Erp.Notifications.Domain.Shared\Erp.Notifications.Domain.Shared.csproj" /> <ProjectReference Include="..\..\modules\Erp.Notifications\Erp.Notifications.Domain.Shared\Erp.Notifications.Domain.Shared.csproj" />
<ProjectReference Include="..\..\modules\Erp.Reports\Erp.Reports.Domain.Shared\Erp.Reports.Domain.Shared.csproj" />
<ProjectReference Include="..\..\modules\Erp.Settings\Erp.Settings.Domain.Shared\Erp.Settings.Domain.Shared.csproj" /> <ProjectReference Include="..\..\modules\Erp.Settings\Erp.Settings.Domain.Shared\Erp.Settings.Domain.Shared.csproj" />
</ItemGroup> </ItemGroup>

View file

@ -1,5 +1,6 @@
using Erp.Languages; using Erp.Languages;
using Erp.Notifications.Domain; using Erp.Notifications.Domain;
using Erp.Reports;
using Erp.Platform.Localization; using Erp.Platform.Localization;
using Erp.Settings; using Erp.Settings;
using Volo.Abp.AuditLogging; using Volo.Abp.AuditLogging;
@ -27,7 +28,8 @@ namespace Erp.Platform;
typeof(AbpTenantManagementDomainSharedModule), typeof(AbpTenantManagementDomainSharedModule),
typeof(LanguagesDomainSharedModule), typeof(LanguagesDomainSharedModule),
typeof(SettingsDomainSharedModule), typeof(SettingsDomainSharedModule),
typeof(NotificationDomainSharedModule) typeof(NotificationDomainSharedModule),
typeof(ErpReportsDomainSharedModule)
)] )]
public class PlatformDomainSharedModule : AbpModule public class PlatformDomainSharedModule : AbpModule
{ {

View file

@ -13,6 +13,7 @@
<ProjectReference Include="..\..\modules\Erp.MailQueue\Erp.MailQueue.csproj" /> <ProjectReference Include="..\..\modules\Erp.MailQueue\Erp.MailQueue.csproj" />
<ProjectReference Include="..\..\modules\Erp.Notifications\Erp.Notifications.Domain\Erp.Notifications.Domain.csproj" /> <ProjectReference Include="..\..\modules\Erp.Notifications\Erp.Notifications.Domain\Erp.Notifications.Domain.csproj" />
<ProjectReference Include="..\..\modules\Erp.Settings\Erp.Settings.Domain\Erp.Settings.Domain.csproj" /> <ProjectReference Include="..\..\modules\Erp.Settings\Erp.Settings.Domain\Erp.Settings.Domain.csproj" />
<ProjectReference Include="..\..\modules\Erp.Reports\Erp.Reports.Domain\Erp.Reports.Domain.csproj" />
<ProjectReference Include="..\Erp.Platform.Domain.Shared\Erp.Platform.Domain.Shared.csproj" /> <ProjectReference Include="..\Erp.Platform.Domain.Shared\Erp.Platform.Domain.Shared.csproj" />
</ItemGroup> </ItemGroup>

View file

@ -17,6 +17,7 @@ using Volo.Abp.TenantManagement;
using Volo.Abp.BlobStoring; using Volo.Abp.BlobStoring;
using Volo.Abp.BlobStoring.FileSystem; using Volo.Abp.BlobStoring.FileSystem;
using Volo.Abp.Timing; using Volo.Abp.Timing;
using Erp.Reports;
namespace Erp.Platform; namespace Erp.Platform;
@ -35,6 +36,7 @@ namespace Erp.Platform;
typeof(SettingsDomainModule), typeof(SettingsDomainModule),
typeof(ErpMailQueueModule), typeof(ErpMailQueueModule),
typeof(NotificationDomainModule), typeof(NotificationDomainModule),
typeof(ErpReportsDomainModule),
typeof(AbpBlobStoringModule), typeof(AbpBlobStoringModule),
typeof(AbpBlobStoringFileSystemModule) typeof(AbpBlobStoringFileSystemModule)
)] )]

View file

@ -27,6 +27,7 @@ using static Erp.Platform.PlatformConsts;
using static Erp.Settings.SettingsConsts; using static Erp.Settings.SettingsConsts;
using Erp.Platform.Enums; using Erp.Platform.Enums;
using Erp.SqlQueryManager.EntityFrameworkCore; using Erp.SqlQueryManager.EntityFrameworkCore;
using Erp.Reports.EntityFrameworkCore;
namespace Erp.Platform.EntityFrameworkCore; namespace Erp.Platform.EntityFrameworkCore;
@ -351,6 +352,7 @@ public class PlatformDbContext :
builder.ConfigureMailQueue(); builder.ConfigureMailQueue();
builder.ConfigureNotification(); builder.ConfigureNotification();
builder.ConfigureSqlQueryManager(); builder.ConfigureSqlQueryManager();
builder.ConfigureReports();
//Saas //Saas
builder.Entity<AiBot>(b => builder.Entity<AiBot>(b =>

View file

@ -1,6 +1,7 @@
using System; using System;
using Erp.Languages.EntityFrameworkCore; using Erp.Languages.EntityFrameworkCore;
using Erp.Notifications.EntityFrameworkCore; using Erp.Notifications.EntityFrameworkCore;
using Erp.Reports.EntityFrameworkCore;
using Erp.Settings.EntityFrameworkCore; using Erp.Settings.EntityFrameworkCore;
using Erp.SqlQueryManager.EntityFrameworkCore; using Erp.SqlQueryManager.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -36,7 +37,8 @@ namespace Erp.Platform.EntityFrameworkCore;
typeof(LanguagesEntityFrameworkCoreModule), typeof(LanguagesEntityFrameworkCoreModule),
typeof(SettingsEntityFrameworkCoreModule), typeof(SettingsEntityFrameworkCoreModule),
typeof(NotificationEntityFrameworkCoreModule), typeof(NotificationEntityFrameworkCoreModule),
typeof(SqlQueryManagerEntityFrameworkCoreModule) typeof(SqlQueryManagerEntityFrameworkCoreModule),
typeof(ErpReportsEntityFrameworkCoreModule)
)] )]
public class PlatformEntityFrameworkCoreModule : AbpModule public class PlatformEntityFrameworkCoreModule : AbpModule
{ {

View file

@ -27,6 +27,7 @@
<PackageReference Include="EFCore.BulkExtensions" Version="9.0.1" /> <PackageReference Include="EFCore.BulkExtensions" Version="9.0.1" />
<ProjectReference Include="..\..\modules\Erp.Languages\Erp.Languages.EntityFrameworkCore\Erp.Languages.EntityFrameworkCore.csproj" /> <ProjectReference Include="..\..\modules\Erp.Languages\Erp.Languages.EntityFrameworkCore\Erp.Languages.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\Erp.Notifications\Erp.Notifications.EntityFrameworkCore\Erp.Notifications.EntityFrameworkCore.csproj" /> <ProjectReference Include="..\..\modules\Erp.Notifications\Erp.Notifications.EntityFrameworkCore\Erp.Notifications.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\Erp.Reports\Erp.Reports.EntityFrameworkCore\Erp.Reports.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\Erp.Settings\Erp.Settings.EntityFrameworkCore\Erp.Settings.EntityFrameworkCore.csproj" /> <ProjectReference Include="..\..\modules\Erp.Settings\Erp.Settings.EntityFrameworkCore\Erp.Settings.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\Erp.SqlQueryManager\Erp.SqlQueryManager.EntityFrameworkCore\Erp.SqlQueryManager.EntityFrameworkCore.csproj" /> <ProjectReference Include="..\..\modules\Erp.SqlQueryManager\Erp.SqlQueryManager.EntityFrameworkCore\Erp.SqlQueryManager.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\Erp.Platform.Domain\Erp.Platform.Domain.csproj" /> <ProjectReference Include="..\Erp.Platform.Domain\Erp.Platform.Domain.csproj" />

View file

@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace Erp.Platform.Migrations namespace Erp.Platform.Migrations
{ {
[DbContext(typeof(PlatformDbContext))] [DbContext(typeof(PlatformDbContext))]
[Migration("20251214195617_Initial")] [Migration("20260106110136_Initial")]
partial class Initial partial class Initial
{ {
/// <inheritdoc /> /// <inheritdoc />
@ -17773,6 +17773,63 @@ namespace Erp.Platform.Migrations
b.ToTable("Sas_H_ForumTopic", (string)null); b.ToTable("Sas_H_ForumTopic", (string)null);
}); });
modelBuilder.Entity("Erp.Reports.ReportDefinitions.ReportDefinition", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<byte[]>("Content")
.IsRequired()
.HasColumnType("varbinary(max)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("nvarchar(512)");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("Name");
b.ToTable("Plat_H_ReportDefinition", (string)null);
});
modelBuilder.Entity("Erp.Settings.Entities.SettingDefinition", b => modelBuilder.Entity("Erp.Settings.Entities.SettingDefinition", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")

View file

@ -2009,6 +2009,27 @@ namespace Erp.Platform.Migrations
table.PrimaryKey("PK_Plat_H_NotificationRule", x => x.Id); table.PrimaryKey("PK_Plat_H_NotificationRule", x => x.Id);
}); });
migrationBuilder.CreateTable(
name: "Plat_H_ReportDefinition",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
DisplayName = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: false),
Content = table.Column<byte[]>(type: "varbinary(max)", nullable: false),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Plat_H_ReportDefinition", x => x.Id);
});
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "Plat_H_SettingDefinition", name: "Plat_H_SettingDefinition",
columns: table => new columns: table => new
@ -9505,6 +9526,11 @@ namespace Erp.Platform.Migrations
table: "Plat_H_Notification", table: "Plat_H_Notification",
column: "NotificationRuleId"); column: "NotificationRuleId");
migrationBuilder.CreateIndex(
name: "IX_Plat_H_ReportDefinition_Name",
table: "Plat_H_ReportDefinition",
column: "Name");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_Prj_T_ProjectPhase_CategoryId", name: "IX_Prj_T_ProjectPhase_CategoryId",
table: "Prj_T_ProjectPhase", table: "Prj_T_ProjectPhase",
@ -10675,6 +10701,9 @@ namespace Erp.Platform.Migrations
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Plat_H_Notification"); name: "Plat_H_Notification");
migrationBuilder.DropTable(
name: "Plat_H_ReportDefinition");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Plat_H_SettingDefinition"); name: "Plat_H_SettingDefinition");

View file

@ -17770,6 +17770,63 @@ namespace Erp.Platform.Migrations
b.ToTable("Sas_H_ForumTopic", (string)null); b.ToTable("Sas_H_ForumTopic", (string)null);
}); });
modelBuilder.Entity("Erp.Reports.ReportDefinitions.ReportDefinition", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<byte[]>("Content")
.IsRequired()
.HasColumnType("varbinary(max)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("nvarchar(512)");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("Name");
b.ToTable("Plat_H_ReportDefinition", (string)null);
});
modelBuilder.Entity("Erp.Settings.Entities.SettingDefinition", b => modelBuilder.Entity("Erp.Settings.Entities.SettingDefinition", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")

View file

@ -0,0 +1,15 @@
using DevExpress.AspNetCore.Reporting.WebDocumentViewer;
using DevExpress.AspNetCore.Reporting.WebDocumentViewer.Native.Services;
using Microsoft.AspNetCore.Mvc;
namespace Erp.Platform.Controllers;
[Route("DXXRDV")]
[ApiExplorerSettings(IgnoreApi = true)]
public class CustomWebDocumentViewerController : WebDocumentViewerController
{
public CustomWebDocumentViewerController(IWebDocumentViewerMvcControllerService controllerService)
: base(controllerService)
{
}
}

View file

@ -0,0 +1,67 @@
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace Erp.Reports.HttpApi.Host.Data;
public class SqlDataConnectionDescription : DataConnection { }
public class JsonDataConnectionDescription : DataConnection { }
public abstract class DataConnection
{
public int Id { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
public string ConnectionString { get; set; }
}
public class LegacyReportDbContext : DbContext
{
public DbSet<JsonDataConnectionDescription> JsonDataConnections { get; set; }
public DbSet<SqlDataConnectionDescription> SqlDataConnections { get; set; }
public LegacyReportDbContext(DbContextOptions<LegacyReportDbContext> options) : base(options)
{
}
public void InitializeDatabase()
{
Database.EnsureCreated();
var nwindJsonDataConnectionName = "NWindProductsJson";
if (!JsonDataConnections.Any(x => x.Name == nwindJsonDataConnectionName))
{
var newData = new JsonDataConnectionDescription
{
Name = nwindJsonDataConnectionName,
DisplayName = "Northwind Products (JSON)",
ConnectionString = "Uri=Data/nwind.json"
};
JsonDataConnections.Add(newData);
}
var nwindSqlDataConnectionName = "NWindConnectionString";
if (!SqlDataConnections.Any(x => x.Name == nwindSqlDataConnectionName))
{
var newData = new SqlDataConnectionDescription
{
Name = nwindSqlDataConnectionName,
DisplayName = "Northwind Data Connection",
ConnectionString = "XpoProvider=SQLite;Data Source=|DataDirectory|Data/nwind.db"
};
SqlDataConnections.Add(newData);
}
var reportsDataConnectionName = "ReportsDataSqlite";
if (!SqlDataConnections.Any(x => x.Name == reportsDataConnectionName))
{
var newData = new SqlDataConnectionDescription
{
Name = reportsDataConnectionName,
DisplayName = "Reports Data (Demo)",
ConnectionString = "XpoProvider=SQLite;Data Source=|DataDirectory|Data/reportsData.db"
};
SqlDataConnections.Add(newData);
}
SaveChanges();
}
}

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -10,6 +10,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DevExpress.AspNetCore.Reporting" Version="25.2.3" />
<PackageReference Include="DevExpress.Drawing.Skia" Version="25.2.3" />
<PackageReference Include="Volo.Abp.AspNetCore.MultiTenancy" Version="9.0.2" /> <PackageReference Include="Volo.Abp.AspNetCore.MultiTenancy" Version="9.0.2" />
<PackageReference Include="Volo.Abp.Autofac" Version="9.0.2" /> <PackageReference Include="Volo.Abp.Autofac" Version="9.0.2" />
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="9.0.2" /> <PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="9.0.2" />
@ -42,5 +44,20 @@
<None Remove="Logs\**" /> <None Remove="Logs\**" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="Data\nwind.db">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Data\reportsData.db">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Compile Update="PredefinedReports\TestReport.cs">
<SubType>XtraReport</SubType>
</Compile>
</ItemGroup>
</Project> </Project>

View file

@ -9,6 +9,7 @@ using Erp.MailQueue;
using Erp.Notifications.Application; using Erp.Notifications.Application;
using Erp.Platform.Classrooms; using Erp.Platform.Classrooms;
using Erp.Platform.EntityFrameworkCore; using Erp.Platform.EntityFrameworkCore;
using Erp.Reports;
using Erp.SqlQueryManager; using Erp.SqlQueryManager;
using Erp.Platform.Extensions; using Erp.Platform.Extensions;
using Erp.Platform.FileManagement; using Erp.Platform.FileManagement;
@ -55,6 +56,10 @@ using Erp.Platform.DynamicServices;
using static Erp.Platform.PlatformConsts; using static Erp.Platform.PlatformConsts;
using static Erp.Settings.SettingsConsts; using static Erp.Settings.SettingsConsts;
using Hangfire.SqlServer; using Hangfire.SqlServer;
using DevExpress.AspNetCore;
using DevExpress.AspNetCore.Reporting;
using DevExpress.XtraReports.Web.Extensions;
using Erp.Platform.ReportServices;
namespace Erp.Platform; namespace Erp.Platform;
@ -69,7 +74,8 @@ namespace Erp.Platform;
typeof(AbpAspNetCoreSerilogModule), typeof(AbpAspNetCoreSerilogModule),
typeof(AbpSwashbuckleModule), typeof(AbpSwashbuckleModule),
typeof(AbpBackgroundWorkersHangfireModule), typeof(AbpBackgroundWorkersHangfireModule),
typeof(SqlQueryManagerApplicationModule) typeof(SqlQueryManagerApplicationModule),
typeof(ErpReportsApplicationModule)
)] )]
public class PlatformHttpApiHostModule : AbpModule public class PlatformHttpApiHostModule : AbpModule
{ {
@ -127,6 +133,7 @@ public class PlatformHttpApiHostModule : AbpModule
ConfigureAuditing(); ConfigureAuditing();
ConfigureDynamicServices(context); ConfigureDynamicServices(context);
ConfigureDevExpressReporting(context);
context.Services.AddSignalR(); context.Services.AddSignalR();
@ -207,6 +214,7 @@ public class PlatformHttpApiHostModule : AbpModule
options.ConventionalControllers.Create(typeof(ErpMailQueueModule).Assembly); options.ConventionalControllers.Create(typeof(ErpMailQueueModule).Assembly);
options.ConventionalControllers.Create(typeof(NotificationApplicationModule).Assembly); options.ConventionalControllers.Create(typeof(NotificationApplicationModule).Assembly);
options.ConventionalControllers.Create(typeof(SqlQueryManagerApplicationModule).Assembly); options.ConventionalControllers.Create(typeof(SqlQueryManagerApplicationModule).Assembly);
options.ConventionalControllers.Create(typeof(ErpReportsApplicationModule).Assembly);
options.ChangeControllerModelApiExplorerGroupName = false; options.ChangeControllerModelApiExplorerGroupName = false;
options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(PlatformUpdateProfileDto)); options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(PlatformUpdateProfileDto));
options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(UploadFileDto)); options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(UploadFileDto));
@ -386,6 +394,30 @@ public class PlatformHttpApiHostModule : AbpModule
context.Services.AddSingleton<Microsoft.AspNetCore.Mvc.Controllers.IControllerActivator, DynamicControllerActivator>(); context.Services.AddSingleton<Microsoft.AspNetCore.Mvc.Controllers.IControllerActivator, DynamicControllerActivator>();
} }
private void ConfigureDevExpressReporting(ServiceConfigurationContext context)
{
context.Services.AddDevExpressControls();
context.Services.ConfigureReportingServices(configurator =>
{
configurator.ConfigureReportDesigner(designerConfigurator =>
{
});
configurator.ConfigureWebDocumentViewer(viewerConfigurator =>
{
viewerConfigurator.UseCachedReportSourceBuilder();
});
});
// Register report storage extension
context.Services.AddScoped<ReportStorageWebExtension, CustomReportStorageWebExtension>();
// Register custom data connection providers
context.Services.AddScoped<CustomSqlDataConnectionProviderFactory>();
context.Services.AddScoped<CustomJsonDataConnectionProviderFactory>();
context.Services.AddScoped<CustomSqlDataSourceWizardConnectionStringsProvider>();
context.Services.AddScoped<CustomDataSourceWizardJsonDataConnectionStorage>();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context) public override void OnApplicationInitialization(ApplicationInitializationContext context)
{ {
var app = context.GetApplicationBuilder(); var app = context.GetApplicationBuilder();

View file

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using DevExpress.XtraReports.UI;
namespace Erp.Reports.PredefinedReports;
public static class ReportsFactory
{
public static Dictionary<string, Func<XtraReport>> Reports = new Dictionary<string, Func<XtraReport>>()
{
["TestReport"] = () => new TestReport()
};
}

View file

@ -0,0 +1,559 @@
namespace Erp.Reports.PredefinedReports
{
partial class TestReport
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
this.components = new System.ComponentModel.Container();
DevExpress.DataAccess.Sql.SelectQuery selectQuery1 = new DevExpress.DataAccess.Sql.SelectQuery();
DevExpress.DataAccess.Sql.Column column1 = new DevExpress.DataAccess.Sql.Column();
DevExpress.DataAccess.Sql.ColumnExpression columnExpression1 = new DevExpress.DataAccess.Sql.ColumnExpression();
DevExpress.DataAccess.Sql.Table table4 = new DevExpress.DataAccess.Sql.Table();
DevExpress.DataAccess.Sql.Column column2 = new DevExpress.DataAccess.Sql.Column();
DevExpress.DataAccess.Sql.ColumnExpression columnExpression2 = new DevExpress.DataAccess.Sql.ColumnExpression();
DevExpress.DataAccess.Sql.Column column3 = new DevExpress.DataAccess.Sql.Column();
DevExpress.DataAccess.Sql.ColumnExpression columnExpression3 = new DevExpress.DataAccess.Sql.ColumnExpression();
DevExpress.DataAccess.Sql.Column column4 = new DevExpress.DataAccess.Sql.Column();
DevExpress.DataAccess.Sql.ColumnExpression columnExpression4 = new DevExpress.DataAccess.Sql.ColumnExpression();
DevExpress.DataAccess.Sql.Column column5 = new DevExpress.DataAccess.Sql.Column();
DevExpress.DataAccess.Sql.ColumnExpression columnExpression5 = new DevExpress.DataAccess.Sql.ColumnExpression();
DevExpress.DataAccess.Sql.Column column6 = new DevExpress.DataAccess.Sql.Column();
DevExpress.DataAccess.Sql.ColumnExpression columnExpression6 = new DevExpress.DataAccess.Sql.ColumnExpression();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TestReport));
this.TopMargin = new DevExpress.XtraReports.UI.TopMarginBand();
this.BottomMargin = new DevExpress.XtraReports.UI.BottomMarginBand();
this.pageInfo1 = new DevExpress.XtraReports.UI.XRPageInfo();
this.pageInfo2 = new DevExpress.XtraReports.UI.XRPageInfo();
this.ReportHeader = new DevExpress.XtraReports.UI.ReportHeaderBand();
this.label1 = new DevExpress.XtraReports.UI.XRLabel();
this.GroupHeader1 = new DevExpress.XtraReports.UI.GroupHeaderBand();
this.table1 = new DevExpress.XtraReports.UI.XRTable();
this.tableRow1 = new DevExpress.XtraReports.UI.XRTableRow();
this.tableCell1 = new DevExpress.XtraReports.UI.XRTableCell();
this.tableCell2 = new DevExpress.XtraReports.UI.XRTableCell();
this.GroupHeader2 = new DevExpress.XtraReports.UI.GroupHeaderBand();
this.table2 = new DevExpress.XtraReports.UI.XRTable();
this.tableRow2 = new DevExpress.XtraReports.UI.XRTableRow();
this.tableCell3 = new DevExpress.XtraReports.UI.XRTableCell();
this.tableCell4 = new DevExpress.XtraReports.UI.XRTableCell();
this.tableCell5 = new DevExpress.XtraReports.UI.XRTableCell();
this.tableCell6 = new DevExpress.XtraReports.UI.XRTableCell();
this.tableCell7 = new DevExpress.XtraReports.UI.XRTableCell();
this.Detail = new DevExpress.XtraReports.UI.DetailBand();
this.table3 = new DevExpress.XtraReports.UI.XRTable();
this.tableRow3 = new DevExpress.XtraReports.UI.XRTableRow();
this.tableCell8 = new DevExpress.XtraReports.UI.XRTableCell();
this.tableCell9 = new DevExpress.XtraReports.UI.XRTableCell();
this.tableCell10 = new DevExpress.XtraReports.UI.XRTableCell();
this.pictureBox1 = new DevExpress.XtraReports.UI.XRPictureBox();
this.tableCell11 = new DevExpress.XtraReports.UI.XRTableCell();
this.pictureBox2 = new DevExpress.XtraReports.UI.XRPictureBox();
this.tableCell12 = new DevExpress.XtraReports.UI.XRTableCell();
this.pictureBox3 = new DevExpress.XtraReports.UI.XRPictureBox();
this.GroupFooter1 = new DevExpress.XtraReports.UI.GroupFooterBand();
this.label2 = new DevExpress.XtraReports.UI.XRLabel();
this.sqlDataSource1 = new DevExpress.DataAccess.Sql.SqlDataSource(this.components);
this.Title = new DevExpress.XtraReports.UI.XRControlStyle();
this.GroupCaption1 = new DevExpress.XtraReports.UI.XRControlStyle();
this.GroupData1 = new DevExpress.XtraReports.UI.XRControlStyle();
this.DetailCaption1 = new DevExpress.XtraReports.UI.XRControlStyle();
this.DetailData1 = new DevExpress.XtraReports.UI.XRControlStyle();
this.GroupFooterBackground3 = new DevExpress.XtraReports.UI.XRControlStyle();
this.DetailData3_Odd = new DevExpress.XtraReports.UI.XRControlStyle();
this.PageInfo = new DevExpress.XtraReports.UI.XRControlStyle();
((System.ComponentModel.ISupportInitialize)(this.table1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.table2)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.table3)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
//
// TopMargin
//
this.TopMargin.Name = "TopMargin";
//
// BottomMargin
//
this.BottomMargin.Controls.AddRange(new DevExpress.XtraReports.UI.XRControl[] {
this.pageInfo1,
this.pageInfo2});
this.BottomMargin.Name = "BottomMargin";
//
// pageInfo1
//
this.pageInfo1.LocationFloat = new DevExpress.Utils.PointFloat(0F, 0F);
this.pageInfo1.Name = "pageInfo1";
this.pageInfo1.PageInfo = DevExpress.XtraPrinting.PageInfo.DateTime;
this.pageInfo1.SizeF = new System.Drawing.SizeF(325F, 23F);
this.pageInfo1.StyleName = "PageInfo";
//
// pageInfo2
//
this.pageInfo2.LocationFloat = new DevExpress.Utils.PointFloat(325F, 0F);
this.pageInfo2.Name = "pageInfo2";
this.pageInfo2.SizeF = new System.Drawing.SizeF(325F, 23F);
this.pageInfo2.StyleName = "PageInfo";
this.pageInfo2.TextAlignment = DevExpress.XtraPrinting.TextAlignment.TopRight;
this.pageInfo2.TextFormatString = "Page {0} of {1}";
//
// ReportHeader
//
this.ReportHeader.Controls.AddRange(new DevExpress.XtraReports.UI.XRControl[] {
this.label1});
this.ReportHeader.HeightF = 60F;
this.ReportHeader.Name = "ReportHeader";
//
// label1
//
this.label1.LocationFloat = new DevExpress.Utils.PointFloat(0F, 0F);
this.label1.Name = "label1";
this.label1.SizeF = new System.Drawing.SizeF(650F, 24.19433F);
this.label1.StyleName = "Title";
this.label1.Text = "Report";
//
// GroupHeader1
//
this.GroupHeader1.Controls.AddRange(new DevExpress.XtraReports.UI.XRControl[] {
this.table1});
this.GroupHeader1.GroupFields.AddRange(new DevExpress.XtraReports.UI.GroupField[] {
new DevExpress.XtraReports.UI.GroupField("CategoryID", DevExpress.XtraReports.UI.XRColumnSortOrder.Ascending)});
this.GroupHeader1.GroupUnion = DevExpress.XtraReports.UI.GroupUnion.WithFirstDetail;
this.GroupHeader1.HeightF = 27F;
this.GroupHeader1.Level = 1;
this.GroupHeader1.Name = "GroupHeader1";
//
// table1
//
this.table1.LocationFloat = new DevExpress.Utils.PointFloat(0F, 2F);
this.table1.Name = "table1";
this.table1.Rows.AddRange(new DevExpress.XtraReports.UI.XRTableRow[] {
this.tableRow1});
this.table1.SizeF = new System.Drawing.SizeF(650F, 25F);
//
// tableRow1
//
this.tableRow1.Cells.AddRange(new DevExpress.XtraReports.UI.XRTableCell[] {
this.tableCell1,
this.tableCell2});
this.tableRow1.Name = "tableRow1";
this.tableRow1.Weight = 1D;
//
// tableCell1
//
this.tableCell1.Name = "tableCell1";
this.tableCell1.StyleName = "GroupCaption1";
this.tableCell1.Text = "CATEGORY ID";
this.tableCell1.Weight = 1434852.375D;
//
// tableCell2
//
this.tableCell2.ExpressionBindings.AddRange(new DevExpress.XtraReports.UI.ExpressionBinding[] {
new DevExpress.XtraReports.UI.ExpressionBinding("BeforePrint", "Text", "[CategoryID]")});
this.tableCell2.Name = "tableCell2";
this.tableCell2.StyleName = "GroupData1";
this.tableCell2.Weight = 9214747D;
//
// GroupHeader2
//
this.GroupHeader2.Controls.AddRange(new DevExpress.XtraReports.UI.XRControl[] {
this.table2});
this.GroupHeader2.GroupUnion = DevExpress.XtraReports.UI.GroupUnion.WithFirstDetail;
this.GroupHeader2.HeightF = 28F;
this.GroupHeader2.Level = 2;
this.GroupHeader2.Name = "GroupHeader2";
//
// table2
//
this.table2.LocationFloat = new DevExpress.Utils.PointFloat(0F, 0F);
this.table2.Name = "table2";
this.table2.Rows.AddRange(new DevExpress.XtraReports.UI.XRTableRow[] {
this.tableRow2});
this.table2.SizeF = new System.Drawing.SizeF(650F, 28F);
//
// tableRow2
//
this.tableRow2.Cells.AddRange(new DevExpress.XtraReports.UI.XRTableCell[] {
this.tableCell3,
this.tableCell4,
this.tableCell5,
this.tableCell6,
this.tableCell7});
this.tableRow2.Name = "tableRow2";
this.tableRow2.Weight = 1D;
//
// tableCell3
//
this.tableCell3.Borders = DevExpress.XtraPrinting.BorderSide.None;
this.tableCell3.Name = "tableCell3";
this.tableCell3.StyleName = "DetailCaption1";
this.tableCell3.StylePriority.UseBorders = false;
this.tableCell3.Text = "Category Name";
this.tableCell3.Weight = 0.29834482046274041D;
//
// tableCell4
//
this.tableCell4.Name = "tableCell4";
this.tableCell4.StyleName = "DetailCaption1";
this.tableCell4.Text = "Description";
this.tableCell4.Weight = 0.2344280066856971D;
//
// tableCell5
//
this.tableCell5.Name = "tableCell5";
this.tableCell5.StyleName = "DetailCaption1";
this.tableCell5.Text = "Picture";
this.tableCell5.Weight = 0.1609015596829928D;
//
// tableCell6
//
this.tableCell6.Name = "tableCell6";
this.tableCell6.StyleName = "DetailCaption1";
this.tableCell6.Text = "Icon17";
this.tableCell6.Weight = 0.153162841796875D;
//
// tableCell7
//
this.tableCell7.Name = "tableCell7";
this.tableCell7.StyleName = "DetailCaption1";
this.tableCell7.Text = "Icon25";
this.tableCell7.Weight = 0.15316274789663462D;
//
// Detail
//
this.Detail.Controls.AddRange(new DevExpress.XtraReports.UI.XRControl[] {
this.table3});
this.Detail.HeightF = 25F;
this.Detail.Name = "Detail";
//
// table3
//
this.table3.LocationFloat = new DevExpress.Utils.PointFloat(0F, 0F);
this.table3.Name = "table3";
this.table3.OddStyleName = "DetailData3_Odd";
this.table3.Rows.AddRange(new DevExpress.XtraReports.UI.XRTableRow[] {
this.tableRow3});
this.table3.SizeF = new System.Drawing.SizeF(650F, 25F);
//
// tableRow3
//
this.tableRow3.Cells.AddRange(new DevExpress.XtraReports.UI.XRTableCell[] {
this.tableCell8,
this.tableCell9,
this.tableCell10,
this.tableCell11,
this.tableCell12});
this.tableRow3.Name = "tableRow3";
this.tableRow3.Weight = 11.5D;
//
// tableCell8
//
this.tableCell8.Borders = DevExpress.XtraPrinting.BorderSide.None;
this.tableCell8.ExpressionBindings.AddRange(new DevExpress.XtraReports.UI.ExpressionBinding[] {
new DevExpress.XtraReports.UI.ExpressionBinding("BeforePrint", "Text", "[CategoryName]")});
this.tableCell8.Name = "tableCell8";
this.tableCell8.StyleName = "DetailData1";
this.tableCell8.StylePriority.UseBorders = false;
this.tableCell8.Weight = 0.29834482046274041D;
//
// tableCell9
//
this.tableCell9.ExpressionBindings.AddRange(new DevExpress.XtraReports.UI.ExpressionBinding[] {
new DevExpress.XtraReports.UI.ExpressionBinding("BeforePrint", "Text", "[Description]")});
this.tableCell9.Name = "tableCell9";
this.tableCell9.StyleName = "DetailData1";
this.tableCell9.Weight = 0.2344280066856971D;
//
// tableCell10
//
this.tableCell10.Controls.AddRange(new DevExpress.XtraReports.UI.XRControl[] {
this.pictureBox1});
this.tableCell10.Name = "tableCell10";
this.tableCell10.StyleName = "DetailData1";
this.tableCell10.Weight = 0.1609015596829928D;
//
// pictureBox1
//
this.pictureBox1.AnchorHorizontal = ((DevExpress.XtraReports.UI.HorizontalAnchorStyles)((DevExpress.XtraReports.UI.HorizontalAnchorStyles.Left | DevExpress.XtraReports.UI.HorizontalAnchorStyles.Right)));
this.pictureBox1.AnchorVertical = ((DevExpress.XtraReports.UI.VerticalAnchorStyles)((DevExpress.XtraReports.UI.VerticalAnchorStyles.Top | DevExpress.XtraReports.UI.VerticalAnchorStyles.Bottom)));
this.pictureBox1.ExpressionBindings.AddRange(new DevExpress.XtraReports.UI.ExpressionBinding[] {
new DevExpress.XtraReports.UI.ExpressionBinding("BeforePrint", "ImageSource", "[Picture]")});
this.pictureBox1.LocationFloat = new DevExpress.Utils.PointFloat(2.083333F, 0F);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.SizeF = new System.Drawing.SizeF(102.5027F, 25F);
this.pictureBox1.Sizing = DevExpress.XtraPrinting.ImageSizeMode.ZoomImage;
//
// tableCell11
//
this.tableCell11.Controls.AddRange(new DevExpress.XtraReports.UI.XRControl[] {
this.pictureBox2});
this.tableCell11.Name = "tableCell11";
this.tableCell11.StyleName = "DetailData1";
this.tableCell11.Weight = 0.153162841796875D;
//
// pictureBox2
//
this.pictureBox2.AnchorHorizontal = ((DevExpress.XtraReports.UI.HorizontalAnchorStyles)((DevExpress.XtraReports.UI.HorizontalAnchorStyles.Left | DevExpress.XtraReports.UI.HorizontalAnchorStyles.Right)));
this.pictureBox2.AnchorVertical = ((DevExpress.XtraReports.UI.VerticalAnchorStyles)((DevExpress.XtraReports.UI.VerticalAnchorStyles.Top | DevExpress.XtraReports.UI.VerticalAnchorStyles.Bottom)));
this.pictureBox2.ExpressionBindings.AddRange(new DevExpress.XtraReports.UI.ExpressionBinding[] {
new DevExpress.XtraReports.UI.ExpressionBinding("BeforePrint", "ImageSource", "[Icon17]")});
this.pictureBox2.LocationFloat = new DevExpress.Utils.PointFloat(2.083333F, 0F);
this.pictureBox2.Name = "pictureBox2";
this.pictureBox2.SizeF = new System.Drawing.SizeF(97.47251F, 25F);
this.pictureBox2.Sizing = DevExpress.XtraPrinting.ImageSizeMode.ZoomImage;
//
// tableCell12
//
this.tableCell12.Controls.AddRange(new DevExpress.XtraReports.UI.XRControl[] {
this.pictureBox3});
this.tableCell12.Name = "tableCell12";
this.tableCell12.StyleName = "DetailData1";
this.tableCell12.Weight = 0.15316274789663462D;
//
// pictureBox3
//
this.pictureBox3.AnchorHorizontal = ((DevExpress.XtraReports.UI.HorizontalAnchorStyles)((DevExpress.XtraReports.UI.HorizontalAnchorStyles.Left | DevExpress.XtraReports.UI.HorizontalAnchorStyles.Right)));
this.pictureBox3.AnchorVertical = ((DevExpress.XtraReports.UI.VerticalAnchorStyles)((DevExpress.XtraReports.UI.VerticalAnchorStyles.Top | DevExpress.XtraReports.UI.VerticalAnchorStyles.Bottom)));
this.pictureBox3.ExpressionBindings.AddRange(new DevExpress.XtraReports.UI.ExpressionBinding[] {
new DevExpress.XtraReports.UI.ExpressionBinding("BeforePrint", "ImageSource", "[Icon25]")});
this.pictureBox3.LocationFloat = new DevExpress.Utils.PointFloat(2.083333F, 0F);
this.pictureBox3.Name = "pictureBox3";
this.pictureBox3.SizeF = new System.Drawing.SizeF(97.47245F, 25F);
this.pictureBox3.Sizing = DevExpress.XtraPrinting.ImageSizeMode.ZoomImage;
//
// GroupFooter1
//
this.GroupFooter1.Controls.AddRange(new DevExpress.XtraReports.UI.XRControl[] {
this.label2});
this.GroupFooter1.GroupUnion = DevExpress.XtraReports.UI.GroupFooterUnion.WithLastDetail;
this.GroupFooter1.HeightF = 6F;
this.GroupFooter1.Name = "GroupFooter1";
//
// label2
//
this.label2.Borders = DevExpress.XtraPrinting.BorderSide.None;
this.label2.LocationFloat = new DevExpress.Utils.PointFloat(0F, 0F);
this.label2.Name = "label2";
this.label2.SizeF = new System.Drawing.SizeF(650F, 2.08F);
this.label2.StyleName = "GroupFooterBackground3";
this.label2.StylePriority.UseBorders = false;
//
// sqlDataSource1
//
this.sqlDataSource1.ConnectionName = "NWindConnectionString";
this.sqlDataSource1.Name = "sqlDataSource1";
columnExpression1.ColumnName = "CategoryID";
table4.Name = "Categories";
columnExpression1.Table = table4;
column1.Expression = columnExpression1;
columnExpression2.ColumnName = "CategoryName";
columnExpression2.Table = table4;
column2.Expression = columnExpression2;
columnExpression3.ColumnName = "Description";
columnExpression3.Table = table4;
column3.Expression = columnExpression3;
columnExpression4.ColumnName = "Picture";
columnExpression4.Table = table4;
column4.Expression = columnExpression4;
columnExpression5.ColumnName = "Icon17";
columnExpression5.Table = table4;
column5.Expression = columnExpression5;
columnExpression6.ColumnName = "Icon25";
columnExpression6.Table = table4;
column6.Expression = columnExpression6;
selectQuery1.Columns.Add(column1);
selectQuery1.Columns.Add(column2);
selectQuery1.Columns.Add(column3);
selectQuery1.Columns.Add(column4);
selectQuery1.Columns.Add(column5);
selectQuery1.Columns.Add(column6);
selectQuery1.Name = "Categories";
selectQuery1.Tables.Add(table4);
this.sqlDataSource1.Queries.AddRange(new DevExpress.DataAccess.Sql.SqlQuery[] {
selectQuery1});
this.sqlDataSource1.ResultSchemaSerializable = resources.GetString("sqlDataSource1.ResultSchemaSerializable");
//
// Title
//
this.Title.BackColor = System.Drawing.Color.Transparent;
this.Title.BorderColor = System.Drawing.Color.Black;
this.Title.Borders = DevExpress.XtraPrinting.BorderSide.None;
this.Title.BorderWidth = 1F;
this.Title.Font = new DevExpress.Drawing.DXFont("Arial", 14.25F);
this.Title.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(70)))), ((int)(((byte)(80)))));
this.Title.Name = "Title";
this.Title.Padding = new DevExpress.XtraPrinting.PaddingInfo(6, 6, 0, 0, 100F);
//
// GroupCaption1
//
this.GroupCaption1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(181)))), ((int)(((byte)(211)))), ((int)(((byte)(142)))));
this.GroupCaption1.BorderColor = System.Drawing.Color.White;
this.GroupCaption1.Borders = DevExpress.XtraPrinting.BorderSide.Bottom;
this.GroupCaption1.BorderWidth = 2F;
this.GroupCaption1.Font = new DevExpress.Drawing.DXFont("Arial", 8.25F, DevExpress.Drawing.DXFontStyle.Bold);
this.GroupCaption1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(228)))), ((int)(((byte)(228)))), ((int)(((byte)(228)))));
this.GroupCaption1.Name = "GroupCaption1";
this.GroupCaption1.Padding = new DevExpress.XtraPrinting.PaddingInfo(6, 2, 0, 0, 100F);
this.GroupCaption1.TextAlignment = DevExpress.XtraPrinting.TextAlignment.MiddleLeft;
//
// GroupData1
//
this.GroupData1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(181)))), ((int)(((byte)(211)))), ((int)(((byte)(142)))));
this.GroupData1.BorderColor = System.Drawing.Color.White;
this.GroupData1.Borders = DevExpress.XtraPrinting.BorderSide.Bottom;
this.GroupData1.BorderWidth = 2F;
this.GroupData1.Font = new DevExpress.Drawing.DXFont("Arial", 8.25F, DevExpress.Drawing.DXFontStyle.Bold);
this.GroupData1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(70)))), ((int)(((byte)(80)))));
this.GroupData1.Name = "GroupData1";
this.GroupData1.Padding = new DevExpress.XtraPrinting.PaddingInfo(6, 2, 0, 0, 100F);
this.GroupData1.TextAlignment = DevExpress.XtraPrinting.TextAlignment.MiddleLeft;
//
// DetailCaption1
//
this.DetailCaption1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(181)))), ((int)(((byte)(211)))), ((int)(((byte)(142)))));
this.DetailCaption1.BorderColor = System.Drawing.Color.White;
this.DetailCaption1.Borders = DevExpress.XtraPrinting.BorderSide.Left;
this.DetailCaption1.BorderWidth = 2F;
this.DetailCaption1.Font = new DevExpress.Drawing.DXFont("Arial", 8.25F, DevExpress.Drawing.DXFontStyle.Bold);
this.DetailCaption1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(70)))), ((int)(((byte)(80)))));
this.DetailCaption1.Name = "DetailCaption1";
this.DetailCaption1.Padding = new DevExpress.XtraPrinting.PaddingInfo(6, 6, 0, 0, 100F);
this.DetailCaption1.TextAlignment = DevExpress.XtraPrinting.TextAlignment.MiddleLeft;
//
// DetailData1
//
this.DetailData1.BorderColor = System.Drawing.Color.Transparent;
this.DetailData1.Borders = DevExpress.XtraPrinting.BorderSide.Left;
this.DetailData1.BorderWidth = 2F;
this.DetailData1.Font = new DevExpress.Drawing.DXFont("Arial", 8.25F);
this.DetailData1.ForeColor = System.Drawing.Color.Black;
this.DetailData1.Name = "DetailData1";
this.DetailData1.Padding = new DevExpress.XtraPrinting.PaddingInfo(6, 6, 0, 0, 100F);
this.DetailData1.TextAlignment = DevExpress.XtraPrinting.TextAlignment.MiddleLeft;
//
// GroupFooterBackground3
//
this.GroupFooterBackground3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(109)))), ((int)(((byte)(117)))), ((int)(((byte)(129)))));
this.GroupFooterBackground3.BorderColor = System.Drawing.Color.White;
this.GroupFooterBackground3.Borders = DevExpress.XtraPrinting.BorderSide.Bottom;
this.GroupFooterBackground3.BorderWidth = 2F;
this.GroupFooterBackground3.Font = new DevExpress.Drawing.DXFont("Arial", 8.25F, DevExpress.Drawing.DXFontStyle.Bold);
this.GroupFooterBackground3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(228)))), ((int)(((byte)(228)))), ((int)(((byte)(228)))));
this.GroupFooterBackground3.Name = "GroupFooterBackground3";
this.GroupFooterBackground3.Padding = new DevExpress.XtraPrinting.PaddingInfo(6, 2, 0, 0, 100F);
this.GroupFooterBackground3.TextAlignment = DevExpress.XtraPrinting.TextAlignment.MiddleLeft;
//
// DetailData3_Odd
//
this.DetailData3_Odd.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(243)))), ((int)(((byte)(245)))), ((int)(((byte)(248)))));
this.DetailData3_Odd.BorderColor = System.Drawing.Color.Transparent;
this.DetailData3_Odd.Borders = DevExpress.XtraPrinting.BorderSide.None;
this.DetailData3_Odd.BorderWidth = 1F;
this.DetailData3_Odd.Font = new DevExpress.Drawing.DXFont("Arial", 8.25F);
this.DetailData3_Odd.ForeColor = System.Drawing.Color.Black;
this.DetailData3_Odd.Name = "DetailData3_Odd";
this.DetailData3_Odd.Padding = new DevExpress.XtraPrinting.PaddingInfo(6, 6, 0, 0, 100F);
this.DetailData3_Odd.TextAlignment = DevExpress.XtraPrinting.TextAlignment.MiddleLeft;
//
// PageInfo
//
this.PageInfo.Font = new DevExpress.Drawing.DXFont("Arial", 8.25F, DevExpress.Drawing.DXFontStyle.Bold);
this.PageInfo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(70)))), ((int)(((byte)(80)))));
this.PageInfo.Name = "PageInfo";
this.PageInfo.Padding = new DevExpress.XtraPrinting.PaddingInfo(6, 6, 0, 0, 100F);
//
// TestReport
//
this.Bands.AddRange(new DevExpress.XtraReports.UI.Band[] {
this.TopMargin,
this.BottomMargin,
this.ReportHeader,
this.GroupHeader1,
this.GroupHeader2,
this.Detail,
this.GroupFooter1});
this.ComponentStorage.AddRange(new System.ComponentModel.IComponent[] {
this.sqlDataSource1});
this.DataMember = "Categories";
this.DataSource = this.sqlDataSource1;
this.Font = new DevExpress.Drawing.DXFont("Arial", 9.75F);
this.StyleSheet.AddRange(new DevExpress.XtraReports.UI.XRControlStyle[] {
this.Title,
this.GroupCaption1,
this.GroupData1,
this.DetailCaption1,
this.DetailData1,
this.GroupFooterBackground3,
this.DetailData3_Odd,
this.PageInfo});
this.Version = "22.2";
((System.ComponentModel.ISupportInitialize)(this.table1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.table2)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.table3)).EndInit();
((System.ComponentModel.ISupportInitialize)(this)).EndInit();
}
#endregion
private DevExpress.XtraReports.UI.TopMarginBand TopMargin;
private DevExpress.XtraReports.UI.BottomMarginBand BottomMargin;
private DevExpress.XtraReports.UI.XRPageInfo pageInfo1;
private DevExpress.XtraReports.UI.XRPageInfo pageInfo2;
private DevExpress.XtraReports.UI.ReportHeaderBand ReportHeader;
private DevExpress.XtraReports.UI.XRLabel label1;
private DevExpress.XtraReports.UI.GroupHeaderBand GroupHeader1;
private DevExpress.XtraReports.UI.XRTable table1;
private DevExpress.XtraReports.UI.XRTableRow tableRow1;
private DevExpress.XtraReports.UI.XRTableCell tableCell1;
private DevExpress.XtraReports.UI.XRTableCell tableCell2;
private DevExpress.XtraReports.UI.GroupHeaderBand GroupHeader2;
private DevExpress.XtraReports.UI.XRTable table2;
private DevExpress.XtraReports.UI.XRTableRow tableRow2;
private DevExpress.XtraReports.UI.XRTableCell tableCell3;
private DevExpress.XtraReports.UI.XRTableCell tableCell4;
private DevExpress.XtraReports.UI.XRTableCell tableCell5;
private DevExpress.XtraReports.UI.XRTableCell tableCell6;
private DevExpress.XtraReports.UI.XRTableCell tableCell7;
private DevExpress.XtraReports.UI.DetailBand Detail;
private DevExpress.XtraReports.UI.XRTable table3;
private DevExpress.XtraReports.UI.XRTableRow tableRow3;
private DevExpress.XtraReports.UI.XRTableCell tableCell8;
private DevExpress.XtraReports.UI.XRTableCell tableCell9;
private DevExpress.XtraReports.UI.XRTableCell tableCell10;
private DevExpress.XtraReports.UI.XRPictureBox pictureBox1;
private DevExpress.XtraReports.UI.XRTableCell tableCell11;
private DevExpress.XtraReports.UI.XRPictureBox pictureBox2;
private DevExpress.XtraReports.UI.XRTableCell tableCell12;
private DevExpress.XtraReports.UI.XRPictureBox pictureBox3;
private DevExpress.XtraReports.UI.GroupFooterBand GroupFooter1;
private DevExpress.XtraReports.UI.XRLabel label2;
private DevExpress.DataAccess.Sql.SqlDataSource sqlDataSource1;
private DevExpress.XtraReports.UI.XRControlStyle Title;
private DevExpress.XtraReports.UI.XRControlStyle GroupCaption1;
private DevExpress.XtraReports.UI.XRControlStyle GroupData1;
private DevExpress.XtraReports.UI.XRControlStyle DetailCaption1;
private DevExpress.XtraReports.UI.XRControlStyle DetailData1;
private DevExpress.XtraReports.UI.XRControlStyle GroupFooterBackground3;
private DevExpress.XtraReports.UI.XRControlStyle DetailData3_Odd;
private DevExpress.XtraReports.UI.XRControlStyle PageInfo;
}
}

View file

@ -0,0 +1,9 @@
namespace Erp.Reports.PredefinedReports;
public partial class TestReport : DevExpress.XtraReports.UI.XtraReport
{
public TestReport()
{
InitializeComponent();
}
}

View file

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="sqlDataSource1.ResultSchemaSerializable" xml:space="preserve">
<value>PERhdGFTZXQgTmFtZT0ic3FsRGF0YVNvdXJjZTEiPjxWaWV3IE5hbWU9IkNhdGVnb3JpZXMiPjxGaWVsZCBOYW1lPSJDYXRlZ29yeUlEIiBUeXBlPSJJbnQ2NCIgLz48RmllbGQgTmFtZT0iQ2F0ZWdvcnlOYW1lIiBUeXBlPSJTdHJpbmciIC8+PEZpZWxkIE5hbWU9IkRlc2NyaXB0aW9uIiBUeXBlPSJTdHJpbmciIC8+PEZpZWxkIE5hbWU9IlBpY3R1cmUiIFR5cGU9IkJ5dGVBcnJheSIgLz48RmllbGQgTmFtZT0iSWNvbjE3IiBUeXBlPSJCeXRlQXJyYXkiIC8+PEZpZWxkIE5hbWU9Ikljb24yNSIgVHlwZT0iQnl0ZUFycmF5IiAvPjwvVmlldz48L0RhdGFTZXQ+</value>
</data>
</root>

View file

@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DevExpress.DataAccess.Json;
using DevExpress.DataAccess.Web;
using DevExpress.DataAccess.Wizard.Services;
using Erp.Reports.HttpApi.Host.Data;
namespace Erp.Platform.ReportServices;
public class CustomDataSourceWizardJsonDataConnectionStorage : IDataSourceWizardJsonConnectionStorage
{
protected LegacyReportDbContext DbContext { get; }
public CustomDataSourceWizardJsonDataConnectionStorage(LegacyReportDbContext dbContext)
{
DbContext = dbContext;
}
public List<JsonDataConnectionDescription> GetConnections()
{
return DbContext.JsonDataConnections.ToList();
}
bool IJsonConnectionStorageService.CanSaveConnection { get { return DbContext.JsonDataConnections != null; } }
bool IJsonConnectionStorageService.ContainsConnection(string connectionName)
{
return GetConnections().Any(x => x.Name == connectionName);
}
IEnumerable<JsonDataConnection> IJsonConnectionStorageService.GetConnections()
{
return GetConnections().Select(x => CreateJsonDataConnectionFromString(x));
}
JsonDataConnection IJsonDataConnectionProviderService.GetJsonDataConnection(string name)
{
var connection = GetConnections().FirstOrDefault(x => x.Name == name);
if (connection == null)
throw new InvalidOperationException();
return CreateJsonDataConnectionFromString(connection);
}
void IJsonConnectionStorageService.SaveConnection(string connectionName, JsonDataConnection dataConnection, bool saveCredentials)
{
var connections = GetConnections();
var connectionString = dataConnection.CreateConnectionString();
foreach (var connection in connections)
{
if (connection.Name == connectionName)
{
connection.ConnectionString = connectionString;
DbContext.SaveChanges();
return;
}
}
DbContext.JsonDataConnections.Add(new JsonDataConnectionDescription() { Name = connectionName, ConnectionString = connectionString });
DbContext.SaveChanges();
}
public static JsonDataConnection CreateJsonDataConnectionFromString(DataConnection dataConnection)
{
return new JsonDataConnection(dataConnection.ConnectionString) { StoreConnectionNameOnly = true, Name = dataConnection.Name };
}
}

View file

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DevExpress.DataAccess.Json;
using DevExpress.DataAccess.Web;
using Erp.Reports.HttpApi.Host.Data;
namespace Erp.Platform.ReportServices;
public class CustomJsonDataConnectionProviderFactory : IJsonDataConnectionProviderFactory
{
protected LegacyReportDbContext DbContext { get; }
public CustomJsonDataConnectionProviderFactory(LegacyReportDbContext dbContext)
{
DbContext = dbContext;
}
public IJsonDataConnectionProviderService Create()
{
return new WebDocumentViewerJsonDataConnectionProvider(DbContext.JsonDataConnections.ToList());
}
}
public class WebDocumentViewerJsonDataConnectionProvider : IJsonDataConnectionProviderService
{
readonly IEnumerable<DataConnection> jsonDataConnections;
public WebDocumentViewerJsonDataConnectionProvider(IEnumerable<DataConnection> jsonDataConnections)
{
this.jsonDataConnections = jsonDataConnections;
}
public JsonDataConnection GetJsonDataConnection(string name)
{
var connection = jsonDataConnections.FirstOrDefault(x => x.Name == name);
if (connection == null)
throw new InvalidOperationException();
return CustomDataSourceWizardJsonDataConnectionStorage.CreateJsonDataConnectionFromString(connection);
}
}

View file

@ -0,0 +1,83 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using DevExpress.XtraReports.UI;
using Erp.Reports.EntityFrameworkCore;
using System;
using Erp.Reports.PredefinedReports;
namespace Erp.Platform.ReportServices;
public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extensions.ReportStorageWebExtension
{
protected ErpReportsDbContext DbContext { get; set; }
public CustomReportStorageWebExtension(ErpReportsDbContext dbContext)
{
this.DbContext = dbContext;
}
public override bool CanSetData(string url)
{
return true;
}
public override bool IsValidUrl(string url)
{
return true;
}
public override byte[] GetData(string url)
{
var reportData = DbContext.ReportDefinitions.FirstOrDefault(x => x.Name == url);
if (reportData != null)
return reportData.Content;
if (ReportsFactory.Reports.ContainsKey(url))
{
using var ms = new MemoryStream();
using XtraReport report = ReportsFactory.Reports[url]();
report.SaveLayoutToXml(ms);
return ms.ToArray();
}
throw new DevExpress.XtraReports.Web.ClientControls.FaultException($"Could not find report '{url}'.");
}
public override Dictionary<string, string> GetUrls()
{
return DbContext.ReportDefinitions
.ToList()
.Select(x => x.Name)
.Union(ReportsFactory.Reports.Select(x => x.Key))
.ToDictionary<string, string>(x => x);
}
public override void SetData(XtraReport report, string url)
{
using var stream = new MemoryStream();
report.SaveLayoutToXml(stream);
var reportData = DbContext.ReportDefinitions.FirstOrDefault(x => x.Name == url);
if (reportData == null)
{
var newReport = new Erp.Reports.ReportDefinitions.ReportDefinition(
Guid.NewGuid(),
url,
url,
stream.ToArray()
);
DbContext.ReportDefinitions.Add(newReport);
}
else
{
reportData.UpdateContent(stream.ToArray());
}
DbContext.SaveChanges();
}
public override string SetNewData(XtraReport report, string defaultUrl)
{
SetData(report, defaultUrl);
return defaultUrl;
}
}

View file

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DevExpress.DataAccess.ConnectionParameters;
using DevExpress.DataAccess.Sql;
using DevExpress.DataAccess.Web;
using DevExpress.DataAccess.Wizard.Services;
using Erp.Reports.HttpApi.Host.Data;
namespace Erp.Platform.ReportServices;
public class CustomSqlDataConnectionProviderFactory : IConnectionProviderFactory
{
private readonly LegacyReportDbContext reportDbContext;
public CustomSqlDataConnectionProviderFactory(LegacyReportDbContext reportDbContext)
{
this.reportDbContext = reportDbContext;
}
public IConnectionProviderService Create()
{
return new CustomSqlConnectionProviderService(reportDbContext.SqlDataConnections.ToList());
}
}
public class CustomSqlConnectionProviderService : IConnectionProviderService
{
readonly IEnumerable<DataConnection> sqlDataConnections;
public CustomSqlConnectionProviderService(IEnumerable<DataConnection> sqlDataConnections)
{
this.sqlDataConnections = sqlDataConnections;
}
public SqlDataConnection LoadConnection(string connectionName)
{
var sqlDataConnectionData = sqlDataConnections.FirstOrDefault(x => x.Name == connectionName);
if (sqlDataConnectionData == null)
throw new InvalidOperationException();
if (string.IsNullOrEmpty(sqlDataConnectionData.ConnectionString))
throw new KeyNotFoundException($"Connection string '{connectionName}' not found.");
var connectionParameters = new CustomStringConnectionParameters(sqlDataConnectionData.ConnectionString);
return new SqlDataConnection(connectionName, connectionParameters);
}
}

View file

@ -0,0 +1,27 @@
using System.Collections.Generic;
using System.Linq;
using DevExpress.DataAccess.ConnectionParameters;
using DevExpress.DataAccess.Web;
using Erp.Reports.HttpApi.Host.Data;
namespace Erp.Platform.ReportServices;
public class CustomSqlDataSourceWizardConnectionStringsProvider : IDataSourceWizardConnectionStringsProvider
{
readonly LegacyReportDbContext reportDataContext;
public CustomSqlDataSourceWizardConnectionStringsProvider(LegacyReportDbContext reportDataContext)
{
this.reportDataContext = reportDataContext;
}
Dictionary<string, string> IDataSourceWizardConnectionStringsProvider.GetConnectionDescriptions()
{
return reportDataContext.SqlDataConnections.ToDictionary(x => x.Name, x => x.DisplayName);
}
DataConnectionParametersBase IDataSourceWizardConnectionStringsProvider.GetDataConnectionParameters(string name)
{
return null;
}
}

96
ui/package-lock.json generated
View file

@ -29,6 +29,7 @@
"axios": "^1.7.9", "axios": "^1.7.9",
"classnames": "^2.5.1", "classnames": "^2.5.1",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"devexpress-reporting-react": "25.1.7",
"devextreme": "25.1.7", "devextreme": "25.1.7",
"devextreme-dist": "25.1.7", "devextreme-dist": "25.1.7",
"devextreme-react": "25.1.7", "devextreme-react": "25.1.7",
@ -1714,6 +1715,22 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@devexpress/analytics-core": {
"version": "25.1.7",
"resolved": "https://registry.npmjs.org/@devexpress/analytics-core/-/analytics-core-25.1.7.tgz",
"integrity": "sha512-3H98zZe4uylgiBdIi65z4TIJQa8owrpDVR6o6ACxjH0PtjCVgZr5MgExGEobYrjqK8GUCglUCFwsUDgRVTDlcA==",
"license": "SEE LICENSE IN README.md",
"peer": true,
"dependencies": {
"@types/jquery": "^3.1.1",
"ace-builds": "^1.4.13",
"jquery": "^3.1.1",
"knockout": "~3.5.0"
},
"peerDependencies": {
"devextreme": "25.1.7"
}
},
"node_modules/@devexpress/utils": { "node_modules/@devexpress/utils": {
"version": "1.4.8", "version": "1.4.8",
"resolved": "https://registry.npmjs.org/@devexpress/utils/-/utils-1.4.8.tgz", "resolved": "https://registry.npmjs.org/@devexpress/utils/-/utils-1.4.8.tgz",
@ -3552,6 +3569,16 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"node_modules/@types/jquery": {
"version": "3.5.33",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.33.tgz",
"integrity": "sha512-SeyVJXlCZpEki5F0ghuYe+L+PprQta6nRZqhONt9F13dWBtR/ftoaIbdRQ7cis7womE+X2LKhsDdDtkkDhJS6g==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/sizzle": "*"
}
},
"node_modules/@types/json-schema": { "node_modules/@types/json-schema": {
"version": "7.0.15", "version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@ -3596,9 +3623,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/prop-types": { "node_modules/@types/prop-types": {
"version": "15.7.15", "version": "15.7.13",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz",
"integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/raf": { "node_modules/@types/raf": {
@ -3622,7 +3649,6 @@
"version": "18.3.7", "version": "18.3.7",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
"integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
"devOptional": true,
"license": "MIT", "license": "MIT",
"peerDependencies": { "peerDependencies": {
"@types/react": "^18.0.0" "@types/react": "^18.0.0"
@ -3692,6 +3718,13 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/sizzle": {
"version": "2.3.10",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.10.tgz",
"integrity": "sha512-TC0dmN0K8YcWEAEfiPi5gJP14eJe30TTGjkvek3iM/1NdHHsdCA/Td6GvNndMOo/iSnIsZ4HuuhrYPDAmbxzww==",
"license": "MIT",
"peer": true
},
"node_modules/@types/trusted-types": { "node_modules/@types/trusted-types": {
"version": "2.0.7", "version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
@ -4206,6 +4239,13 @@
"node": ">=6.5" "node": ">=6.5"
} }
}, },
"node_modules/ace-builds": {
"version": "1.43.5",
"resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.43.5.tgz",
"integrity": "sha512-iH5FLBKdB7SVn9GR37UgA/tpQS8OTWIxWAuq3Ofaw+Qbc69FfPXsXd9jeW7KRG2xKpKMqBDnu0tHBrCWY5QI7A==",
"license": "BSD-3-Clause",
"peer": true
},
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.15.0", "version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
@ -5762,6 +5802,40 @@
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
"license": "0BSD" "license": "0BSD"
}, },
"node_modules/devexpress-reporting": {
"version": "25.1.7",
"resolved": "https://registry.npmjs.org/devexpress-reporting/-/devexpress-reporting-25.1.7.tgz",
"integrity": "sha512-4Ffvj6bgzII63hAfq3u53w0VypDd4HRJHQnQv4yqWm5VyW+7V7ztLLeNQRerbyqjzdhfkN2qyXqFV+3YxZwoEg==",
"license": "SEE LICENSE IN README.md",
"peer": true,
"dependencies": {
"ace-builds": "^1.4.13",
"jquery": "^3.1.1",
"knockout": "~3.5.0"
},
"peerDependencies": {
"@devexpress/analytics-core": "25.1.7"
}
},
"node_modules/devexpress-reporting-react": {
"version": "25.1.7",
"resolved": "https://registry.npmjs.org/devexpress-reporting-react/-/devexpress-reporting-react-25.1.7.tgz",
"integrity": "sha512-2PbTbqsAFfZec+BgGSHqU/SBpyyXWps9qx+UD1eC09s7sIHdBvooGMwPI9Vb2+FUiqq1vcDKPxH1hLUqAJYZvg==",
"license": "SEE LICENSE IN README.md",
"dependencies": {
"prop-types": "^15.8.1"
},
"peerDependencies": {
"@devexpress/analytics-core": "25.1.7",
"@types/prop-types": "15.7.13",
"@types/react": "^18.0.0 || ^19.0.0",
"@types/react-dom": "^18.0.0 || ^19.0.0",
"devexpress-reporting": "25.1.7",
"devextreme-react": "25.1.7",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
}
},
"node_modules/devextreme": { "node_modules/devextreme": {
"version": "25.1.7", "version": "25.1.7",
"resolved": "https://registry.npmjs.org/devextreme/-/devextreme-25.1.7.tgz", "resolved": "https://registry.npmjs.org/devextreme/-/devextreme-25.1.7.tgz",
@ -8691,6 +8765,13 @@
"jiti": "bin/jiti.js" "jiti": "bin/jiti.js"
} }
}, },
"node_modules/jquery": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==",
"license": "MIT",
"peer": true
},
"node_modules/js-sha3": { "node_modules/js-sha3": {
"version": "0.8.0", "version": "0.8.0",
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
@ -8914,6 +8995,13 @@
"json-buffer": "3.0.1" "json-buffer": "3.0.1"
} }
}, },
"node_modules/knockout": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/knockout/-/knockout-3.5.1.tgz",
"integrity": "sha512-wRJ9I4az0QcsH7A4v4l0enUpkS++MBx0BnL/68KaLzJg7x1qmbjSlwEoCNol7KTYZ+pmtI7Eh2J0Nu6/2Z5J/Q==",
"license": "MIT",
"peer": true
},
"node_modules/language-subtag-registry": { "node_modules/language-subtag-registry": {
"version": "0.3.23", "version": "0.3.23",
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz",

View file

@ -40,6 +40,7 @@
"devextreme": "25.1.7", "devextreme": "25.1.7",
"devextreme-dist": "25.1.7", "devextreme-dist": "25.1.7",
"devextreme-react": "25.1.7", "devextreme-react": "25.1.7",
"devexpress-reporting-react": "25.1.7",
"easy-peasy": "^6.0.5", "easy-peasy": "^6.0.5",
"emoji-picker-react": "^4.14.1", "emoji-picker-react": "^4.14.1",
"exceljs": "^4.4.0", "exceljs": "^4.4.0",

View file

@ -0,0 +1,29 @@
import React from 'react'
import { Container } from '@/components/shared'
import { Helmet } from 'react-helmet'
import ReportViewer, { RequestOptions } from 'devexpress-reporting-react/dx-report-viewer'
import { useLocalization } from '@/utils/hooks/useLocalization'
import 'devextreme/dist/css/dx.light.css'
import '@devexpress/analytics-core/dist/css/dx-analytics.common.css'
import '@devexpress/analytics-core/dist/css/dx-analytics.light.css'
import 'devexpress-reporting/dist/css/dx-webdocumentviewer.css'
const DevexpressReportViewer: React.FC = () => {
const { translate } = useLocalization()
return (
<Container>
<Helmet
titleTemplate="%s | Erp Platform"
title={translate('::' + 'App.Reports')}
defaultTitle="Erp Platform"
></Helmet>
<ReportViewer reportUrl="TestReport">
<RequestOptions host="https://localhost:44344/" invokeAction="DXXRDV" />
</ReportViewer>
</Container>
)
}
export default DevexpressReportViewer