Compare commits

..

47 Commits

Author SHA1 Message Date
Developer 02
a757749767 Refactor SQL execution and enhance envelope creation
- Updated `ISQLExecutor<TEntity>` to inherit from new `ISQLExecutor` interface for improved SQL execution flexibility.
- Added package references for `Dapper` and `DigitalData.Core` in project files.
- Modified `CreateEnvelopeCommand` to include `[BindNever]` on `UserId` for better model binding control.
- Refactored `CreateEnvelopeCommandHandler` to use `DynamicParameters` for SQL parameter handling.
- Updated `CreateEnvelopeSQL` to select only the top record for performance.
- Introduced `GetIdOrDefault` method in `ControllerExtensions` for user ID retrieval with fallback.
- Added `CreateAsync` method in `EnvelopeController` for envelope creation using `IMediator`.
- Ensured infrastructure project has necessary package references.
- Refactored `SQLExecutor` to implement new interface and simplified constructor.
- Introduced `SQLExecutorBaseEntity` for entity-specific SQL command execution.
2025-05-05 10:15:36 +02:00
Developer 02
5166f41941 Refactor CreateEnvelopeResponse to use record type
Changed CreateEnvelopeResponse from a class to a record type for improved immutability and conciseness. The new definition inherits from ReadEnvelopeResponse, reusing its functionality. Added XML documentation comments for better clarity on each parameter.
2025-05-05 02:06:33 +02:00
Developer 02
928f2a7780 Add AutoMapper profile for envelope mapping
Introduces `CreateEnvelopeMappingProfile` class to define
mapping between `Envelope` entity and `CreateEnvelopeResponse`
DTO using AutoMapper's `CreateMap` method.
2025-05-05 02:03:56 +02:00
Developer 02
d46aa6e2b8 Add envelope creation functionality and SQL integration
- Updated `EnvelopeGenerator.Application.csproj` to include `Microsoft.Data.SqlClient` package.
- Refactored `CreateEnvelopeReceiverCommand` to inherit from `CreateEnvelopeCommand`.
- Enhanced `CreateEnvelopeSQL` with a SQL script for envelope creation.
- Introduced `CreateEnvelopeCommand` to encapsulate envelope creation data.
- Added `CreateEnvelopeCommandHandler` to process commands and interact with the database.
- Created `CreateEnvelopeResponse` class for handling responses from envelope creation.
2025-05-05 02:01:01 +02:00
Developer 02
7cffc3f7bc fix: Change SQLExecutor service registration to scoped
Updated the `AddSQLExecutor<T>` method in the `DIExtensions` class to register `ISQLExecutor<T>` as a scoped service instead of a singleton. This ensures that a new instance of `SQLExecutor<T>` is created for each request within the same scope, improving resource management and request isolation.
2025-05-05 00:36:00 +02:00
Developer 02
841da3c261 Refactor DI extensions and add SQL executor support
Removed `DIExtensions.cs` and integrated its content into `DependencyExtensions.cs`, enhancing the dependency injection setup with repository and SQL executor registrations. Added a new `CreateEnvelopeSQL` class implementing the `ISQL<Envelope>` interface, currently with a placeholder implementation.
2025-05-05 00:31:58 +02:00
Developer 02
adbfd69418 feat(IQueryExecutor): IQuery umbenennen 2025-04-30 16:49:26 +02:00
Developer 02
1e54b775a2 refactor: Vereinfachung der SQLExecutor-Implementierung zur Rückgabe von IQueryExecutor
- Aktualisiert `SQLExecutor<T>` um `ISQLExecutor<T>` zu implementieren und `IQueryExecutor<T>` für die weitere Abfrageausführung zurückzugeben.
- Umstrukturierte Methoden zur Verwendung von `ToExecutor()` für die Konvertierung von rohen SQL-Abfragen in einen `IQueryExecutor<T>`.
- Geänderter Konstruktor, um `IServiceProvider` für die Injektion von Abhängigkeiten von benutzerdefinierten SQL-Abfrageklassen zu akzeptieren.
2025-04-29 17:14:38 +02:00
Developer 02
6e82b24578 feat: Implement QueryExecutor for executing queries using IQueryable
- Added a record `QueryExecutor<TEntity>` implementing `IQueryExecutor<TEntity>` for executing common query operations like First, Single, and ToList both synchronously and asynchronously.
- Methods leverage the IQueryable interface to perform database queries for entity types.
2025-04-29 16:56:13 +02:00
Developer 02
5331efe3c1 feat(sql): Hinzufügen generischer Überladungen zu SQLExecutor unter Verwendung von ISQL<T> über DI
Es wurden Überladungen für ExecuteFirstAsync, ExecuteSingleAsync und ExecuteAllAsync
eingeführt, die SQL-Definitionen aus dem Dependency Injection Container mittels ISQL<T> auflösen.
Außerdem wurde ein Fehler bei der Verwendung der Direktive von .cs zu standardmäßigem Schnittstellenimport korrigiert.
2025-04-29 16:39:18 +02:00
Developer 02
3b4ad2960a feat: SQLExecutor-Klasse für die Ausführung von Roh-SQL-Abfragen mit Entity Framework Core hinzufügen 2025-04-29 16:26:26 +02:00
Developer 02
33048e185b feat(CreateEnvelopeReceiverCommandHandler): initialized 2025-04-29 14:41:21 +02:00
Developer 02
3ae1b94eb7 refactor(Login): Id in UserId umbenennen 2025-04-29 11:39:21 +02:00
Developer 02
3d1966a715 feat(Jenkinsfile): Als Beispiel erstellt 2025-04-29 09:34:57 +02:00
Developer 02
c173814b8d refactor(AuthController): Login-Methoden aktualisieren, um NotImplementedException zu werfen, nur um Swagger-Dokumentation bereitzustellen 2025-04-29 09:21:05 +02:00
Developer 02
a85397a363 refactor(auth): Refactoring der Login-Methoden für OpenAPI-Kompatibilität
– Die Login-Methoden wurden überarbeitet, um NotImplementedException auszulösen und OpenAPI (Swagger) und Skalar zu konfigurieren.
– Unnötige using-Anweisungen wurden entfernt, um den Code zu optimieren.
2025-04-28 16:49:46 +02:00
Developer 02
2d3987b81e Add JWT Bearer authentication support
- Integrated JWT Bearer authentication for API security.
- Replaced previous CookieAuthenticationDefaults with JwtBearerDefaults as the default authentication scheme.
- Configured JWT token validation with issuer, audience, and signing key parameters.
- Added handling for token retrieval from cookies or query strings when missing in the header.
- Updated the authentication configuration to support both Cookie and JWT authentication schemes.
- Enhanced security by validating JWT tokens against provided public keys.
2025-04-28 16:18:31 +02:00
Developer 02
875ff95278 feat(AuthTokenKeys): Erstellt, um Parameter für Authentifizierungs-Tokens zu konfigurieren.
- AuthTokenKeys aus der Konfiguration in Program.cs lesen.
 - Upgrade von Core.Abstractions auf 3.5
2025-04-28 15:49:40 +02:00
Developer 02
dcdf0844cb feat(Program): DeferredServiceProvider-Instanz erstellen und Fabrik einstellen 2025-04-28 15:08:07 +02:00
Developer 02
27e9de4709 chore(Core.Abstraction): Aktualisiert auf 3.4.4 2025-04-28 15:02:49 +02:00
Developer 02
e2bdc73b76 chore: auth-hub-client hinzufügen und konfigurieren 2025-04-28 14:15:45 +02:00
Developer 02
7abb3a6c8a chore(deps): NuGet-Paketversionen aktualisieren und DigitalData.Auth.Client hinzufügen 2025-04-28 10:47:55 +02:00
Developer 02
9183ba4da5 Merge branch 'feat/terminal' 2025-04-28 09:19:52 +02:00
Developer 02
08e2e91e9a feat(program): Konfiguration aus appsettings.json laden
Die Anwendung lädt nun Konfigurationseinstellungen aus einer "appsettings.json"-Datei im Basisverzeichnis.
Dies ermöglicht eine externe Konfiguration ohne Codeänderungen und unterstützt das Neuladen der Einstellungen zur Laufzeit bei Änderungen der Datei.
2025-04-28 09:16:24 +02:00
Developer 02
2966d64455 feat(terminal): ReadDocument-Befehl um PDF-Speicheroptionen erweitert
Optionen `save`, `dir` und `fileName` zum `ReadDocument`-Befehl hinzugefügt.
Wenn `save` aktiviert ist, wird das PDF an dem angegebenen oder dem Standardpfad gespeichert.
Ermöglicht dem Benutzer mehr Kontrolle über Speicherort und Dateinamen.
2025-04-25 19:33:29 +02:00
Developer 02
41cb2c2d93 fix(PDFBurnerParams): Verschieben in das Verzeichnis /FinalizeDocument 2025-04-25 11:39:59 +02:00
Developer 02
edd54ab302 Merge branch 'master' of http://git.dd:3000/AppStd/EnvelopeGenerator 2025-04-24 16:08:48 +02:00
Developer 02
51920089af feat(PDFBurner): PDFBurnerParams hinzufügen und Konfiguration binden 2025-04-24 16:08:05 +02:00
Developer01
5714c54385 Merge branch 'master' of http://git.dd:3000/AppStd/EnvelopeGenerator 2025-04-24 16:00:29 +02:00
Developer01
09d2640345 V 2.9.0.0 WISAG 2025-04-24 16:00:16 +02:00
Developer 02
82cb50b7e1 feat(PDFBurnerParams): erstellt, um PDFBurner zu konfigurieren 2025-04-24 15:50:08 +02:00
Developer 02
ff36dc47c1 refactor(PDFBurner): Logik hinzufügen, um den Unterschied zwischen FormField-Annotationen zu verringern 2025-04-24 15:29:22 +02:00
Developer 02
186f3c3319 Merge branch 'master' of http://git.dd:3000/AppStd/EnvelopeGenerator 2025-04-24 12:01:55 +02:00
Developer 02
276adda516 unnötige Protokollierung entfernt 2025-04-24 11:48:54 +02:00
Developer 02
ac0ae10fab unnötige Protokollierung entfernt 2025-04-24 11:47:11 +02:00
Developer01
3713669ec5 Merge 2025-04-24 11:45:38 +02:00
Developer 02
7f0131fc2d refactor(FinalizeDocumentJob): Update für detaillierte Protokollierung 2025-04-24 11:44:29 +02:00
Developer01
d9deb589d1 MS AdminTab 2025-04-24 11:43:55 +02:00
OlgunR
c961e9fffd Merge branch 'master' of http://git.dd:3000/AppStd/EnvelopeGenerator 2025-04-24 11:43:18 +02:00
OlgunR
ae31b1da0f Funktion zur Aufhebung der Formfelder im Signiervorgang - Class EnvelopeEditorController, Class FlattenFormFields 2025-04-24 11:42:50 +02:00
Developer 02
bf5faf53bd refactor(frmFinalizePDF): Aktualisieren von Button1_Click zum Öffnen von PDF nach dem Brennvorgang 2025-04-24 11:37:46 +02:00
Developer 02
9a74b448f2 Merge branch 'master' of http://git.dd:3000/AppStd/EnvelopeGenerator 2025-04-24 09:32:34 +02:00
Developer 02
784a834214 chore: auf 3.1.2 aufgerüstet 2025-04-24 09:28:27 +02:00
Developer01
3c5f5cb5f5 Neues Release plus Flatternformfleds RO 2025-04-24 08:56:33 +02:00
Developer01
4e2682a75d DocumentRotationChanged 2025-04-23 12:40:28 +02:00
Developer01
278d56c58d Merge branch 'master' of http://git.dd:3000/AppStd/EnvelopeGenerator 2025-04-23 12:38:02 +02:00
Developer01
9f71579c78 MS Neue Konstante 2025-04-23 12:37:57 +02:00
72 changed files with 1395 additions and 438 deletions

View File

@@ -0,0 +1,70 @@
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
/// <summary>
/// Provides methods for executing common queries on a given entity type.
/// This interface abstracts away the direct usage of ORM libraries (such as Entity Framework) for querying data
/// and provides asynchronous and synchronous operations for querying a collection or single entity.
/// </summary>
/// <typeparam name="TEntity">The type of the entity being queried.</typeparam>
public interface IQuery<TEntity>
{
/// <summary>
/// Asynchronously retrieves the first entity or a default value if no entity is found.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the entity or a default value.</returns>
public Task<TEntity?> FirstOrDefaultAsync();
/// <summary>
/// Asynchronously retrieves a single entity or a default value if no entity is found.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the entity or a default value.</returns>
public Task<TEntity?> SingleOrDefaultAsync();
/// <summary>
/// Asynchronously retrieves a list of entities.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the list of entities.</returns>
public Task<IEnumerable<TEntity>> ToListAsync();
/// <summary>
/// Asynchronously retrieves the first entity. Throws an exception if no entity is found.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the first entity.</returns>
public Task<TEntity> FirstAsync();
/// <summary>
/// Asynchronously retrieves a single entity. Throws an exception if no entity is found.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the single entity.</returns>
public Task<TEntity> SingleAsync();
/// <summary>
/// Synchronously retrieves the first entity or a default value if no entity is found.
/// </summary>
/// <returns>The first entity or a default value.</returns>
public TEntity? FirstOrDefault();
/// <summary>
/// Synchronously retrieves a single entity or a default value if no entity is found.
/// </summary>
/// <returns>The single entity or a default value.</returns>
public TEntity? SingleOrDefault();
/// <summary>
/// Synchronously retrieves a list of entities.
/// </summary>
/// <returns>The list of entities.</returns>
public IEnumerable<TEntity> ToList();
/// <summary>
/// Synchronously retrieves the first entity. Throws an exception if no entity is found.
/// </summary>
/// <returns>The first entity.</returns>
public TEntity First();
/// <summary>
/// Synchronously retrieves a single entity. Throws an exception if no entity is found.
/// </summary>
/// <returns>The single entity.</returns>
public TEntity Single();
}

View File

@@ -0,0 +1,20 @@
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
/// <summary>
/// Represents a raw SQL query contract.
/// </summary>
public interface ISQL
{
/// <summary>
/// Gets the raw SQL query string.
/// </summary>
string Raw { get; }
}
/// <summary>
/// Represents a typed SQL query contract for a specific entity.
/// </summary>
/// <typeparam name="TEntity">The type of the entity associated with the SQL query.</typeparam>
public interface ISQL<TEntity> : ISQL
{
}

View File

@@ -0,0 +1,27 @@
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
/// <summary>
/// Defines methods for executing raw SQL queries or custom SQL query classes and returning query executors for further operations.
/// Provides abstraction for raw SQL execution as well as mapping the results to <typeparamref name="TEntity"/> objects.
/// </summary>
/// <typeparam name="TEntity">The entity type to which the SQL query results will be mapped.</typeparam>
public interface ISQLExecutor<TEntity>: ISQLExecutor
{
/// <summary>
/// Executes a raw SQL query and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
/// </summary>
/// <param name="sql">The raw SQL query to execute.</param>
/// <param name="cancellation">Optional cancellation token for the operation.</param>
/// <param name="parameters">Optional parameters for the SQL query.</param>
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
IQuery<TEntity> Execute(string sql, CancellationToken cancellation = default, params object[] parameters);
/// <summary>
/// Executes a custom SQL query defined by a class that implements <see cref="ISQL{TEntity}"/> and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
/// </summary>
/// <typeparam name="TSQL">The type of the custom SQL query class implementing <see cref="ISQL{TEntity}"/>.</typeparam>
/// <param name="cancellation">Optional cancellation token for the operation.</param>
/// <param name="parameters">Optional parameters for the SQL query.</param>
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
IQuery<TEntity> Execute<TSQL>(CancellationToken cancellation = default, params object[] parameters) where TSQL : ISQL<TEntity>;
}

View File

@@ -0,0 +1,29 @@
using Dapper;
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
/// <summary>
///
/// </summary>
public interface ISQLExecutor
{
/// <summary>
/// Executes a raw SQL query and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
/// </summary>
/// <typeparam name="TEntity">The entity type to which the SQL query results will be mapped.</typeparam>
/// <param name="sql">The raw SQL query to execute.</param>
/// <param name="parameters">Parameters for the SQL query.</param>
/// <param name="cancellation">Optional cancellation token for the operation.</param>
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
Task<IEnumerable<TEntity>> Execute<TEntity>(string sql, DynamicParameters parameters, CancellationToken cancellation = default);
/// <summary>
/// Executes a custom SQL query defined by a class that implements <see cref="ISQL{TEntity}"/> and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
/// </summary>
/// <typeparam name="TEntity">The entity type to which the SQL query results will be mapped.</typeparam>
/// <typeparam name="TSQL">The type of the custom SQL query class implementing <see cref="ISQL{TEntity}"/>.</typeparam>
/// <param name="parameters">Parameters for the SQL query.</param>
/// <param name="cancellation">Optional cancellation token for the operation.</param>
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
Task<IEnumerable<TEntity>> Execute<TEntity, TSQL>(DynamicParameters parameters, CancellationToken cancellation = default) where TSQL : ISQL;
}

View File

@@ -3,23 +3,8 @@
/// <summary> /// <summary>
/// Represents the response for reading a document. /// Represents the response for reading a document.
/// </summary> /// </summary>
public class ReadDocumentResponse public class ReadDocumentResponse : ReadDocumentResponseBase
{ {
/// <summary>
/// The unique identifier of the document.
/// </summary>
public int Guid { get; init; }
/// <summary>
/// The identifier of the associated envelope.
/// </summary>
public int EnvelopeId { get; init; }
/// <summary>
/// The date and time when the document was added.
/// </summary>
public DateTime AddedWhen { get; init; }
/// <summary> /// <summary>
/// The binary data of the document, if available. /// The binary data of the document, if available.
/// </summary> /// </summary>

View File

@@ -0,0 +1,22 @@
namespace EnvelopeGenerator.Application.Documents.Queries.Read;
/// <summary>
/// Represents the response for reading a document.
/// </summary>
public class ReadDocumentResponseBase
{
/// <summary>
/// The unique identifier of the document.
/// </summary>
public int Guid { get; init; }
/// <summary>
/// The identifier of the associated envelope.
/// </summary>
public int EnvelopeId { get; init; }
/// <summary>
/// The date and time when the document was added.
/// </summary>
public DateTime AddedWhen { get; init; }
}

View File

@@ -13,13 +13,15 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" /> <PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" />
<PackageReference Include="DigitalData.Core.Application" Version="3.2.1" /> <PackageReference Include="DigitalData.Core.Application" Version="3.2.1" />
<PackageReference Include="DigitalData.Core.Client" Version="2.0.3" /> <PackageReference Include="DigitalData.Core.Client" Version="2.0.3" />
<PackageReference Include="DigitalData.Core.DTO" Version="2.0.1" /> <PackageReference Include="DigitalData.Core.DTO" Version="2.0.1" />
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.0.0" /> <PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.0.0" />
<PackageReference Include="MediatR" Version="12.5.0" /> <PackageReference Include="MediatR" Version="12.5.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
<PackageReference Include="Otp.NET" Version="1.4.0" /> <PackageReference Include="Otp.NET" Version="1.4.0" />
<PackageReference Include="QRCoder" Version="1.6.0" /> <PackageReference Include="QRCoder" Version="1.6.0" />
@@ -80,4 +82,8 @@
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Procedures\" />
</ItemGroup>
</Project> </Project>

View File

@@ -1,4 +1,5 @@
using MediatR; using EnvelopeGenerator.Application.Envelopes.Commands;
using MediatR;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create; namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
@@ -17,7 +18,7 @@ public record CreateEnvelopeReceiverCommand(
[Required] DocumentCreateCommand Document, [Required] DocumentCreateCommand Document,
[Required] IEnumerable<ReceiverGetOrCreateCommand> Receivers, [Required] IEnumerable<ReceiverGetOrCreateCommand> Receivers,
bool TFAEnabled = false bool TFAEnabled = false
) : IRequest; ) : CreateEnvelopeCommand(Title, Message, TFAEnabled), IRequest;
#region DTOs #region DTOs
/// <summary> /// <summary>

View File

@@ -0,0 +1,24 @@
using MediatR;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
/// <summary>
/// Handles the creation of an envelope along with its associated document and recipients.
/// This command processes the envelope data, including title, message, document content,
/// recipient list, and optional two-factor authentication settings.
/// </summary>
public class CreateEnvelopeReceiverCommandHandler : IRequestHandler<CreateEnvelopeReceiverCommand>
{
/// <summary>
/// Handles the execution of the <see cref="CreateEnvelopeReceiverCommand"/>.
/// Responsible for validating input data, creating or retrieving recipients, associating signatures,
/// and storing the envelope and document details.
/// </summary>
/// <param name="request">The command containing all necessary information to create an envelope.</param>
/// <param name="cancellationToken">Token to observe while waiting for the task to complete.</param>
/// <returns>A task representing the asynchronous operation.</returns>
public Task Handle(CreateEnvelopeReceiverCommand request, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}

View File

@@ -0,0 +1,26 @@
using MediatR;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
namespace EnvelopeGenerator.Application.Envelopes.Commands;
/// <summary>
/// Befehl zur Erstellung eines Umschlags.
/// </summary>
/// <param name="Title">Der Titel des Umschlags. Dies ist ein Pflichtfeld.</param>
/// <param name="Message">Die Nachricht, die im Umschlag enthalten sein soll. Dies ist ein Pflichtfeld.</param>
/// <param name="TFAEnabled">Gibt an, ob die Zwei-Faktor-Authentifizierung für den Umschlag aktiviert ist. Standardmäßig false.</param>
public record CreateEnvelopeCommand(
[Required] string Title,
[Required] string Message,
bool TFAEnabled = false
) : IRequest<CreateEnvelopeResponse?>
{
/// <summary>
/// Id of receiver
/// </summary>
[JsonIgnore]
[BindNever]
public int? UserId { get; set; }
};

View File

@@ -0,0 +1,48 @@
using AutoMapper;
using Dapper;
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
using Microsoft.Data.SqlClient;
namespace EnvelopeGenerator.Application.Envelopes.Commands;
/// <summary>
///
/// </summary>
public class CreateEnvelopeCommandHandler : IRequestHandler<CreateEnvelopeCommand, CreateEnvelopeResponse?>
{
private readonly ISQLExecutor<Envelope> _sqlExecutor;
private readonly IMapper _mapper;
/// <summary>
///
/// </summary>
/// <param name="sqlExecutor"></param>
/// <param name="mapper"></param>
public CreateEnvelopeCommandHandler(ISQLExecutor<Envelope> sqlExecutor, IMapper mapper)
{
_sqlExecutor = sqlExecutor;
_mapper = mapper;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<CreateEnvelopeResponse?> Handle(CreateEnvelopeCommand request, CancellationToken cancellationToken)
{
var parameters = new DynamicParameters();
parameters.Add("@UserId", request.UserId);
parameters.Add("@Title", request.Title);
parameters.Add("@TfaEnabled", request.TFAEnabled ? 1 : 0);
parameters.Add("@Message", request.Message);
var envelopes = await _sqlExecutor.Execute<Envelope, CreateEnvelopeSQL>(parameters, cancellationToken);
return _mapper.Map<CreateEnvelopeResponse>(envelopes.FirstOrDefault());
}
}

View File

@@ -0,0 +1,18 @@
using AutoMapper;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Envelopes.Commands;
/// <summary>
///
/// </summary>
public class CreateEnvelopeMappingProfile : Profile
{
/// <summary>
///
/// </summary>
public CreateEnvelopeMappingProfile()
{
CreateMap<Envelope, CreateEnvelopeResponse>();
}
}

View File

@@ -0,0 +1,20 @@
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
namespace EnvelopeGenerator.Application.Envelopes.Commands;
/// <summary>
///
/// </summary>
/// <param name="Id"><inheritdoc/></param>
/// <param name="UserId"><inheritdoc/></param>
/// <param name="Status"><inheritdoc/></param>
/// <param name="Uuid"><inheritdoc/></param>
/// <param name="Message"><inheritdoc/></param>
/// <param name="AddedWhen"><inheritdoc/></param>
/// <param name="ChangedWhen"><inheritdoc/></param>
/// <param name="Title"><inheritdoc/></param>
/// <param name="Language"><inheritdoc/></param>
/// <param name="TFAEnabled"><inheritdoc/></param>
/// <param name="User"><inheritdoc/></param>
public record CreateEnvelopeResponse(int Id, int UserId, int Status, string Uuid, string? Message, DateTime AddedWhen, DateTime? ChangedWhen, string? Title, string Language, bool TFAEnabled, DigitalData.UserManager.Domain.Entities.User User)
: ReadEnvelopeResponse(Id, UserId, Status, Uuid, Message, AddedWhen, ChangedWhen, Title, Language, TFAEnabled, User);

View File

@@ -0,0 +1,29 @@
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
using EnvelopeGenerator.Domain.Entities;
using Microsoft.Data.SqlClient;
namespace EnvelopeGenerator.Application.Envelopes.Commands;
/// <summary>
///
/// </summary>
public class CreateEnvelopeSQL : ISQL<Envelope>
{
/// <summary>
///
/// </summary>
public string Raw => @"
USE [DD_ECM];
DECLARE @OUT_UID varchar(36);
EXEC [dbo].[PRSIG_API_CREATE_ENVELOPE]
@USER_ID = @UserId,
@TITLE = @Title,
@TFAEnabled = @TfaEnabled,
@MESSAGE = @Message,
@OUT_UID = @OUT_UID OUTPUT;
SELECT TOP(1) *
FROM [dbo].[TBSIG_ENVELOPE]
WHERE [ENVELOPE_UUID] = @OUT_UID;
";
}

View File

@@ -4,6 +4,7 @@ Imports GdPicture14
Imports Newtonsoft.Json.Linq Imports Newtonsoft.Json.Linq
Imports EnvelopeGenerator.Common.Jobs Imports EnvelopeGenerator.Common.Jobs
Imports System.IO Imports System.IO
Imports EnvelopeGenerator.Common.Jobs.FinalizeDocument
Public Class frmFinalizePDF Public Class frmFinalizePDF
Private Const CONNECTIONSTRING = "Server=sDD-VMP04-SQL17\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=+bk8oAbbQP1AzoHtvZUbd+Mbok2f8Fl4miEx1qssJ5yEaEWoQJ9prg4L14fURpPnqi1WMNs9fE4=;" Private Const CONNECTIONSTRING = "Server=sDD-VMP04-SQL17\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=+bk8oAbbQP1AzoHtvZUbd+Mbok2f8Fl4miEx1qssJ5yEaEWoQJ9prg4L14fURpPnqi1WMNs9fE4=;"
@@ -15,14 +16,14 @@ Public Class frmFinalizePDF
Private Manager As AnnotationManager Private Manager As AnnotationManager
Private PDFBurner As FinalizeDocument.PDFBurner Private PDFBurner As FinalizeDocument.PDFBurner
Private pGDPictureLicenseKey As String = "kG1Qf9PwmqgR8aDmIW2zI_ebj48RzqAJegRxcystEmkbTGQqfkNBdFOXIb6C_A00Ra8zZkrHdfjqzOPXK7kgkF2YDhvrqKfqh4WDug2vOt0qO31IommzkANSuLjZ4zmraoubyEVd25rE3veQ2h_j7tGIoH_LyIHmy24GaXsxdG0yCzIBMdiLbMMMDwcPY-809KeZ83Grv76OVhFvcbBWyYc251vou1N-kGg5_ZlHDgfWoY85gTLRxafjD3KS_i9ARW4BMiy36y8n7UP2jN8kGRnW_04ubpFtfjJqvtsrP_J9D0x7bqV8xtVtT5JI6dpKsVTiMgDCrIcoFSo5gCC1fw9oUopX4TDCkBQttO4-WHBlOeq9dG5Yb0otonVmJKaQA2tP6sMR-lZDs3ql_WI9t91yPWgpssrJUxSHDd27_LMTH_owJIqkF3NOJd9mYQuAv22oNKFYbH8e41pVKb8cT33Y9CgcQ_sy6YDA5PTuIRi67mjKge_nD9rd0IN213Ir9M_EFWqg9e4haWzIdHXQUo0md70kVhPX4UIH_BKJnxEEnFfoFRNMh77bB0N4jkcBEHPl-ghOERv8dOztf4vCnNpzzWvcLD2cqWIm6THy8XGGq9h4hp8aEreRleSMwv9QQAC7mjLwhQ1rBYkpUHlpTjhTLnMwHknl6HH0Z6zzmsgkRKVyfquv94Pd7QbQfZrRka0ss_48pf9p8hAywEn81Q==" Private pGDPictureLicenseKey As String = "kG1Qf9PwmqgR8aDmIW2zI_ebj48RzqAJegRxcystEmkbTGQqfkNBdFOXIb6C_A00Ra8zZkrHdfjqzOPXK7kgkF2YDhvrqKfqh4WDug2vOt0qO31IommzkANSuLjZ4zmraoubyEVd25rE3veQ2h_j7tGIoH_LyIHmy24GaXsxdG0yCzIBMdiLbMMMDwcPY-809KeZ83Grv76OVhFvcbBWyYc251vou1N-kGg5_ZlHDgfWoY85gTLRxafjD3KS_i9ARW4BMiy36y8n7UP2jN8kGRnW_04ubpFtfjJqvtsrP_J9D0x7bqV8xtVtT5JI6dpKsVTiMgDCrIcoFSo5gCC1fw9oUopX4TDCkBQttO4-WHBlOeq9dG5Yb0otonVmJKaQA2tP6sMR-lZDs3ql_WI9t91yPWgpssrJUxSHDd27_LMTH_owJIqkF3NOJd9mYQuAv22oNKFYbH8e41pVKb8cT33Y9CgcQ_sy6YDA5PTuIRi67mjKge_nD9rd0IN213Ir9M_EFWqg9e4haWzIdHXQUo0md70kVhPX4UIH_BKJnxEEnFfoFRNMh77bB0N4jkcBEHPl-ghOERv8dOztf4vCnNpzzWvcLD2cqWIm6THy8XGGq9h4hp8aEreRleSMwv9QQAC7mjLwhQ1rBYkpUHlpTjhTLnMwHknl6HH0Z6zzmsgkRKVyfquv94Pd7QbQfZrRka0ss_48pf9p8hAywEn81Q=="
Private ReadOnly _ignoredLabels As New List(Of String) From {"Date", "Datum", "ZIP", "PLZ", "Place", "Ort", "Position", "Stellung"} Private ReadOnly _pdfBurnerParams As New PDFBurnerParams()
Private Sub frmFinalizePDF_Load(sender As Object, e As EventArgs) Handles MyBase.Load Private Sub frmFinalizePDF_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LogConfig = New LogConfig(LogConfig.PathType.CustomPath, Application.StartupPath) LogConfig = New LogConfig(LogConfig.PathType.CustomPath, Application.StartupPath)
Database = New MSSQLServer(LogConfig, MSSQLServer.DecryptConnectionString(CONNECTIONSTRING)) Database = New MSSQLServer(LogConfig, MSSQLServer.DecryptConnectionString(CONNECTIONSTRING))
PDFBurner = New FinalizeDocument.PDFBurner(LogConfig, pGDPictureLicenseKey, _ignoredLabels) PDFBurner = New FinalizeDocument.PDFBurner(LogConfig, pGDPictureLicenseKey, _pdfBurnerParams)
Viewer = New GdViewer() Viewer = New GdViewer()
Manager = New AnnotationManager() Manager = New AnnotationManager()
@@ -77,6 +78,8 @@ Public Class frmFinalizePDF
Dim oNewPath = Path.Combine(desktopPath, $"E{txtEnvelope.Text}R{txtReceiver.Text}.burned.pdf") Dim oNewPath = Path.Combine(desktopPath, $"E{txtEnvelope.Text}R{txtReceiver.Text}.burned.pdf")
File.WriteAllBytes(oNewPath, oNewBuffer) File.WriteAllBytes(oNewPath, oNewBuffer)
Process.Start(oNewPath)
Catch ex As Exception Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical) MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try End Try

View File

@@ -13,6 +13,8 @@
EnvelopeReportCreated = 1007 EnvelopeReportCreated = 1007
EnvelopeArchived = 1008 EnvelopeArchived = 1008
EnvelopeDeleted = 1009 EnvelopeDeleted = 1009
EnvelopeRejected = 10007
EnvelopeWithdrawn = 10009
AccessCodeRequested = 2001 AccessCodeRequested = 2001
AccessCodeCorrect = 2002 AccessCodeCorrect = 2002
AccessCodeIncorrect = 2003 AccessCodeIncorrect = 2003
@@ -28,6 +30,7 @@
MessageConfirmationSent = 3003 MessageConfirmationSent = 3003
MessageDeletionSent = 3004 MessageDeletionSent = 3004
MessageCompletionSent = 3005 MessageCompletionSent = 3005
DocumentMod_Rotation = 4001
End Enum End Enum
'TODO: standardize in xwiki 'TODO: standardize in xwiki
@@ -127,7 +130,7 @@
Public Const DATABASE = "DATABASE" Public Const DATABASE = "DATABASE"
Public Const LOGCONFIG = "LOGCONFIG" Public Const LOGCONFIG = "LOGCONFIG"
Public Const GDPICTURE = "GDPICTURE" Public Const GDPICTURE = "GDPICTURE"
Public Const IGNORED_LABELS = "IgnoredLabels" Public Const PDF_BURNER_PARAMS = "PDFBurnerParams"
Public Const GREEN_300 = "#bbf7d0" Public Const GREEN_300 = "#bbf7d0"
Public Const RED_300 = "#fecaca" Public Const RED_300 = "#fecaca"

View File

@@ -25,6 +25,7 @@
Public Property Message As String = My.Resources.Envelope.Please_read_and_sign_this_document Public Property Message As String = My.Resources.Envelope.Please_read_and_sign_this_document
Public Property AddedWhen As Date Public Property AddedWhen As Date
Public Property ChangedWhen As Date
Public Property User As New User() Public Property User As New User()
Public Property Documents As New List(Of EnvelopeDocument) Public Property Documents As New List(Of EnvelopeDocument)

View File

@@ -8,6 +8,7 @@
Public Property HasAccess As Boolean Public Property HasAccess As Boolean
Public Property IsAdmin As Boolean Public Property IsAdmin As Boolean
Public Property GhostModeActive As Boolean
Public ReadOnly Property FullName() As String Public ReadOnly Property FullName() As String
Get Get

View File

@@ -281,6 +281,7 @@
<Compile Include="Entities\ElementStatus.vb" /> <Compile Include="Entities\ElementStatus.vb" />
<Compile Include="Entities\EmailData.vb" /> <Compile Include="Entities\EmailData.vb" />
<Compile Include="Entities\EmailTemplate.vb" /> <Compile Include="Entities\EmailTemplate.vb" />
<Compile Include="Jobs\FinalizeDocument\PDFBurnerParams.vb" />
<Compile Include="Services\TemplateService.vb" /> <Compile Include="Services\TemplateService.vb" />
<Compile Include="Entities\Envelope.vb" /> <Compile Include="Entities\Envelope.vb" />
<Compile Include="Entities\EnvelopeDocument.vb" /> <Compile Include="Entities\EnvelopeDocument.vb" />

View File

@@ -74,8 +74,8 @@ Namespace Jobs
InitializeServices(oState) InitializeServices(oState)
Logger.Debug("Loading PDFBurner..") Logger.Debug("Loading PDFBurner..")
Dim ignoredLabels As List(Of String) = pContext.MergedJobDataMap.Item(Constants.IGNORED_LABELS) Dim pdfBurnerParams As PDFBurnerParams = pContext.MergedJobDataMap.Item(Constants.PDF_BURNER_PARAMS)
PDFBurner = New PDFBurner(LogConfig, oGdPictureKey, ignoredLabels) PDFBurner = New PDFBurner(LogConfig, oGdPictureKey, pdfBurnerParams)
Logger.Debug("Loading PDFMerger..") Logger.Debug("Loading PDFMerger..")
PDFMerger = New PDFMerger(LogConfig, oGdPictureKey) PDFMerger = New PDFMerger(LogConfig, oGdPictureKey)
@@ -170,7 +170,7 @@ Namespace Jobs
Throw New ApplicationException("Envelope could not be finalized") Throw New ApplicationException("Envelope could not be finalized")
End If End If
Catch ex As Exception Catch ex As Exception
Logger.Warn($"Unhandled exception while working envelope [{oId}] - [{ex.Message}]") Logger.Warn(ex, $"Unhandled exception while working envelope [{oId}]")
End Try End Try
@@ -378,12 +378,10 @@ Namespace Jobs
Try Try
oInputDocumentBuffer = File.ReadAllBytes(oInputPath) oInputDocumentBuffer = File.ReadAllBytes(oInputPath)
Catch ex As Exception Catch ex As Exception
Logger.Error(ex)
Throw New BurnAnnotationException("Source document could not be read from disk!", ex) Throw New BurnAnnotationException("Source document could not be read from disk!", ex)
End Try End Try
End If End If
Return PDFBurner.BurnInstantJSONAnnotationsToPDF(oInputDocumentBuffer, oAnnotations) Return PDFBurner.BurnInstantJSONAnnotationsToPDF(oInputDocumentBuffer, oAnnotations)
End Function End Function

View File

@@ -16,9 +16,9 @@ Namespace Jobs.FinalizeDocument
Private Const ANNOTATION_TYPE_IMAGE = "pspdfkit/image" Private Const ANNOTATION_TYPE_IMAGE = "pspdfkit/image"
Private Const ANNOTATION_TYPE_INK = "pspdfkit/ink" Private Const ANNOTATION_TYPE_INK = "pspdfkit/ink"
Private Const ANNOTATION_TYPE_WIDGET = "pspdfkit/widget" Private Const ANNOTATION_TYPE_WIDGET = "pspdfkit/widget"
Private Property _ignoredLabels As List(Of String) Private Property _pdfBurnerParams As PDFBurnerParams
Public Sub New(pLogConfig As LogConfig, pGDPictureLicenseKey As String, ignoredLabels As List(Of String)) Public Sub New(pLogConfig As LogConfig, pGDPictureLicenseKey As String, pdfBurnerParams As PDFBurnerParams)
MyBase.New(pLogConfig) MyBase.New(pLogConfig)
LicenseManager = New LicenseManager() LicenseManager = New LicenseManager()
@@ -26,56 +26,50 @@ Namespace Jobs.FinalizeDocument
Manager = New AnnotationManager() Manager = New AnnotationManager()
_ignoredLabels = ignoredLabels _pdfBurnerParams = pdfBurnerParams
End Sub End Sub
Public Function BurnInstantJSONAnnotationsToPDF(pSourceBuffer As Byte(), pInstantJSONList As List(Of String)) As Byte() Public Function BurnInstantJSONAnnotationsToPDF(pSourceBuffer As Byte(), pInstantJSONList As List(Of String)) As Byte()
Dim oResult As GdPictureStatus Dim oResult As GdPictureStatus
Using oSourceStream As New MemoryStream(pSourceBuffer)
' Open PDF
oResult = Manager.InitFromStream(oSourceStream)
If oResult <> GdPictureStatus.OK Then
Throw New BurnAnnotationException($"Could not open document for burning: [{oResult}]")
End If
Try ' Add annotation to PDF
Using oSourceStream As New MemoryStream(pSourceBuffer) For Each oJSON In pInstantJSONList
' Open PDF If AddInstantJSONAnnotationToPDF(oJSON) = False Then
oResult = Manager.InitFromStream(oSourceStream) Logger.Warn($"Error in AddInstantJSONAnnotationToPDF - oJson: ")
Logger.Warn(oJSON)
Throw New BurnAnnotationException($"Adding Annotation failed")
End If
Next
oResult = Manager.BurnAnnotationsToPage(RemoveInitialAnnots:=True, VectorMode:=True)
If oResult <> GdPictureStatus.OK Then
Throw New BurnAnnotationException($"Could not burn annotations to file: [{oResult}]")
End If
'Save PDF
Using oNewStream As New MemoryStream()
oResult = Manager.SaveDocumentToPDF(oNewStream)
If oResult <> GdPictureStatus.OK Then If oResult <> GdPictureStatus.OK Then
Throw New BurnAnnotationException($"Could not open document for burning: [{oResult}]") Throw New BurnAnnotationException($"Could not save document to stream: [{oResult}]")
End If End If
' Add annotation to PDF Manager.Close()
For Each oJSON In pInstantJSONList
If AddInstantJSONAnnotationToPDF(oJSON) = False Then
Logger.Warn($"Error in AddInstantJSONAnnotationToPDF - oJson: ")
Logger.Warn(oJSON)
Throw New BurnAnnotationException($"Adding Annotation failed")
End If
Next
oResult = Manager.BurnAnnotationsToPage(RemoveInitialAnnots:=True, VectorMode:=True)
If oResult <> GdPictureStatus.OK Then
Throw New BurnAnnotationException($"Could not burn annotations to file: [{oResult}]")
End If
'Save PDF Return oNewStream.ToArray()
Using oNewStream As New MemoryStream()
oResult = Manager.SaveDocumentToPDF(oNewStream)
If oResult <> GdPictureStatus.OK Then
Throw New BurnAnnotationException($"Could not save document to stream: [{oResult}]")
End If
Manager.Close()
Return oNewStream.ToArray()
End Using
End Using End Using
Catch ex As Exception End Using
Logger.Error(ex)
Return Nothing
End Try
End Function End Function
Private Function AddInstantJSONAnnotationToPDF(pInstantJSON As String) As Boolean Private Function AddInstantJSONAnnotationToPDF(pInstantJSON As String) As Boolean
Try Try
Dim oAnnotationData = JsonConvert.DeserializeObject(Of AnnotationData)(pInstantJSON) Dim oAnnotationData = JsonConvert.DeserializeObject(Of AnnotationData)(pInstantJSON)
oAnnotationData.annotations.Reverse()
Dim formFieldIndex = 0
For Each oAnnotation In oAnnotationData.annotations For Each oAnnotation In oAnnotationData.annotations
Logger.Debug("Adding AnnotationID: " + oAnnotation.id) Logger.Debug("Adding AnnotationID: " + oAnnotation.id)
Select Case oAnnotation.type Select Case oAnnotation.type
@@ -88,10 +82,12 @@ Namespace Jobs.FinalizeDocument
Case ANNOTATION_TYPE_WIDGET Case ANNOTATION_TYPE_WIDGET
'Add form field values 'Add form field values
Dim formFieldValue = oAnnotationData.formFieldValues.FirstOrDefault(Function(fv) fv.name = oAnnotation.id) Dim formFieldValue = oAnnotationData.formFieldValues.FirstOrDefault(Function(fv) fv.name = oAnnotation.id)
If formFieldValue IsNot Nothing AndAlso Not _ignoredLabels.Contains(formFieldValue.value) Then If formFieldValue IsNot Nothing AndAlso Not _pdfBurnerParams.IgnoredLabels.Contains(formFieldValue.value) Then
AddFormFieldValue(oAnnotation, formFieldValue) AddFormFieldValue(oAnnotation, formFieldValue, formFieldIndex)
formFieldIndex += 1
End If End If
End Select End Select
Next Next
Return True Return True
@@ -151,13 +147,13 @@ Namespace Jobs.FinalizeDocument
End Function End Function
Private Function AddFormFieldValue(pAnnotation As Annotation, formFieldValue As FormFieldValue) As Boolean Private Function AddFormFieldValue(pAnnotation As Annotation, formFieldValue As FormFieldValue, index As Integer) As Boolean
Try Try
' Convert pixels to Inches ' Convert pixels to Inches
Dim oBounds = pAnnotation.bbox.Select(AddressOf ToInches).ToList() Dim oBounds = pAnnotation.bbox.Select(AddressOf ToInches).ToList()
Dim oX = oBounds.Item(0) Dim oX = oBounds.Item(0)
Dim oY = oBounds.Item(1) Dim oY = oBounds.Item(1) + _pdfBurnerParams.YOffset * index + _pdfBurnerParams.TopMargin
Dim oWidth = oBounds.Item(2) Dim oWidth = oBounds.Item(2)
Dim oHeight = oBounds.Item(3) Dim oHeight = oBounds.Item(3)
@@ -166,9 +162,9 @@ Namespace Jobs.FinalizeDocument
Dim ant = Manager.AddTextAnnot(oX, oY, oWidth, oHeight, formFieldValue.value) Dim ant = Manager.AddTextAnnot(oX, oY, oWidth, oHeight, formFieldValue.value)
' Set the font properties ' Set the font properties
ant.FontName = "Arial" ant.FontName = _pdfBurnerParams.FontName
ant.FontSize = 8 ant.FontSize = _pdfBurnerParams.FontSize
ant.FontStyle = FontStyle.Italic ant.FontStyle = _pdfBurnerParams.FontStyle
Manager.SaveAnnotationsToPage() Manager.SaveAnnotationsToPage()
Return True Return True
Catch ex As Exception Catch ex As Exception

View File

@@ -0,0 +1,16 @@
Imports System.Drawing
Namespace Jobs.FinalizeDocument
Public Class PDFBurnerParams
Public Property IgnoredLabels As New List(Of String) From {"Date", "Datum", "ZIP", "PLZ", "Place", "Ort", "Position", "Stellung"}
Public Property TopMargin As Double = 0.1
Public Property YOffset As Double = -0.3
Public Property FontName As String = "Arial"
Public Property FontSize As Integer = 8
Public Property FontStyle As FontStyle = FontStyle.Italic
End Class
End Namespace

View File

@@ -35,6 +35,7 @@ Public Class EnvelopeModel
.Language = pRow.ItemEx("LANGUAGE", "de-DE"), .Language = pRow.ItemEx("LANGUAGE", "de-DE"),
.Status = ObjectEx.ToEnum(Of Constants.EnvelopeStatus)(pRow.ItemEx("STATUS", Constants.EnvelopeStatus.EnvelopeCreated.ToString())), .Status = ObjectEx.ToEnum(Of Constants.EnvelopeStatus)(pRow.ItemEx("STATUS", Constants.EnvelopeStatus.EnvelopeCreated.ToString())),
.AddedWhen = pRow.Item("ADDED_WHEN"), .AddedWhen = pRow.Item("ADDED_WHEN"),
.ChangedWhen = pRow.Item("CHANGED_WHEN"),
.CertificationType = ObjectEx.ToEnum(Of Constants.CertificationType)(pRow.ItemEx("CERTIFICATION_TYPE", Constants.CertificationType.AdvancedElectronicSignature.ToString())), .CertificationType = ObjectEx.ToEnum(Of Constants.CertificationType)(pRow.ItemEx("CERTIFICATION_TYPE", Constants.CertificationType.AdvancedElectronicSignature.ToString())),
.User = New User(), .User = New User(),
.ExpiresWhen = pRow.ItemEx(Of Date)("EXPIRES_WHEN", Nothing), .ExpiresWhen = pRow.ItemEx(Of Date)("EXPIRES_WHEN", Nothing),

View File

@@ -33,10 +33,10 @@ Public Class UserModel
Dim oRow = oTable.Rows.Item(0) Dim oRow = oTable.Rows.Item(0)
Dim oHasAccess = oRow.ItemEx("MODULE_ACCESS", False) Dim oHasAccess = oRow.ItemEx("MODULE_ACCESS", False)
Dim oIsAdmin = oRow.ItemEx("IS_ADMIN", False) Dim oIsAdmin = oRow.ItemEx("IS_ADMIN", False)
Dim oGhostmode = oRow.ItemEx("GHOST_MODE_OVERRIDE", False)
pUser.HasAccess = oHasAccess pUser.HasAccess = oHasAccess
pUser.IsAdmin = oIsAdmin pUser.IsAdmin = oIsAdmin
pUser.GhostModeActive = oGhostmode
Return pUser Return pUser
Catch ex As Exception Catch ex As Exception
Logger.Error(ex) Logger.Error(ex)

View File

@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' indem Sie "*" wie unten gezeigt eingeben: ' indem Sie "*" wie unten gezeigt eingeben:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2.4.3.0")> <Assembly: AssemblyVersion("2.4.4.0")>
<Assembly: AssemblyFileVersion("2.4.3.0")> <Assembly: AssemblyFileVersion("2.4.4.0")>

View File

@@ -1,5 +1,6 @@
Imports DevExpress.DataAccess.Native.Web Imports DevExpress.DataAccess.Native.Web
Imports DigitalData.Modules.Base Imports DigitalData.Modules.Base
Imports EnvelopeGenerator.Common.Constants
Imports EnvelopeGenerator.Common.My.Resources Imports EnvelopeGenerator.Common.My.Resources
Public Class ActionService Public Class ActionService
@@ -34,6 +35,12 @@ Public Class ActionService
Return True Return True
End Function End Function
Public Function SetStatusDocumentRotationChanged(pEnvelope As Envelope) As Boolean
If HistoryService.SetEnvelopeStatus(pEnvelope, Constants.EnvelopeStatus.DocumentMod_Rotation, pEnvelope.User.Email) = False Then
Return False
End If
Return True
End Function
Public Function Resend_Receiver(pEnvelope As Envelope, pmail As String) As Boolean Public Function Resend_Receiver(pEnvelope As Envelope, pmail As String) As Boolean
If HistoryService.SetEnvelopeStatus(pEnvelope, Constants.EnvelopeStatus.EnvelopeQueued, pEnvelope.User.Email) = False Then If HistoryService.SetEnvelopeStatus(pEnvelope, Constants.EnvelopeStatus.EnvelopeQueued, pEnvelope.User.Email) = False Then
Return False Return False
@@ -50,7 +57,13 @@ Public Class ActionService
Public Function DeleteEnvelope(pEnvelope As Envelope, pReason As String) As Boolean Public Function DeleteEnvelope(pEnvelope As Envelope, pReason As String) As Boolean
If HistoryService.SetEnvelopeStatus(pEnvelope, Constants.EnvelopeStatus.EnvelopeDeleted, pEnvelope.User.Email) = False Then Dim oStatus As EnvelopeStatus
If pEnvelope.IsAlreadySent Then
oStatus = Constants.EnvelopeStatus.EnvelopeWithdrawn
Else
oStatus = Constants.EnvelopeStatus.EnvelopeDeleted
End If
If HistoryService.SetEnvelopeStatus(pEnvelope, oStatus, pEnvelope.User.Email) = False Then
Return False Return False
End If End If

View File

@@ -121,7 +121,7 @@
<value>Please select the PDF documents you would like to link/concat:</value> <value>Please select the PDF documents you would like to link/concat:</value>
</data> </data>
<data name="Do you really want to delete this envelope" xml:space="preserve"> <data name="Do you really want to delete this envelope" xml:space="preserve">
<value>Do you really want to delete this envelope?</value> <value>Do you really want to withdraw/delete this envelope?</value>
</data> </data>
<data name="Do you really want to remove this document" xml:space="preserve"> <data name="Do you really want to remove this document" xml:space="preserve">
<value>Do you really want to remove this document?</value> <value>Do you really want to remove this document?</value>

View File

@@ -121,7 +121,7 @@
<value>Bitte wählen Sie die PDF-Dokumente die Sie verketten möchten:</value> <value>Bitte wählen Sie die PDF-Dokumente die Sie verketten möchten:</value>
</data> </data>
<data name="Do you really want to delete this envelope" xml:space="preserve"> <data name="Do you really want to delete this envelope" xml:space="preserve">
<value>Wollen Sie diesen Umschlag wirklich löschen?</value> <value>Wollen Sie diesen Umschlag wirklich zurückrufen/löschen?</value>
</data> </data>
<data name="Do you really want to remove this document" xml:space="preserve"> <data name="Do you really want to remove this document" xml:space="preserve">
<value>Wollen Sie dieses Dokument wirklich entfernen?</value> <value>Wollen Sie dieses Dokument wirklich entfernen?</value>
@@ -220,6 +220,9 @@ Pattern: +491234567890</value>
<data name="Missing Receivers" xml:space="preserve"> <data name="Missing Receivers" xml:space="preserve">
<value>Fehlende Empfänger</value> <value>Fehlende Empfänger</value>
</data> </data>
<data name="ModificationOriginFile_FormFields" xml:space="preserve">
<value />
</data>
<data name="New Envelope" xml:space="preserve"> <data name="New Envelope" xml:space="preserve">
<value>Neuer Umschlag</value> <value>Neuer Umschlag</value>
</data> </data>

View File

@@ -74,7 +74,7 @@ Namespace My.Resources
End Property End Property
'''<summary> '''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Wollen Sie diesen Umschlag wirklich löschen? ähnelt. ''' Sucht eine lokalisierte Zeichenfolge, die Wollen Sie diesen Umschlag wirklich zurückrufen/löschen? ähnelt.
'''</summary> '''</summary>
Public Shared ReadOnly Property Do_you_really_want_to_delete_this_envelope() As String Public Shared ReadOnly Property Do_you_really_want_to_delete_this_envelope() As String
Get Get
@@ -371,6 +371,15 @@ Namespace My.Resources
End Get End Get
End Property End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die ähnelt.
'''</summary>
Public Shared ReadOnly Property ModificationOriginFile_FormFields() As String
Get
Return ResourceManager.GetString("ModificationOriginFile_FormFields", resourceCulture)
End Get
End Property
'''<summary> '''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Neuer Umschlag ähnelt. ''' Sucht eine lokalisierte Zeichenfolge, die Neuer Umschlag ähnelt.
'''</summary> '''</summary>

View File

@@ -136,6 +136,15 @@ Namespace My.Resources
End Get End Get
End Property End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Dokument Rotation geändert ähnelt.
'''</summary>
Public Shared ReadOnly Property DocumentMod_Rotation() As String
Get
Return ResourceManager.GetString("DocumentMod_Rotation", resourceCulture)
End Get
End Property
'''<summary> '''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Dokument geöffnet ähnelt. ''' Sucht eine lokalisierte Zeichenfolge, die Dokument geöffnet ähnelt.
'''</summary> '''</summary>
@@ -145,6 +154,15 @@ Namespace My.Resources
End Get End Get
End Property End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Unterzeichnung abgelehnt ähnelt.
'''</summary>
Public Shared ReadOnly Property DocumentRejected() As String
Get
Return ResourceManager.GetString("DocumentRejected", resourceCulture)
End Get
End Property
'''<summary> '''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Dokument unterzeichnet ähnelt. ''' Sucht eine lokalisierte Zeichenfolge, die Dokument unterzeichnet ähnelt.
'''</summary> '''</summary>
@@ -217,6 +235,15 @@ Namespace My.Resources
End Get End Get
End Property End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Umschlag abgelehnt ähnelt.
'''</summary>
Public Shared ReadOnly Property EnvelopeRejected() As String
Get
Return ResourceManager.GetString("EnvelopeRejected", resourceCulture)
End Get
End Property
'''<summary> '''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Signierungszertifikat erstellt ähnelt. ''' Sucht eine lokalisierte Zeichenfolge, die Signierungszertifikat erstellt ähnelt.
'''</summary> '''</summary>
@@ -244,6 +271,15 @@ Namespace My.Resources
End Get End Get
End Property End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Umschlag zurückgezogen ähnelt.
'''</summary>
Public Shared ReadOnly Property EnvelopeWithdrawn() As String
Get
Return ResourceManager.GetString("EnvelopeWithdrawn", resourceCulture)
End Get
End Property
'''<summary> '''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Zugriffscode versendet ähnelt. ''' Sucht eine lokalisierte Zeichenfolge, die Zugriffscode versendet ähnelt.
'''</summary> '''</summary>
@@ -289,6 +325,15 @@ Namespace My.Resources
End Get End Get
End Property End Property
'''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die ähnelt.
'''</summary>
Public Shared ReadOnly Property ModificationOriginFile_FormFields() As String
Get
Return ResourceManager.GetString("ModificationOriginFile_FormFields", resourceCulture)
End Get
End Property
'''<summary> '''<summary>
''' Sucht eine lokalisierte Zeichenfolge, die Nein ähnelt. ''' Sucht eine lokalisierte Zeichenfolge, die Nein ähnelt.
'''</summary> '''</summary>

View File

@@ -138,9 +138,15 @@
<data name="Created" xml:space="preserve"> <data name="Created" xml:space="preserve">
<value>Created</value> <value>Created</value>
</data> </data>
<data name="DocumentMod_Rotation" xml:space="preserve">
<value>Document rotation adapted</value>
</data>
<data name="DocumentOpened" xml:space="preserve"> <data name="DocumentOpened" xml:space="preserve">
<value>Document opened</value> <value>Document opened</value>
</data> </data>
<data name="DocumentRejected" xml:space="preserve">
<value>Signing rejected</value>
</data>
<data name="DocumentSigned" xml:space="preserve"> <data name="DocumentSigned" xml:space="preserve">
<value>Document signed</value> <value>Document signed</value>
</data> </data>
@@ -154,16 +160,19 @@
<value>Completely signed</value> <value>Completely signed</value>
</data> </data>
<data name="EnvelopeCreated" xml:space="preserve"> <data name="EnvelopeCreated" xml:space="preserve">
<value>Created</value> <value>Envelope Created</value>
</data> </data>
<data name="EnvelopeDeleted" xml:space="preserve"> <data name="EnvelopeDeleted" xml:space="preserve">
<value>Deleted</value> <value>Envelope Deleted</value>
</data> </data>
<data name="EnvelopePartlySigned" xml:space="preserve"> <data name="EnvelopePartlySigned" xml:space="preserve">
<value>Partly signed</value> <value>Partly signed</value>
</data> </data>
<data name="EnvelopeQueued" xml:space="preserve"> <data name="EnvelopeQueued" xml:space="preserve">
<value>Queued</value> <value>Envelope Queued</value>
</data>
<data name="EnvelopeRejected" xml:space="preserve">
<value>Envelope Rejected</value>
</data> </data>
<data name="EnvelopeReportCreated" xml:space="preserve"> <data name="EnvelopeReportCreated" xml:space="preserve">
<value>Signature certificate created</value> <value>Signature certificate created</value>
@@ -174,6 +183,9 @@
<data name="EnvelopeSent" xml:space="preserve"> <data name="EnvelopeSent" xml:space="preserve">
<value>Sent</value> <value>Sent</value>
</data> </data>
<data name="EnvelopeWithdrawn" xml:space="preserve">
<value>Withdrawn</value>
</data>
<data name="MessageAccessCodeSent" xml:space="preserve"> <data name="MessageAccessCodeSent" xml:space="preserve">
<value>Accesscode sent</value> <value>Accesscode sent</value>
</data> </data>

View File

@@ -141,9 +141,15 @@
<data name="Created" xml:space="preserve"> <data name="Created" xml:space="preserve">
<value>Erstellt</value> <value>Erstellt</value>
</data> </data>
<data name="DocumentMod_Rotation" xml:space="preserve">
<value>Dokument Rotation geändert</value>
</data>
<data name="DocumentOpened" xml:space="preserve"> <data name="DocumentOpened" xml:space="preserve">
<value>Dokument geöffnet</value> <value>Dokument geöffnet</value>
</data> </data>
<data name="DocumentRejected" xml:space="preserve">
<value>Unterzeichnung abgelehnt</value>
</data>
<data name="DocumentSigned" xml:space="preserve"> <data name="DocumentSigned" xml:space="preserve">
<value>Dokument unterzeichnet</value> <value>Dokument unterzeichnet</value>
</data> </data>
@@ -168,6 +174,9 @@
<data name="EnvelopeQueued" xml:space="preserve"> <data name="EnvelopeQueued" xml:space="preserve">
<value>Umschlag in Queue</value> <value>Umschlag in Queue</value>
</data> </data>
<data name="EnvelopeRejected" xml:space="preserve">
<value>Umschlag abgelehnt</value>
</data>
<data name="EnvelopeReportCreated" xml:space="preserve"> <data name="EnvelopeReportCreated" xml:space="preserve">
<value>Signierungszertifikat erstellt</value> <value>Signierungszertifikat erstellt</value>
</data> </data>
@@ -177,6 +186,9 @@
<data name="EnvelopeSent" xml:space="preserve"> <data name="EnvelopeSent" xml:space="preserve">
<value>Gesendet</value> <value>Gesendet</value>
</data> </data>
<data name="EnvelopeWithdrawn" xml:space="preserve">
<value>Umschlag zurückgezogen</value>
</data>
<data name="MessageAccessCodeSent" xml:space="preserve"> <data name="MessageAccessCodeSent" xml:space="preserve">
<value>Zugriffscode versendet</value> <value>Zugriffscode versendet</value>
</data> </data>

View File

@@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" /> <PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" />
<PackageReference Include="DigitalData.EmailProfilerDispatcher.Abstraction" Version="3.0.0" /> <PackageReference Include="DigitalData.EmailProfilerDispatcher.Abstraction" Version="3.0.0" />
<PackageReference Include="UserManager.Domain" Version="3.0.2" /> <PackageReference Include="UserManager.Domain" Version="3.0.2" />
</ItemGroup> </ItemGroup>

View File

@@ -1,9 +1,11 @@
Imports System.Data.SqlClient Imports System.Data.SqlClient
Imports System.IO Imports System.IO
Imports DevExpress.XtraBars.Docking
Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Logging
Imports EnvelopeGenerator.Common Imports EnvelopeGenerator.Common
Imports EnvelopeGenerator.Common.Constants Imports EnvelopeGenerator.Common.Constants
Imports EnvelopeGenerator.Common.My Imports EnvelopeGenerator.Common.My
Imports GdPicture14
Public Class EnvelopeEditorController Public Class EnvelopeEditorController
Inherits BaseController Inherits BaseController
@@ -38,6 +40,9 @@ Public Class EnvelopeEditorController
Public Function SendEnvelope() As Boolean Public Function SendEnvelope() As Boolean
Return ActionService.SendEnvelope(Envelope) Return ActionService.SendEnvelope(Envelope)
End Function End Function
Public Function DocumentRotationChanged() As Boolean
Return ActionService.SetStatusDocumentRotationChanged(Envelope)
End Function
Public Function ResendReceiverInvitation(pEnvelope As Envelope, pReceiver As EnvelopeReceiver) As Boolean Public Function ResendReceiverInvitation(pEnvelope As Envelope, pReceiver As EnvelopeReceiver) As Boolean
Return ActionService.ResendReceiver(pEnvelope, pReceiver) Return ActionService.ResendReceiver(pEnvelope, pReceiver)
End Function End Function
@@ -158,8 +163,10 @@ Public Class EnvelopeEditorController
Try Try
Dim oFixedPath = FixPageRotation.FixPageRotation(pDocumentFilePath) Dim oFixedPath = FixPageRotation.FixPageRotation(pDocumentFilePath)
If oFixedPath <> pDocumentFilePath Then If oFixedPath <> pDocumentFilePath Then
DocumentRotationChanged()
Logger.Info("PageRotation has been reseted to 0.") Logger.Info("PageRotation has been reseted to 0.")
End If End If
oFixedPath = FlattenFormFields.FlattenFormFields(oFixedPath)
Dim oFileInfo = New FileInfo(oFixedPath) Dim oFileInfo = New FileInfo(oFixedPath)
Dim oTempFiles As New TempFiles(State.LogConfig) Dim oTempFiles As New TempFiles(State.LogConfig)
Dim oTempFilePath = Path.Combine(oTempFiles._TempPath, Guid.NewGuid().ToString + oFileInfo.Extension) Dim oTempFilePath = Path.Combine(oTempFiles._TempPath, Guid.NewGuid().ToString + oFileInfo.Extension)

View File

@@ -369,6 +369,7 @@
</Compile> </Compile>
<Compile Include="Helper\Encryption.vb" /> <Compile Include="Helper\Encryption.vb" />
<Compile Include="Helper\FixPageRotation.vb" /> <Compile Include="Helper\FixPageRotation.vb" />
<Compile Include="Helper\FlattenFormFields.vb" />
<Compile Include="Helper\RefreshHelper.vb" /> <Compile Include="Helper\RefreshHelper.vb" />
<Compile Include="Helper\TempFiles.vb" /> <Compile Include="Helper\TempFiles.vb" />
<Compile Include="Helper\Thumbnail.vb" /> <Compile Include="Helper\Thumbnail.vb" />
@@ -415,6 +416,7 @@
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="frmGhostMode.resx"> <EmbeddedResource Include="frmGhostMode.resx">
<DependentUpon>frmGhostMode.vb</DependentUpon> <DependentUpon>frmGhostMode.vb</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="frmMain.en.resx"> <EmbeddedResource Include="frmMain.en.resx">
<DependentUpon>frmMain.vb</DependentUpon> <DependentUpon>frmMain.vb</DependentUpon>

View File

@@ -0,0 +1,35 @@
Imports System.IO
Imports GdPicture14
Public Class FlattenFormFields
Public Shared Function FlattenFormFields(pFilePath As String) As String
Dim oFolder As String = Path.GetDirectoryName(pFilePath)
Dim gdpicturePdf As GdPicturePDF = New GdPicturePDF()
Dim status As GdPictureStatus = gdpicturePdf.LoadFromFile(pFilePath, True)
If status = GdPictureStatus.OK Then
Dim oFormFieldsCount = gdpicturePdf.GetFormFieldsCount()
If oFormFieldsCount > 0 Then
gdpicturePdf.FlattenFormFields()
Dim newFilesPath As String = Path.Combine(oFolder, "InputFieldsFlattend_" & Path.GetFileName(pFilePath))
If gdpicturePdf.SaveToFile(newFilesPath) = GdPictureStatus.OK Then
Dim oNameofFile = Path.GetFileName(newFilesPath)
MsgBox("Your PDF-file contained form-fields!" & vbNewLine & "We needed to adapt the file and created an new version!" & vbNewLine &
$"New filename: {oNameofFile}", MsgBoxStyle.Exclamation, "Information")
Return newFilesPath
End If
End If
End If
Return pFilePath
End Function
End Class

View File

@@ -16,10 +16,14 @@ Module ModuleSettings
Public SQL_REP_ENV_USER_TM As String = "" Public SQL_REP_ENV_USER_TM As String = ""
Public SQL_REP_ENV_USER_Y As String = "" Public SQL_REP_ENV_USER_Y As String = ""
Public SQL_REP_ENV_USER_ALL As String = "" Public SQL_REP_ENV_USER_ALL As String = ""
Public SQL_REP_ENV_ALL_USER_MONTH As String = ""
Public SQL_REP_ENV_ALL_USER_LAST_MONTH As String = ""
Public DT_CHARTS As DataTable Public DT_CHARTS As DataTable
Public MyLogger As Logger Public MyLogger As Logger
Public USER_GHOST_MODE_USRNAME As String = "" Public USER_GHOST_MODE_USRNAME As String = ""
Public USER_GHOST_MODE_ACTIVE As Boolean = False Public USER_GHOST_MODE_ACTIVE As Boolean = False
Public MyUserModel As UserModel Public MyUserModel As UserModel
Public MyState As State Public MyState As State
Public CurrentEnvelopID As Integer = 0
Public CurrentEnvelopetitle As String = ""
End Module End Module

View File

@@ -632,6 +632,7 @@ Partial Public Class frmEnvelopeEditor
resources.ApplyResources(Me.txtMessage, "txtMessage") resources.ApplyResources(Me.txtMessage, "txtMessage")
Me.txtMessage.MenuManager = Me.RibbonControl1 Me.txtMessage.MenuManager = Me.RibbonControl1
Me.txtMessage.Name = "txtMessage" Me.txtMessage.Name = "txtMessage"
Me.txtMessage.Properties.AcceptsTab = True
Me.txtMessage.Properties.Appearance.Font = CType(resources.GetObject("txtMessage.Properties.Appearance.Font"), System.Drawing.Font) Me.txtMessage.Properties.Appearance.Font = CType(resources.GetObject("txtMessage.Properties.Appearance.Font"), System.Drawing.Font)
Me.txtMessage.Properties.Appearance.Options.UseFont = True Me.txtMessage.Properties.Appearance.Options.UseFont = True
Me.txtMessage.StyleController = Me.LayoutControl1 Me.txtMessage.StyleController = Me.LayoutControl1
@@ -664,7 +665,7 @@ Partial Public Class frmEnvelopeEditor
Me.LayoutControlItem3.Size = New System.Drawing.Size(873, 216) Me.LayoutControlItem3.Size = New System.Drawing.Size(873, 216)
resources.ApplyResources(Me.LayoutControlItem3, "LayoutControlItem3") resources.ApplyResources(Me.LayoutControlItem3, "LayoutControlItem3")
Me.LayoutControlItem3.TextLocation = DevExpress.Utils.Locations.Top Me.LayoutControlItem3.TextLocation = DevExpress.Utils.Locations.Top
Me.LayoutControlItem3.TextSize = New System.Drawing.Size(49, 13) Me.LayoutControlItem3.TextSize = New System.Drawing.Size(46, 13)
' '
'FrmEditorBindingSource 'FrmEditorBindingSource
' '

View File

@@ -939,7 +939,7 @@
<value>0</value> <value>0</value>
</data> </data>
<metadata name="FrmEditorBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="FrmEditorBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>792, 17</value> <value>17, 54</value>
</metadata> </metadata>
<metadata name="EnvelopeDocumentBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="EnvelopeDocumentBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>557, 17</value> <value>557, 17</value>

View File

@@ -200,7 +200,7 @@ Partial Public Class frmEnvelopeEditor
Private Sub btnSave_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnSave.ItemClick Private Sub btnSave_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnSave.ItemClick
Try Try
If SaveEnvelopeWithOutValidation() = True Then If SaveEnvelopeWithOutValidation() = True Then
bsitm_info.Caption = "Data saved succeddfully " + Now.ToString bsitm_info.Caption = "Data saved successfully " + Now.ToString
Else Else
bsitm_info.Caption = "Exceprion - Error saving Data. Check LOG" bsitm_info.Caption = "Exceprion - Error saving Data. Check LOG"
End If End If

View File

@@ -47,6 +47,7 @@ Partial Class frmMain
Me.colStatus = New DevExpress.XtraGrid.Columns.GridColumn() Me.colStatus = New DevExpress.XtraGrid.Columns.GridColumn()
Me.colTitle = New DevExpress.XtraGrid.Columns.GridColumn() Me.colTitle = New DevExpress.XtraGrid.Columns.GridColumn()
Me.colAddedWhen = New DevExpress.XtraGrid.Columns.GridColumn() Me.colAddedWhen = New DevExpress.XtraGrid.Columns.GridColumn()
Me.GridColumn2 = New DevExpress.XtraGrid.Columns.GridColumn()
Me.RibbonControl = New DevExpress.XtraBars.Ribbon.RibbonControl() Me.RibbonControl = New DevExpress.XtraBars.Ribbon.RibbonControl()
Me.btnCreateEnvelope = New DevExpress.XtraBars.BarButtonItem() Me.btnCreateEnvelope = New DevExpress.XtraBars.BarButtonItem()
Me.btnEditEnvelope = New DevExpress.XtraBars.BarButtonItem() Me.btnEditEnvelope = New DevExpress.XtraBars.BarButtonItem()
@@ -61,9 +62,10 @@ Partial Class frmMain
Me.bsitmInfo = New DevExpress.XtraBars.BarStaticItem() Me.bsitmInfo = New DevExpress.XtraBars.BarStaticItem()
Me.bbtnitmEB = New DevExpress.XtraBars.BarButtonItem() Me.bbtnitmEB = New DevExpress.XtraBars.BarButtonItem()
Me.bbtnitmInfoMail = New DevExpress.XtraBars.BarButtonItem() Me.bbtnitmInfoMail = New DevExpress.XtraBars.BarButtonItem()
Me.BarButtonItem2 = New DevExpress.XtraBars.BarButtonItem() Me.bbtnitm_ResendInvitation = New DevExpress.XtraBars.BarButtonItem()
Me.BarButtonItem3 = New DevExpress.XtraBars.BarButtonItem() Me.BarButtonItem3 = New DevExpress.XtraBars.BarButtonItem()
Me.BarButtonItem4 = New DevExpress.XtraBars.BarButtonItem() Me.BarButtonItem4 = New DevExpress.XtraBars.BarButtonItem()
Me.BarStaticItemGhost = New DevExpress.XtraBars.BarStaticItem()
Me.RibbonPage1 = New DevExpress.XtraBars.Ribbon.RibbonPage() Me.RibbonPage1 = New DevExpress.XtraBars.Ribbon.RibbonPage()
Me.RibbonPageEnvelopeActions = New DevExpress.XtraBars.Ribbon.RibbonPageGroup() Me.RibbonPageEnvelopeActions = New DevExpress.XtraBars.Ribbon.RibbonPageGroup()
Me.RibbonPageGroup1 = New DevExpress.XtraBars.Ribbon.RibbonPageGroup() Me.RibbonPageGroup1 = New DevExpress.XtraBars.Ribbon.RibbonPageGroup()
@@ -87,13 +89,15 @@ Partial Class frmMain
Me.GridColumn4 = New DevExpress.XtraGrid.Columns.GridColumn() Me.GridColumn4 = New DevExpress.XtraGrid.Columns.GridColumn()
Me.GridColumn5 = New DevExpress.XtraGrid.Columns.GridColumn() Me.GridColumn5 = New DevExpress.XtraGrid.Columns.GridColumn()
Me.GridColumn7 = New DevExpress.XtraGrid.Columns.GridColumn() Me.GridColumn7 = New DevExpress.XtraGrid.Columns.GridColumn()
Me.GridColumn1 = New DevExpress.XtraGrid.Columns.GridColumn()
Me.XtraTabPageAdmin = New DevExpress.XtraTab.XtraTabPage() Me.XtraTabPageAdmin = New DevExpress.XtraTab.XtraTabPage()
Me.SplitContainerControl2 = New DevExpress.XtraEditors.SplitContainerControl() Me.SplitContainerControl2 = New DevExpress.XtraEditors.SplitContainerControl()
Me.GridControlData = New DevExpress.XtraGrid.GridControl() Me.GridControlData = New DevExpress.XtraGrid.GridControl()
Me.GridViewData = New DevExpress.XtraGrid.Views.Grid.GridView() Me.GridViewData = New DevExpress.XtraGrid.Views.Grid.GridView()
Me.PanelControl1 = New DevExpress.XtraEditors.PanelControl() Me.PanelControl1 = New DevExpress.XtraEditors.PanelControl()
Me.GroupControl2 = New DevExpress.XtraEditors.GroupControl() Me.GroupControl2 = New DevExpress.XtraEditors.GroupControl()
Me.LabelControl1 = New DevExpress.XtraEditors.LabelControl() Me.btnEvvallUs_lastmonth = New DevExpress.XtraEditors.SimpleButton()
Me.btnEvvallUs_thismonth = New DevExpress.XtraEditors.SimpleButton()
Me.GroupControl1 = New DevExpress.XtraEditors.GroupControl() Me.GroupControl1 = New DevExpress.XtraEditors.GroupControl()
Me.btnEnvelopes_All = New DevExpress.XtraEditors.SimpleButton() Me.btnEnvelopes_All = New DevExpress.XtraEditors.SimpleButton()
Me.btnEnvelopes_thisYear = New DevExpress.XtraEditors.SimpleButton() Me.btnEnvelopes_thisYear = New DevExpress.XtraEditors.SimpleButton()
@@ -102,7 +106,6 @@ Partial Class frmMain
Me.RefreshTimer = New System.Windows.Forms.Timer(Me.components) Me.RefreshTimer = New System.Windows.Forms.Timer(Me.components)
Me.SaveFileDialog1 = New System.Windows.Forms.SaveFileDialog() Me.SaveFileDialog1 = New System.Windows.Forms.SaveFileDialog()
Me.XtraSaveFileDialog1 = New DevExpress.XtraEditors.XtraSaveFileDialog(Me.components) Me.XtraSaveFileDialog1 = New DevExpress.XtraEditors.XtraSaveFileDialog(Me.components)
Me.BarStaticItemGhost = New DevExpress.XtraBars.BarStaticItem()
CType(Me.SplitContainerControl1, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.SplitContainerControl1, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.SplitContainerControl1.Panel1, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.SplitContainerControl1.Panel1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SplitContainerControl1.Panel1.SuspendLayout() Me.SplitContainerControl1.Panel1.SuspendLayout()
@@ -278,11 +281,12 @@ Partial Class frmMain
' '
'ViewEnvelopes 'ViewEnvelopes
' '
Me.ViewEnvelopes.Columns.AddRange(New DevExpress.XtraGrid.Columns.GridColumn() {Me.colEnvelopeId, Me.colContractType, Me.colStatus, Me.colTitle, Me.colAddedWhen}) Me.ViewEnvelopes.Columns.AddRange(New DevExpress.XtraGrid.Columns.GridColumn() {Me.colEnvelopeId, Me.colContractType, Me.colStatus, Me.colTitle, Me.colAddedWhen, Me.GridColumn2})
Me.ViewEnvelopes.GridControl = Me.GridEnvelopes Me.ViewEnvelopes.GridControl = Me.GridEnvelopes
Me.ViewEnvelopes.Name = "ViewEnvelopes" Me.ViewEnvelopes.Name = "ViewEnvelopes"
Me.ViewEnvelopes.OptionsBehavior.Editable = False Me.ViewEnvelopes.OptionsBehavior.Editable = False
Me.ViewEnvelopes.OptionsBehavior.ReadOnly = True Me.ViewEnvelopes.OptionsBehavior.ReadOnly = True
Me.ViewEnvelopes.OptionsView.ShowAutoFilterRow = True
Me.ViewEnvelopes.OptionsView.ShowIndicator = False Me.ViewEnvelopes.OptionsView.ShowIndicator = False
' '
'colEnvelopeId 'colEnvelopeId
@@ -317,12 +321,20 @@ Partial Class frmMain
Me.colAddedWhen.FieldName = "AddedWhen" Me.colAddedWhen.FieldName = "AddedWhen"
Me.colAddedWhen.Name = "colAddedWhen" Me.colAddedWhen.Name = "colAddedWhen"
' '
'GridColumn2
'
resources.ApplyResources(Me.GridColumn2, "GridColumn2")
Me.GridColumn2.DisplayFormat.FormatString = "G"
Me.GridColumn2.DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime
Me.GridColumn2.FieldName = "ChangedWhen"
Me.GridColumn2.Name = "GridColumn2"
'
'RibbonControl 'RibbonControl
' '
Me.RibbonControl.ExpandCollapseItem.Id = 0 Me.RibbonControl.ExpandCollapseItem.Id = 0
Me.RibbonControl.ExpandCollapseItem.ImageOptions.ImageIndex = CType(resources.GetObject("RibbonControl.ExpandCollapseItem.ImageOptions.ImageIndex"), Integer) Me.RibbonControl.ExpandCollapseItem.ImageOptions.ImageIndex = CType(resources.GetObject("RibbonControl.ExpandCollapseItem.ImageOptions.ImageIndex"), Integer)
Me.RibbonControl.ExpandCollapseItem.ImageOptions.LargeImageIndex = CType(resources.GetObject("RibbonControl.ExpandCollapseItem.ImageOptions.LargeImageIndex"), Integer) Me.RibbonControl.ExpandCollapseItem.ImageOptions.LargeImageIndex = CType(resources.GetObject("RibbonControl.ExpandCollapseItem.ImageOptions.LargeImageIndex"), Integer)
Me.RibbonControl.Items.AddRange(New DevExpress.XtraBars.BarItem() {Me.RibbonControl.ExpandCollapseItem, Me.RibbonControl.SearchEditItem, Me.btnCreateEnvelope, Me.btnEditEnvelope, Me.btnDeleteEnvelope, Me.BarButtonItem1, Me.txtRefreshLabel, Me.btnShowDocument, Me.btnContactReceiver, Me.txtEnvelopeIdLabel, Me.btnOpenLogDirectory, Me.BarCheckItem1, Me.bsitmInfo, Me.bbtnitmEB, Me.bbtnitmInfoMail, Me.BarButtonItem2, Me.BarButtonItem3, Me.BarButtonItem4, Me.BarStaticItemGhost}) Me.RibbonControl.Items.AddRange(New DevExpress.XtraBars.BarItem() {Me.RibbonControl.ExpandCollapseItem, Me.RibbonControl.SearchEditItem, Me.btnCreateEnvelope, Me.btnEditEnvelope, Me.btnDeleteEnvelope, Me.BarButtonItem1, Me.txtRefreshLabel, Me.btnShowDocument, Me.btnContactReceiver, Me.txtEnvelopeIdLabel, Me.btnOpenLogDirectory, Me.BarCheckItem1, Me.bsitmInfo, Me.bbtnitmEB, Me.bbtnitmInfoMail, Me.bbtnitm_ResendInvitation, Me.BarButtonItem3, Me.BarButtonItem4, Me.BarStaticItemGhost})
resources.ApplyResources(Me.RibbonControl, "RibbonControl") resources.ApplyResources(Me.RibbonControl, "RibbonControl")
Me.RibbonControl.MaxItemId = 20 Me.RibbonControl.MaxItemId = 20
Me.RibbonControl.Name = "RibbonControl" Me.RibbonControl.Name = "RibbonControl"
@@ -446,13 +458,14 @@ Partial Class frmMain
Me.bbtnitmInfoMail.Id = 15 Me.bbtnitmInfoMail.Id = 15
Me.bbtnitmInfoMail.ImageOptions.SvgImage = CType(resources.GetObject("bbtnitmInfoMail.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage) Me.bbtnitmInfoMail.ImageOptions.SvgImage = CType(resources.GetObject("bbtnitmInfoMail.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
Me.bbtnitmInfoMail.Name = "bbtnitmInfoMail" Me.bbtnitmInfoMail.Name = "bbtnitmInfoMail"
Me.bbtnitmInfoMail.Visibility = DevExpress.XtraBars.BarItemVisibility.Never
' '
'BarButtonItem2 'bbtnitm_ResendInvitation
' '
resources.ApplyResources(Me.BarButtonItem2, "BarButtonItem2") resources.ApplyResources(Me.bbtnitm_ResendInvitation, "bbtnitm_ResendInvitation")
Me.BarButtonItem2.Id = 16 Me.bbtnitm_ResendInvitation.Id = 16
Me.BarButtonItem2.ImageOptions.SvgImage = CType(resources.GetObject("BarButtonItem2.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage) Me.bbtnitm_ResendInvitation.ImageOptions.SvgImage = CType(resources.GetObject("bbtnitm_ResendInvitation.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
Me.BarButtonItem2.Name = "BarButtonItem2" Me.bbtnitm_ResendInvitation.Name = "bbtnitm_ResendInvitation"
' '
'BarButtonItem3 'BarButtonItem3
' '
@@ -468,6 +481,19 @@ Partial Class frmMain
Me.BarButtonItem4.ImageOptions.SvgImage = CType(resources.GetObject("BarButtonItem4.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage) Me.BarButtonItem4.ImageOptions.SvgImage = CType(resources.GetObject("BarButtonItem4.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
Me.BarButtonItem4.Name = "BarButtonItem4" Me.BarButtonItem4.Name = "BarButtonItem4"
' '
'BarStaticItemGhost
'
resources.ApplyResources(Me.BarStaticItemGhost, "BarStaticItemGhost")
Me.BarStaticItemGhost.Id = 19
Me.BarStaticItemGhost.ItemAppearance.Normal.BackColor = System.Drawing.Color.Yellow
Me.BarStaticItemGhost.ItemAppearance.Normal.Font = CType(resources.GetObject("BarStaticItemGhost.ItemAppearance.Normal.Font"), System.Drawing.Font)
Me.BarStaticItemGhost.ItemAppearance.Normal.ForeColor = System.Drawing.Color.Black
Me.BarStaticItemGhost.ItemAppearance.Normal.Options.UseBackColor = True
Me.BarStaticItemGhost.ItemAppearance.Normal.Options.UseFont = True
Me.BarStaticItemGhost.ItemAppearance.Normal.Options.UseForeColor = True
Me.BarStaticItemGhost.Name = "BarStaticItemGhost"
Me.BarStaticItemGhost.Visibility = DevExpress.XtraBars.BarItemVisibility.Never
'
'RibbonPage1 'RibbonPage1
' '
Me.RibbonPage1.Groups.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPageGroup() {Me.RibbonPageEnvelopeActions, Me.RibbonPageGroup1, Me.RibbonPageGroupFunctions}) Me.RibbonPage1.Groups.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPageGroup() {Me.RibbonPageEnvelopeActions, Me.RibbonPageGroup1, Me.RibbonPageGroupFunctions})
@@ -493,7 +519,7 @@ Partial Class frmMain
'RibbonPageGroupFunctions 'RibbonPageGroupFunctions
' '
Me.RibbonPageGroupFunctions.ItemLinks.Add(Me.btnShowDocument) Me.RibbonPageGroupFunctions.ItemLinks.Add(Me.btnShowDocument)
Me.RibbonPageGroupFunctions.ItemLinks.Add(Me.BarButtonItem2) Me.RibbonPageGroupFunctions.ItemLinks.Add(Me.bbtnitm_ResendInvitation)
Me.RibbonPageGroupFunctions.ItemLinks.Add(Me.btnContactReceiver) Me.RibbonPageGroupFunctions.ItemLinks.Add(Me.btnContactReceiver)
Me.RibbonPageGroupFunctions.ItemLinks.Add(Me.bbtnitmEB) Me.RibbonPageGroupFunctions.ItemLinks.Add(Me.bbtnitmEB)
Me.RibbonPageGroupFunctions.ItemLinks.Add(Me.bbtnitmInfoMail) Me.RibbonPageGroupFunctions.ItemLinks.Add(Me.bbtnitmInfoMail)
@@ -622,11 +648,12 @@ Partial Class frmMain
' '
'ViewCompleted 'ViewCompleted
' '
Me.ViewCompleted.Columns.AddRange(New DevExpress.XtraGrid.Columns.GridColumn() {Me.GridColumn3, Me.GridColumn4, Me.GridColumn5, Me.GridColumn7}) Me.ViewCompleted.Columns.AddRange(New DevExpress.XtraGrid.Columns.GridColumn() {Me.GridColumn3, Me.GridColumn4, Me.GridColumn5, Me.GridColumn7, Me.GridColumn1})
Me.ViewCompleted.GridControl = Me.GridCompleted Me.ViewCompleted.GridControl = Me.GridCompleted
Me.ViewCompleted.Name = "ViewCompleted" Me.ViewCompleted.Name = "ViewCompleted"
Me.ViewCompleted.OptionsBehavior.Editable = False Me.ViewCompleted.OptionsBehavior.Editable = False
Me.ViewCompleted.OptionsBehavior.ReadOnly = True Me.ViewCompleted.OptionsBehavior.ReadOnly = True
Me.ViewCompleted.OptionsView.ShowAutoFilterRow = True
Me.ViewCompleted.OptionsView.ShowIndicator = False Me.ViewCompleted.OptionsView.ShowIndicator = False
' '
'GridColumn3 'GridColumn3
@@ -650,9 +677,19 @@ Partial Class frmMain
'GridColumn7 'GridColumn7
' '
resources.ApplyResources(Me.GridColumn7, "GridColumn7") resources.ApplyResources(Me.GridColumn7, "GridColumn7")
Me.GridColumn7.DisplayFormat.FormatString = "G"
Me.GridColumn7.DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime
Me.GridColumn7.FieldName = "AddedWhen" Me.GridColumn7.FieldName = "AddedWhen"
Me.GridColumn7.Name = "GridColumn7" Me.GridColumn7.Name = "GridColumn7"
' '
'GridColumn1
'
resources.ApplyResources(Me.GridColumn1, "GridColumn1")
Me.GridColumn1.DisplayFormat.FormatString = "G"
Me.GridColumn1.DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime
Me.GridColumn1.FieldName = "ChangedWhen"
Me.GridColumn1.Name = "GridColumn1"
'
'XtraTabPageAdmin 'XtraTabPageAdmin
' '
Me.XtraTabPageAdmin.Controls.Add(Me.SplitContainerControl2) Me.XtraTabPageAdmin.Controls.Add(Me.SplitContainerControl2)
@@ -673,7 +710,7 @@ Partial Class frmMain
'SplitContainerControl2.Panel2 'SplitContainerControl2.Panel2
' '
resources.ApplyResources(Me.SplitContainerControl2.Panel2, "SplitContainerControl2.Panel2") resources.ApplyResources(Me.SplitContainerControl2.Panel2, "SplitContainerControl2.Panel2")
Me.SplitContainerControl2.SplitterPosition = 584 Me.SplitContainerControl2.SplitterPosition = 907
' '
'GridControlData 'GridControlData
' '
@@ -687,6 +724,7 @@ Partial Class frmMain
' '
Me.GridViewData.GridControl = Me.GridControlData Me.GridViewData.GridControl = Me.GridControlData
Me.GridViewData.Name = "GridViewData" Me.GridViewData.Name = "GridViewData"
Me.GridViewData.OptionsView.ShowAutoFilterRow = True
' '
'PanelControl1 'PanelControl1
' '
@@ -697,14 +735,24 @@ Partial Class frmMain
' '
'GroupControl2 'GroupControl2
' '
Me.GroupControl2.Controls.Add(Me.LabelControl1) Me.GroupControl2.Controls.Add(Me.btnEvvallUs_lastmonth)
Me.GroupControl2.Controls.Add(Me.btnEvvallUs_thismonth)
resources.ApplyResources(Me.GroupControl2, "GroupControl2") resources.ApplyResources(Me.GroupControl2, "GroupControl2")
Me.GroupControl2.Name = "GroupControl2" Me.GroupControl2.Name = "GroupControl2"
' '
'LabelControl1 'btnEvvallUs_lastmonth
' '
resources.ApplyResources(Me.LabelControl1, "LabelControl1") Me.btnEvvallUs_lastmonth.Appearance.BackColor = System.Drawing.Color.MediumPurple
Me.LabelControl1.Name = "LabelControl1" Me.btnEvvallUs_lastmonth.Appearance.Options.UseBackColor = True
resources.ApplyResources(Me.btnEvvallUs_lastmonth, "btnEvvallUs_lastmonth")
Me.btnEvvallUs_lastmonth.Name = "btnEvvallUs_lastmonth"
'
'btnEvvallUs_thismonth
'
Me.btnEvvallUs_thismonth.Appearance.BackColor = System.Drawing.Color.MediumSlateBlue
Me.btnEvvallUs_thismonth.Appearance.Options.UseBackColor = True
resources.ApplyResources(Me.btnEvvallUs_thismonth, "btnEvvallUs_thismonth")
Me.btnEvvallUs_thismonth.Name = "btnEvvallUs_thismonth"
' '
'GroupControl1 'GroupControl1
' '
@@ -755,19 +803,6 @@ Partial Class frmMain
' '
Me.XtraSaveFileDialog1.FileName = "XtraSaveFileDialog1" Me.XtraSaveFileDialog1.FileName = "XtraSaveFileDialog1"
' '
'BarStaticItemGhost
'
resources.ApplyResources(Me.BarStaticItemGhost, "BarStaticItemGhost")
Me.BarStaticItemGhost.Id = 19
Me.BarStaticItemGhost.ItemAppearance.Normal.BackColor = System.Drawing.Color.Yellow
Me.BarStaticItemGhost.ItemAppearance.Normal.Font = CType(resources.GetObject("BarStaticItemGhost.ItemAppearance.Normal.Font"), System.Drawing.Font)
Me.BarStaticItemGhost.ItemAppearance.Normal.ForeColor = System.Drawing.Color.Black
Me.BarStaticItemGhost.ItemAppearance.Normal.Options.UseBackColor = True
Me.BarStaticItemGhost.ItemAppearance.Normal.Options.UseFont = True
Me.BarStaticItemGhost.ItemAppearance.Normal.Options.UseForeColor = True
Me.BarStaticItemGhost.Name = "BarStaticItemGhost"
Me.BarStaticItemGhost.Visibility = DevExpress.XtraBars.BarItemVisibility.Never
'
'frmMain 'frmMain
' '
resources.ApplyResources(Me, "$this") resources.ApplyResources(Me, "$this")
@@ -809,7 +844,6 @@ Partial Class frmMain
Me.PanelControl1.ResumeLayout(False) Me.PanelControl1.ResumeLayout(False)
CType(Me.GroupControl2, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.GroupControl2, System.ComponentModel.ISupportInitialize).EndInit()
Me.GroupControl2.ResumeLayout(False) Me.GroupControl2.ResumeLayout(False)
Me.GroupControl2.PerformLayout()
CType(Me.GroupControl1, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.GroupControl1, System.ComponentModel.ISupportInitialize).EndInit()
Me.GroupControl1.ResumeLayout(False) Me.GroupControl1.ResumeLayout(False)
Me.ResumeLayout(False) Me.ResumeLayout(False)
@@ -876,7 +910,7 @@ Partial Class frmMain
Friend WithEvents SaveFileDialog1 As SaveFileDialog Friend WithEvents SaveFileDialog1 As SaveFileDialog
Friend WithEvents bbtnitmEB As DevExpress.XtraBars.BarButtonItem Friend WithEvents bbtnitmEB As DevExpress.XtraBars.BarButtonItem
Friend WithEvents bbtnitmInfoMail As DevExpress.XtraBars.BarButtonItem Friend WithEvents bbtnitmInfoMail As DevExpress.XtraBars.BarButtonItem
Friend WithEvents BarButtonItem2 As DevExpress.XtraBars.BarButtonItem Friend WithEvents bbtnitm_ResendInvitation As DevExpress.XtraBars.BarButtonItem
Friend WithEvents XtraTabPageAdmin As DevExpress.XtraTab.XtraTabPage Friend WithEvents XtraTabPageAdmin As DevExpress.XtraTab.XtraTabPage
Friend WithEvents PanelControl1 As DevExpress.XtraEditors.PanelControl Friend WithEvents PanelControl1 As DevExpress.XtraEditors.PanelControl
Friend WithEvents GroupControl1 As DevExpress.XtraEditors.GroupControl Friend WithEvents GroupControl1 As DevExpress.XtraEditors.GroupControl
@@ -888,10 +922,13 @@ Partial Class frmMain
Friend WithEvents GridViewData As DevExpress.XtraGrid.Views.Grid.GridView Friend WithEvents GridViewData As DevExpress.XtraGrid.Views.Grid.GridView
Friend WithEvents GroupControl2 As DevExpress.XtraEditors.GroupControl Friend WithEvents GroupControl2 As DevExpress.XtraEditors.GroupControl
Friend WithEvents SplitContainerControl2 As DevExpress.XtraEditors.SplitContainerControl Friend WithEvents SplitContainerControl2 As DevExpress.XtraEditors.SplitContainerControl
Friend WithEvents LabelControl1 As DevExpress.XtraEditors.LabelControl
Friend WithEvents BarButtonItem3 As DevExpress.XtraBars.BarButtonItem Friend WithEvents BarButtonItem3 As DevExpress.XtraBars.BarButtonItem
Friend WithEvents XtraSaveFileDialog1 As DevExpress.XtraEditors.XtraSaveFileDialog Friend WithEvents XtraSaveFileDialog1 As DevExpress.XtraEditors.XtraSaveFileDialog
Friend WithEvents RibbonPageGroupFunctions As DevExpress.XtraBars.Ribbon.RibbonPageGroup Friend WithEvents RibbonPageGroupFunctions As DevExpress.XtraBars.Ribbon.RibbonPageGroup
Friend WithEvents BarButtonItem4 As DevExpress.XtraBars.BarButtonItem Friend WithEvents BarButtonItem4 As DevExpress.XtraBars.BarButtonItem
Friend WithEvents BarStaticItemGhost As DevExpress.XtraBars.BarStaticItem Friend WithEvents BarStaticItemGhost As DevExpress.XtraBars.BarStaticItem
Friend WithEvents btnEvvallUs_thismonth As DevExpress.XtraEditors.SimpleButton
Friend WithEvents btnEvvallUs_lastmonth As DevExpress.XtraEditors.SimpleButton
Friend WithEvents GridColumn1 As DevExpress.XtraGrid.Columns.GridColumn
Friend WithEvents GridColumn2 As DevExpress.XtraGrid.Columns.GridColumn
End Class End Class

View File

@@ -265,7 +265,7 @@
<value>2</value> <value>2</value>
</data> </data>
<data name="colContractType.Width" type="System.Int32, mscorlib"> <data name="colContractType.Width" type="System.Int32, mscorlib">
<value>120</value> <value>112</value>
</data> </data>
<data name="colStatus.Caption" xml:space="preserve"> <data name="colStatus.Caption" xml:space="preserve">
<value>Status</value> <value>Status</value>
@@ -277,7 +277,7 @@
<value>1</value> <value>1</value>
</data> </data>
<data name="colStatus.Width" type="System.Int32, mscorlib"> <data name="colStatus.Width" type="System.Int32, mscorlib">
<value>193</value> <value>180</value>
</data> </data>
<data name="colTitle.Caption" xml:space="preserve"> <data name="colTitle.Caption" xml:space="preserve">
<value>Titel</value> <value>Titel</value>
@@ -289,7 +289,7 @@
<value>0</value> <value>0</value>
</data> </data>
<data name="colTitle.Width" type="System.Int32, mscorlib"> <data name="colTitle.Width" type="System.Int32, mscorlib">
<value>575</value> <value>538</value>
</data> </data>
<data name="colAddedWhen.Caption" xml:space="preserve"> <data name="colAddedWhen.Caption" xml:space="preserve">
<value>Erstellt am</value> <value>Erstellt am</value>
@@ -301,7 +301,19 @@
<value>3</value> <value>3</value>
</data> </data>
<data name="colAddedWhen.Width" type="System.Int32, mscorlib"> <data name="colAddedWhen.Width" type="System.Int32, mscorlib">
<value>196</value> <value>130</value>
</data>
<data name="GridColumn2.Caption" xml:space="preserve">
<value>Zuletzt geändert am</value>
</data>
<data name="GridColumn2.Visible" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="GridColumn2.VisibleIndex" type="System.Int32, mscorlib">
<value>4</value>
</data>
<data name="GridColumn2.Width" type="System.Int32, mscorlib">
<value>130</value>
</data> </data>
<data name="RibbonControl.ExpandCollapseItem.ImageOptions.ImageIndex" type="System.Int32, mscorlib"> <data name="RibbonControl.ExpandCollapseItem.ImageOptions.ImageIndex" type="System.Int32, mscorlib">
<value>0</value> <value>0</value>
@@ -365,7 +377,7 @@
</value> </value>
</data> </data>
<data name="btnDeleteEnvelope.Caption" xml:space="preserve"> <data name="btnDeleteEnvelope.Caption" xml:space="preserve">
<value>Umschlag zurückrufen</value> <value>Umschlag zurückrufen/löschen</value>
</data> </data>
<data name="btnDeleteEnvelope.ImageOptions.ImageIndex" type="System.Int32, mscorlib"> <data name="btnDeleteEnvelope.ImageOptions.ImageIndex" type="System.Int32, mscorlib">
<value>0</value> <value>0</value>
@@ -733,10 +745,10 @@
IDwvZz4NCjwvc3ZnPgs= IDwvZz4NCjwvc3ZnPgs=
</value> </value>
</data> </data>
<data name="BarButtonItem2.Caption" xml:space="preserve"> <data name="bbtnitm_ResendInvitation.Caption" xml:space="preserve">
<value>Einladung erneut versenden</value> <value>Einladung erneut versenden</value>
</data> </data>
<data name="BarButtonItem2.ImageOptions.SvgImage" type="DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="bbtnitm_ResendInvitation.ImageOptions.SvgImage" type="DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40 AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
@@ -1052,7 +1064,7 @@
<value>2</value> <value>2</value>
</data> </data>
<data name="GridColumn3.Width" type="System.Int32, mscorlib"> <data name="GridColumn3.Width" type="System.Int32, mscorlib">
<value>120</value> <value>100</value>
</data> </data>
<data name="GridColumn4.Caption" xml:space="preserve"> <data name="GridColumn4.Caption" xml:space="preserve">
<value>Status</value> <value>Status</value>
@@ -1064,7 +1076,7 @@
<value>1</value> <value>1</value>
</data> </data>
<data name="GridColumn4.Width" type="System.Int32, mscorlib"> <data name="GridColumn4.Width" type="System.Int32, mscorlib">
<value>195</value> <value>163</value>
</data> </data>
<data name="GridColumn5.Caption" xml:space="preserve"> <data name="GridColumn5.Caption" xml:space="preserve">
<value>Titel</value> <value>Titel</value>
@@ -1076,7 +1088,7 @@
<value>0</value> <value>0</value>
</data> </data>
<data name="GridColumn5.Width" type="System.Int32, mscorlib"> <data name="GridColumn5.Width" type="System.Int32, mscorlib">
<value>574</value> <value>482</value>
</data> </data>
<data name="GridColumn7.Caption" xml:space="preserve"> <data name="GridColumn7.Caption" xml:space="preserve">
<value>Erstellt am</value> <value>Erstellt am</value>
@@ -1088,10 +1100,22 @@
<value>3</value> <value>3</value>
</data> </data>
<data name="GridColumn7.Width" type="System.Int32, mscorlib"> <data name="GridColumn7.Width" type="System.Int32, mscorlib">
<value>195</value> <value>120</value>
</data>
<data name="GridColumn1.Caption" xml:space="preserve">
<value>Zuletzt geändert am</value>
</data>
<data name="GridColumn1.Visible" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="GridColumn1.VisibleIndex" type="System.Int32, mscorlib">
<value>4</value>
</data>
<data name="GridColumn1.Width" type="System.Int32, mscorlib">
<value>120</value>
</data> </data>
<data name="GridCompleted.Size" type="System.Drawing.Size, System.Drawing"> <data name="GridCompleted.Size" type="System.Drawing.Size, System.Drawing">
<value>1088, 467</value> <value>1088, 469</value>
</data> </data>
<data name="GridCompleted.TabIndex" type="System.Int32, mscorlib"> <data name="GridCompleted.TabIndex" type="System.Int32, mscorlib">
<value>3</value> <value>3</value>
@@ -1109,7 +1133,7 @@
<value>0</value> <value>0</value>
</data> </data>
<data name="XtraTabPage2.Size" type="System.Drawing.Size, System.Drawing"> <data name="XtraTabPage2.Size" type="System.Drawing.Size, System.Drawing">
<value>1088, 467</value> <value>1088, 469</value>
</data> </data>
<data name="XtraTabPage2.Text" xml:space="preserve"> <data name="XtraTabPage2.Text" xml:space="preserve">
<value>Abgeschlossene Umschläge</value> <value>Abgeschlossene Umschläge</value>
@@ -1139,7 +1163,7 @@
<value>0, 0</value> <value>0, 0</value>
</data> </data>
<data name="GridControlData.Size" type="System.Drawing.Size, System.Drawing"> <data name="GridControlData.Size" type="System.Drawing.Size, System.Drawing">
<value>584, 388</value> <value>907, 390</value>
</data> </data>
<data name="GridControlData.TabIndex" type="System.Int32, mscorlib"> <data name="GridControlData.TabIndex" type="System.Int32, mscorlib">
<value>1</value> <value>1</value>
@@ -1187,7 +1211,7 @@
<value>1</value> <value>1</value>
</data> </data>
<data name="SplitContainerControl2.Size" type="System.Drawing.Size, System.Drawing"> <data name="SplitContainerControl2.Size" type="System.Drawing.Size, System.Drawing">
<value>1088, 388</value> <value>1088, 390</value>
</data> </data>
<data name="SplitContainerControl2.TabIndex" type="System.Int32, mscorlib"> <data name="SplitContainerControl2.TabIndex" type="System.Int32, mscorlib">
<value>2</value> <value>2</value>
@@ -1204,41 +1228,65 @@
<data name="&gt;&gt;SplitContainerControl2.ZOrder" xml:space="preserve"> <data name="&gt;&gt;SplitContainerControl2.ZOrder" xml:space="preserve">
<value>0</value> <value>0</value>
</data> </data>
<data name="LabelControl1.Location" type="System.Drawing.Point, System.Drawing"> <data name="btnEvvallUs_lastmonth.Location" type="System.Drawing.Point, System.Drawing">
<value>17, 37</value> <value>109, 26</value>
</data> </data>
<data name="LabelControl1.Size" type="System.Drawing.Size, System.Drawing"> <data name="btnEvvallUs_lastmonth.Size" type="System.Drawing.Size, System.Drawing">
<value>120, 13</value> <value>98, 35</value>
</data> </data>
<data name="LabelControl1.TabIndex" type="System.Int32, mscorlib"> <data name="btnEvvallUs_lastmonth.TabIndex" type="System.Int32, mscorlib">
<value>0</value> <value>5</value>
</data> </data>
<data name="LabelControl1.Text" xml:space="preserve"> <data name="btnEvvallUs_lastmonth.Text" xml:space="preserve">
<value>Function not active so far</value> <value>Letzter Monat</value>
</data> </data>
<data name="&gt;&gt;LabelControl1.Name" xml:space="preserve"> <data name="&gt;&gt;btnEvvallUs_lastmonth.Name" xml:space="preserve">
<value>LabelControl1</value> <value>btnEvvallUs_lastmonth</value>
</data> </data>
<data name="&gt;&gt;LabelControl1.Type" xml:space="preserve"> <data name="&gt;&gt;btnEvvallUs_lastmonth.Type" xml:space="preserve">
<value>DevExpress.XtraEditors.LabelControl, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>DevExpress.XtraEditors.SimpleButton, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="&gt;&gt;LabelControl1.Parent" xml:space="preserve"> <data name="&gt;&gt;btnEvvallUs_lastmonth.Parent" xml:space="preserve">
<value>GroupControl2</value> <value>GroupControl2</value>
</data> </data>
<data name="&gt;&gt;LabelControl1.ZOrder" xml:space="preserve"> <data name="&gt;&gt;btnEvvallUs_lastmonth.ZOrder" xml:space="preserve">
<value>0</value> <value>0</value>
</data> </data>
<data name="btnEvvallUs_thismonth.Location" type="System.Drawing.Point, System.Drawing">
<value>5, 26</value>
</data>
<data name="btnEvvallUs_thismonth.Size" type="System.Drawing.Size, System.Drawing">
<value>98, 35</value>
</data>
<data name="btnEvvallUs_thismonth.TabIndex" type="System.Int32, mscorlib">
<value>4</value>
</data>
<data name="btnEvvallUs_thismonth.Text" xml:space="preserve">
<value>Dieser Monat</value>
</data>
<data name="&gt;&gt;btnEvvallUs_thismonth.Name" xml:space="preserve">
<value>btnEvvallUs_thismonth</value>
</data>
<data name="&gt;&gt;btnEvvallUs_thismonth.Type" xml:space="preserve">
<value>DevExpress.XtraEditors.SimpleButton, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="&gt;&gt;btnEvvallUs_thismonth.Parent" xml:space="preserve">
<value>GroupControl2</value>
</data>
<data name="&gt;&gt;btnEvvallUs_thismonth.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="GroupControl2.Location" type="System.Drawing.Point, System.Drawing"> <data name="GroupControl2.Location" type="System.Drawing.Point, System.Drawing">
<value>496, 5</value> <value>474, 5</value>
</data> </data>
<data name="GroupControl2.Size" type="System.Drawing.Size, System.Drawing"> <data name="GroupControl2.Size" type="System.Drawing.Size, System.Drawing">
<value>427, 68</value> <value>318, 68</value>
</data> </data>
<data name="GroupControl2.TabIndex" type="System.Int32, mscorlib"> <data name="GroupControl2.TabIndex" type="System.Int32, mscorlib">
<value>2</value> <value>2</value>
</data> </data>
<data name="GroupControl2.Text" xml:space="preserve"> <data name="GroupControl2.Text" xml:space="preserve">
<value>Diagramme</value> <value>Umschläge alle User (abrechnungsrelevant)</value>
</data> </data>
<data name="&gt;&gt;GroupControl2.Name" xml:space="preserve"> <data name="&gt;&gt;GroupControl2.Name" xml:space="preserve">
<value>GroupControl2</value> <value>GroupControl2</value>
@@ -1352,7 +1400,7 @@
<value>11, 5</value> <value>11, 5</value>
</data> </data>
<data name="GroupControl1.Size" type="System.Drawing.Size, System.Drawing"> <data name="GroupControl1.Size" type="System.Drawing.Size, System.Drawing">
<value>453, 68</value> <value>457, 68</value>
</data> </data>
<data name="GroupControl1.TabIndex" type="System.Int32, mscorlib"> <data name="GroupControl1.TabIndex" type="System.Int32, mscorlib">
<value>1</value> <value>1</value>
@@ -1397,7 +1445,7 @@
<value>1</value> <value>1</value>
</data> </data>
<data name="XtraTabPageAdmin.Size" type="System.Drawing.Size, System.Drawing"> <data name="XtraTabPageAdmin.Size" type="System.Drawing.Size, System.Drawing">
<value>1088, 467</value> <value>1088, 469</value>
</data> </data>
<data name="XtraTabPageAdmin.Text" xml:space="preserve"> <data name="XtraTabPageAdmin.Text" xml:space="preserve">
<value>Auswertungen (Admin) - BETA</value> <value>Auswertungen (Admin) - BETA</value>
@@ -1693,6 +1741,12 @@
<data name="&gt;&gt;colAddedWhen.Type" xml:space="preserve"> <data name="&gt;&gt;colAddedWhen.Type" xml:space="preserve">
<value>DevExpress.XtraGrid.Columns.GridColumn, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>DevExpress.XtraGrid.Columns.GridColumn, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="&gt;&gt;GridColumn2.Name" xml:space="preserve">
<value>GridColumn2</value>
</data>
<data name="&gt;&gt;GridColumn2.Type" xml:space="preserve">
<value>DevExpress.XtraGrid.Columns.GridColumn, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="&gt;&gt;btnCreateEnvelope.Name" xml:space="preserve"> <data name="&gt;&gt;btnCreateEnvelope.Name" xml:space="preserve">
<value>btnCreateEnvelope</value> <value>btnCreateEnvelope</value>
</data> </data>
@@ -1771,10 +1825,10 @@
<data name="&gt;&gt;bbtnitmInfoMail.Type" xml:space="preserve"> <data name="&gt;&gt;bbtnitmInfoMail.Type" xml:space="preserve">
<value>DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="&gt;&gt;BarButtonItem2.Name" xml:space="preserve"> <data name="&gt;&gt;bbtnitm_ResendInvitation.Name" xml:space="preserve">
<value>BarButtonItem2</value> <value>bbtnitm_ResendInvitation</value>
</data> </data>
<data name="&gt;&gt;BarButtonItem2.Type" xml:space="preserve"> <data name="&gt;&gt;bbtnitm_ResendInvitation.Type" xml:space="preserve">
<value>DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="&gt;&gt;BarButtonItem3.Name" xml:space="preserve"> <data name="&gt;&gt;BarButtonItem3.Name" xml:space="preserve">
@@ -1789,6 +1843,12 @@
<data name="&gt;&gt;BarButtonItem4.Type" xml:space="preserve"> <data name="&gt;&gt;BarButtonItem4.Type" xml:space="preserve">
<value>DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="&gt;&gt;BarStaticItemGhost.Name" xml:space="preserve">
<value>BarStaticItemGhost</value>
</data>
<data name="&gt;&gt;BarStaticItemGhost.Type" xml:space="preserve">
<value>DevExpress.XtraBars.BarStaticItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="&gt;&gt;RibbonPage1.Name" xml:space="preserve"> <data name="&gt;&gt;RibbonPage1.Name" xml:space="preserve">
<value>RibbonPage1</value> <value>RibbonPage1</value>
</data> </data>
@@ -1909,6 +1969,12 @@
<data name="&gt;&gt;GridColumn7.Type" xml:space="preserve"> <data name="&gt;&gt;GridColumn7.Type" xml:space="preserve">
<value>DevExpress.XtraGrid.Columns.GridColumn, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>DevExpress.XtraGrid.Columns.GridColumn, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="&gt;&gt;GridColumn1.Name" xml:space="preserve">
<value>GridColumn1</value>
</data>
<data name="&gt;&gt;GridColumn1.Type" xml:space="preserve">
<value>DevExpress.XtraGrid.Columns.GridColumn, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="&gt;&gt;GridViewData.Name" xml:space="preserve"> <data name="&gt;&gt;GridViewData.Name" xml:space="preserve">
<value>GridViewData</value> <value>GridViewData</value>
</data> </data>
@@ -1933,12 +1999,6 @@
<data name="&gt;&gt;XtraSaveFileDialog1.Type" xml:space="preserve"> <data name="&gt;&gt;XtraSaveFileDialog1.Type" xml:space="preserve">
<value>DevExpress.XtraEditors.XtraSaveFileDialog, DevExpress.XtraDialogs.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>DevExpress.XtraEditors.XtraSaveFileDialog, DevExpress.XtraDialogs.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="&gt;&gt;BarStaticItemGhost.Name" xml:space="preserve">
<value>BarStaticItemGhost</value>
</data>
<data name="&gt;&gt;BarStaticItemGhost.Type" xml:space="preserve">
<value>DevExpress.XtraBars.BarStaticItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve"> <data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>frmMain</value> <value>frmMain</value>
</data> </data>

View File

@@ -13,6 +13,7 @@ Imports EnvelopeGenerator.Common.My
Imports System.Diagnostics Imports System.Diagnostics
Imports System.ComponentModel Imports System.ComponentModel
Imports DevExpress.XtraPrinting Imports DevExpress.XtraPrinting
Imports System.Web
Public Class frmMain Public Class frmMain
Private ReadOnly LogConfig As LogConfig Private ReadOnly LogConfig As LogConfig
@@ -85,8 +86,14 @@ Public Class frmMain
GridBuilder.SetReadOnlyOptions(ViewHistory) GridBuilder.SetReadOnlyOptions(ViewHistory)
GridBuilder.SetDefaults(ViewHistory) GridBuilder.SetDefaults(ViewHistory)
GridEnvelopes.DataSource = Controller.ListEnvelopes() GridEnvelopes.DataSource = Controller.ListEnvelopes()
If ViewEnvelopes.RowCount = 0 Then
RibbonPageGroupFunctions.Enabled = False
btnDeleteEnvelope.Visibility = DevExpress.XtraBars.BarItemVisibility.Never
Else
RibbonPageGroupFunctions.Enabled = True
btnDeleteEnvelope.Visibility = DevExpress.XtraBars.BarItemVisibility.Always
End If
Catch ex As Exception Catch ex As Exception
Logger.Error(ex) Logger.Error(ex)
End Try End Try
@@ -176,7 +183,11 @@ Public Class frmMain
Private Sub btnDeleteEnvelope_ItemClick_1(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnDeleteEnvelope.ItemClick Private Sub btnDeleteEnvelope_ItemClick_1(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnDeleteEnvelope.ItemClick
Try Try
Dim oSelectedRows = ViewEnvelopes.GetSelectedRows() Dim oSelectedRows = ViewEnvelopes.GetSelectedRows()
Dim oEnvelope As Envelope = DirectCast(ViewEnvelopes.GetRow(oSelectedRows.First), Envelope)
If oSelectedRows.Count > 0 Then If oSelectedRows.Count > 0 Then
CurrentEnvelopID = oEnvelope.Id
CurrentEnvelopetitle = oEnvelope.Title
Dim ofrmAbort As New frmRueckruf Dim ofrmAbort As New frmRueckruf
frmRueckruf.ShowDialog() frmRueckruf.ShowDialog()
If frmRueckruf.Continue_Reject = True Then If frmRueckruf.Continue_Reject = True Then
@@ -196,29 +207,44 @@ Public Class frmMain
End Sub End Sub
Private Sub XtraTabControl1_SelectedPageChanged(sender As Object, e As DevExpress.XtraTab.TabPageChangedEventArgs) Handles XtraTabControlMain.SelectedPageChanged Private Sub XtraTabControl1_SelectedPageChanged(sender As Object, e As DevExpress.XtraTab.TabPageChangedEventArgs) Handles XtraTabControlMain.SelectedPageChanged
RibbonPageGroupFunctions.Enabled = True Dim oHandle = SplashScreenManager.ShowOverlayForm(Me)
RibbonPageEnvelopeActions.Enabled = True Try
Select Case XtraTabControlMain.SelectedTabPageIndex RibbonPageGroupFunctions.Enabled = True
Case 1 RibbonPageEnvelopeActions.Enabled = True
btnEditEnvelope.Enabled = False Select Case XtraTabControlMain.SelectedTabPageIndex
btnDeleteEnvelope.Enabled = False Case 1
btnContactReceiver.Enabled = False btnEditEnvelope.Enabled = False
btnShowDocument.Enabled = False btnDeleteEnvelope.Enabled = False
bbtnitmEB.Enabled = True btnContactReceiver.Enabled = False
LoadEnvelopeData() btnShowDocument.Enabled = False
Case 0 bbtnitm_ResendInvitation.Enabled = False
btnEditEnvelope.Enabled = True bbtnitmInfoMail.Enabled = False
btnDeleteEnvelope.Enabled = True bbtnitmEB.Enabled = True
btnContactReceiver.Enabled = True LoadEnvelopeData()
btnShowDocument.Enabled = True Case 0
bbtnitmEB.Enabled = False If ViewEnvelopes.RowCount = 0 Then
LoadEnvelopeData() RibbonPageGroupFunctions.Enabled = False
txtEnvelopeIdLabel.Caption = "No Envelope selected" End If
btnEditEnvelope.Enabled = True
btnDeleteEnvelope.Enabled = True
btnContactReceiver.Enabled = True
btnShowDocument.Enabled = True
bbtnitm_ResendInvitation.Enabled = True
bbtnitmInfoMail.Enabled = True
bbtnitmEB.Enabled = False
LoadEnvelopeData()
txtEnvelopeIdLabel.Caption = "No Envelope selected"
Case 2
RibbonPageGroupFunctions.Enabled = False
RibbonPageEnvelopeActions.Enabled = False
End Select
Catch ex As Exception
Logger.Error(ex)
Finally
SplashScreenManager.CloseOverlayForm(oHandle)
End Try
Case 2
RibbonPageGroupFunctions.Enabled = False
RibbonPageEnvelopeActions.Enabled = False
End Select
End Sub End Sub
Private Sub BarButtonItem1_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem1.ItemClick Private Sub BarButtonItem1_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem1.ItemClick
@@ -312,7 +338,7 @@ Public Class frmMain
e.Appearance.BackColor = ColorTranslator.FromHtml(Common.Constants.GREEN_300) e.Appearance.BackColor = ColorTranslator.FromHtml(Common.Constants.GREEN_300)
End If End If
If oEnvelope.Status = Common.Constants.EnvelopeStatus.EnvelopeDeleted Then If oEnvelope.Status = Common.Constants.EnvelopeStatus.EnvelopeDeleted Or oEnvelope.Status = Common.Constants.EnvelopeStatus.EnvelopeWithdrawn Or oEnvelope.Status = Common.Constants.EnvelopeStatus.EnvelopeRejected Then
e.Appearance.BackColor = ColorTranslator.FromHtml(Common.Constants.RED_300) e.Appearance.BackColor = ColorTranslator.FromHtml(Common.Constants.RED_300)
End If End If
End Sub End Sub
@@ -512,7 +538,7 @@ Public Class frmMain
End If End If
bbtnitmEB.Enabled = False bbtnitmEB.Enabled = False
RefreshTimer.Start() RefreshTimer.Start()
If USER_GHOST_MODE_ACTIVE Then If USER_GHOST_MODE_ACTIVE Or MYUSER.GhostModeActive Then
frmGhostMode.ShowDialog() frmGhostMode.ShowDialog()
If USER_GHOST_MODE_USRNAME <> "" Then If USER_GHOST_MODE_USRNAME <> "" Then
MyUserModel = New UserModel(MyState) MyUserModel = New UserModel(MyState)
@@ -520,7 +546,8 @@ Public Class frmMain
Dim oUser = MyUserModel.SelectUser() Dim oUser = MyUserModel.SelectUser()
If oUser IsNot Nothing Then If oUser IsNot Nothing Then
MyUserModel.CheckUserLogin(oUser) MyUserModel.CheckUserLogin(oUser)
BarStaticItemGhost.Caption = $"GhostMode active: {USER_GHOST_MODE_USRNAME} - End signFLOW to quit mode" BarStaticItemGhost.Caption = $"GhostMode active: {USER_GHOST_MODE_USRNAME} - End signFLOW to quit ghost-mode"
Me.Text = $"GhostMode active: {USER_GHOST_MODE_USRNAME} - End signFLOW to quit ghost - mode"
BarStaticItemGhost.Visibility = DevExpress.XtraBars.BarItemVisibility.Always BarStaticItemGhost.Visibility = DevExpress.XtraBars.BarItemVisibility.Always
LoadEnvelopeData() LoadEnvelopeData()
End If End If
@@ -538,31 +565,22 @@ Public Class frmMain
Dim oView As GridView = GridEnvelopes.FocusedView Dim oView As GridView = GridEnvelopes.FocusedView
If oView.Name = ViewReceivers.Name Then If oView.Name = ViewReceivers.Name Then
Dim oReceiver As EnvelopeReceiver = oView.GetRow(oView.FocusedRowHandle) Dim oReceiver As EnvelopeReceiver = oView.GetRow(oView.FocusedRowHandle)
Dim oEnvelopeTitle As String = Net.WebUtility.UrlEncode(oEnvelope.Title) Dim mailto As String = "mailto:support-flow@digitaldata.works"
Dim oCode = oReceiver.AccessCode Dim subject As String = Uri.EscapeDataString("signFLOW - Envelope issue - ID: " & oEnvelope.Id)
Dim oUID = oEnvelope.Uuid Dim body As String = Uri.EscapeDataString($"Dear Digital Data Team," & vbCrLf & "There is an error or misbehavin with following envelope and Receiver:" & vbCrLf &
$"Envelope-ID:{oEnvelope.Id}" & vbCrLf & $"Receiver: {oReceiver.Email}" & vbCrLf & "Issue/Description: Please describe the issue in Your own words...")
' E-Mail-Details konfigurieren Dim mailtoUri As String = $"{mailto}?subject={subject}&body={body}"
Dim mailto As String = "support-flow@digitaldata.works"
Dim subject As String = "signFLOW - Envelope issue"
Dim body As String = $"<html><body>Dear Digital Data Team, <br> There is an error or misbehavin with following envelope and Receiver: <p> Envelope: <b>{oUID}</b> <br> Receiver: <b>{oReceiver.Email}</b>
<p>Issue/Description: Please describe the issue in Your own words...</p></body></html>"
' URL-encoding für Betreff und Inhalt der E-Mail Dim psi As New ProcessStartInfo(mailtoUri)
'Dim encodedSubject As String = Uri.EscapeDataString(subject) psi.UseShellExecute = True
'Dim encodedBody As String = Uri.EscapeDataString(body)
' mailto-Link erstellen
Dim mailtoLink As String = $"{mailto}?subject={subject}&body={body}"
Try Try
Process.Start(mailtoLink) Process.Start(psi)
Catch ex1 As Exception Catch ex As Exception
MsgBox(ex1.Message, MsgBoxStyle.Critical, Text) MessageBox.Show("Error in creating mailto-Object: " & ex.Message)
End Try End Try
' E-Mail-Client öffnen
Process.Start($"mailto:{oReceiver.Email}?subject={oEnvelopeTitle}")
Else Else
MsgBox(Resources.Envelope.Please_select_a_recipient_from_the_Recipients_tab, MsgBoxStyle.Information, Text) MsgBox(Resources.Envelope.Please_select_a_recipient_from_the_Recipients_tab, MsgBoxStyle.Information, Text)
End If End If
@@ -572,7 +590,7 @@ Public Class frmMain
End Sub End Sub
Private Sub BarButtonItem2_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem2.ItemClick Private Sub BarButtonItem2_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnitm_ResendInvitation.ItemClick
Dim oView As GridView = GridEnvelopes.FocusedView Dim oView As GridView = GridEnvelopes.FocusedView
Dim selReceiver As EnvelopeReceiver Dim selReceiver As EnvelopeReceiver
If oView.Name = ViewReceivers.Name Then If oView.Name = ViewReceivers.Name Then
@@ -616,7 +634,9 @@ Public Class frmMain
If SQL_REP_ENV_USER_TM <> String.Empty Then If SQL_REP_ENV_USER_TM <> String.Empty Then
Result_Execute(SQL_REP_ENV_USER_TM) Result_Execute(SQL_REP_ENV_USER_TM)
Else Else
GridControlData.DataSource = Nothing GridControlData.DataSource = Nothing
GridViewData.Columns.Clear()
End If End If
End Sub End Sub
@@ -647,7 +667,9 @@ Public Class frmMain
Try Try
Dim oDT As DataTable = DB_DD_ECM.GetDatatable(mySQL) Dim oDT As DataTable = DB_DD_ECM.GetDatatable(mySQL)
If Not IsNothing(oDT) Then If Not IsNothing(oDT) Then
If GridViewData.Columns.Count > 0 Then
GridViewData.Columns.Clear()
End If
GridControlData.DataSource = oDT GridControlData.DataSource = oDT
Else Else
GridControlData.DataSource = Nothing GridControlData.DataSource = Nothing
@@ -657,7 +679,7 @@ Public Class frmMain
End Try End Try
End Sub End Sub
Private Sub LabelControl1_Click(sender As Object, e As EventArgs) Handles LabelControl1.Click Private Sub LabelControl1_Click(sender As Object, e As EventArgs)
End Sub End Sub
@@ -729,4 +751,20 @@ Public Class frmMain
Public Shared Sub Save_Logfiles() Public Shared Sub Save_Logfiles()
End Sub End Sub
Private Sub btnEvvallUs_thismonth_Click(sender As Object, e As EventArgs) Handles btnEvvallUs_thismonth.Click
If SQL_REP_ENV_ALL_USER_MONTH <> String.Empty Then
Result_Execute(SQL_REP_ENV_ALL_USER_MONTH)
Else
GridControlData.DataSource = Nothing
End If
End Sub
Private Sub btnEvvallUs_lastmonth_Click(sender As Object, e As EventArgs) Handles btnEvvallUs_lastmonth.Click
If SQL_REP_ENV_ALL_USER_LAST_MONTH <> String.Empty Then
Result_Execute(SQL_REP_ENV_ALL_USER_LAST_MONTH)
Else
GridControlData.DataSource = Nothing
End If
End Sub
End Class End Class

View File

@@ -30,13 +30,17 @@ Partial Class frmRueckruf
Me.StatusStrip1 = New System.Windows.Forms.StatusStrip() Me.StatusStrip1 = New System.Windows.Forms.StatusStrip()
Me.tsstatus = New System.Windows.Forms.ToolStripStatusLabel() Me.tsstatus = New System.Windows.Forms.ToolStripStatusLabel()
Me.SimpleButton1 = New DevExpress.XtraEditors.SimpleButton() Me.SimpleButton1 = New DevExpress.XtraEditors.SimpleButton()
Me.Label3 = New System.Windows.Forms.Label()
Me.Label4 = New System.Windows.Forms.Label()
Me.lblID = New System.Windows.Forms.Label()
Me.lblTitle = New System.Windows.Forms.Label()
Me.StatusStrip1.SuspendLayout() Me.StatusStrip1.SuspendLayout()
Me.SuspendLayout() Me.SuspendLayout()
' '
'Label2 'Label2
' '
Me.Label2.AutoSize = True Me.Label2.AutoSize = True
Me.Label2.Location = New System.Drawing.Point(22, 20) Me.Label2.Location = New System.Drawing.Point(28, 36)
Me.Label2.Margin = New System.Windows.Forms.Padding(4, 0, 4, 0) Me.Label2.Margin = New System.Windows.Forms.Padding(4, 0, 4, 0)
Me.Label2.Name = "Label2" Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(380, 16) Me.Label2.Size = New System.Drawing.Size(380, 16)
@@ -46,7 +50,7 @@ Partial Class frmRueckruf
'txtReason 'txtReason
' '
Me.txtReason.AcceptsReturn = True Me.txtReason.AcceptsReturn = True
Me.txtReason.Location = New System.Drawing.Point(25, 40) Me.txtReason.Location = New System.Drawing.Point(31, 56)
Me.txtReason.Margin = New System.Windows.Forms.Padding(4) Me.txtReason.Margin = New System.Windows.Forms.Padding(4)
Me.txtReason.Multiline = True Me.txtReason.Multiline = True
Me.txtReason.Name = "txtReason" Me.txtReason.Name = "txtReason"
@@ -66,7 +70,7 @@ Partial Class frmRueckruf
' '
Me.btnCancel.Image = CType(resources.GetObject("btnCancel.Image"), System.Drawing.Image) Me.btnCancel.Image = CType(resources.GetObject("btnCancel.Image"), System.Drawing.Image)
Me.btnCancel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft Me.btnCancel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft
Me.btnCancel.Location = New System.Drawing.Point(251, 134) Me.btnCancel.Location = New System.Drawing.Point(260, 150)
Me.btnCancel.Name = "btnCancel" Me.btnCancel.Name = "btnCancel"
Me.btnCancel.Size = New System.Drawing.Size(203, 44) Me.btnCancel.Size = New System.Drawing.Size(203, 44)
Me.btnCancel.TabIndex = 4 Me.btnCancel.TabIndex = 4
@@ -76,7 +80,7 @@ Partial Class frmRueckruf
'StatusStrip1 'StatusStrip1
' '
Me.StatusStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.tsstatus}) Me.StatusStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.tsstatus})
Me.StatusStrip1.Location = New System.Drawing.Point(0, 185) Me.StatusStrip1.Location = New System.Drawing.Point(0, 211)
Me.StatusStrip1.Name = "StatusStrip1" Me.StatusStrip1.Name = "StatusStrip1"
Me.StatusStrip1.Size = New System.Drawing.Size(488, 22) Me.StatusStrip1.Size = New System.Drawing.Size(488, 22)
Me.StatusStrip1.TabIndex = 5 Me.StatusStrip1.TabIndex = 5
@@ -90,17 +94,59 @@ Partial Class frmRueckruf
'SimpleButton1 'SimpleButton1
' '
Me.SimpleButton1.ImageOptions.SvgImage = CType(resources.GetObject("SimpleButton1.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage) Me.SimpleButton1.ImageOptions.SvgImage = CType(resources.GetObject("SimpleButton1.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
Me.SimpleButton1.Location = New System.Drawing.Point(25, 134) Me.SimpleButton1.Location = New System.Drawing.Point(31, 150)
Me.SimpleButton1.Name = "SimpleButton1" Me.SimpleButton1.Name = "SimpleButton1"
Me.SimpleButton1.Size = New System.Drawing.Size(220, 44) Me.SimpleButton1.Size = New System.Drawing.Size(220, 44)
Me.SimpleButton1.TabIndex = 6 Me.SimpleButton1.TabIndex = 6
Me.SimpleButton1.Text = "Umschlag zurückrufen" Me.SimpleButton1.Text = "Umschlag zurückrufen"
' '
'Label3
'
Me.Label3.AutoSize = True
Me.Label3.Location = New System.Drawing.Point(28, 9)
Me.Label3.Name = "Label3"
Me.Label3.Size = New System.Drawing.Size(80, 16)
Me.Label3.TabIndex = 7
Me.Label3.Text = "Envelope-ID:"
'
'Label4
'
Me.Label4.AutoSize = True
Me.Label4.Location = New System.Drawing.Point(158, 9)
Me.Label4.Name = "Label4"
Me.Label4.Size = New System.Drawing.Size(93, 16)
Me.Label4.TabIndex = 8
Me.Label4.Text = "Envelope-Titel:"
'
'lblID
'
Me.lblID.AutoSize = True
Me.lblID.Font = New System.Drawing.Font("Tahoma", 9.75!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.lblID.Location = New System.Drawing.Point(108, 9)
Me.lblID.Name = "lblID"
Me.lblID.Size = New System.Drawing.Size(49, 16)
Me.lblID.TabIndex = 9
Me.lblID.Text = "Label5"
'
'lblTitle
'
Me.lblTitle.AutoSize = True
Me.lblTitle.Font = New System.Drawing.Font("Tahoma", 9.75!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.lblTitle.Location = New System.Drawing.Point(257, 9)
Me.lblTitle.Name = "lblTitle"
Me.lblTitle.Size = New System.Drawing.Size(49, 16)
Me.lblTitle.TabIndex = 10
Me.lblTitle.Text = "Label5"
'
'frmRueckruf 'frmRueckruf
' '
Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 16.0!) Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 16.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(488, 207) Me.ClientSize = New System.Drawing.Size(488, 233)
Me.Controls.Add(Me.lblTitle)
Me.Controls.Add(Me.lblID)
Me.Controls.Add(Me.Label4)
Me.Controls.Add(Me.Label3)
Me.Controls.Add(Me.SimpleButton1) Me.Controls.Add(Me.SimpleButton1)
Me.Controls.Add(Me.StatusStrip1) Me.Controls.Add(Me.StatusStrip1)
Me.Controls.Add(Me.btnCancel) Me.Controls.Add(Me.btnCancel)
@@ -129,4 +175,8 @@ Partial Class frmRueckruf
Friend WithEvents StatusStrip1 As StatusStrip Friend WithEvents StatusStrip1 As StatusStrip
Friend WithEvents tsstatus As ToolStripStatusLabel Friend WithEvents tsstatus As ToolStripStatusLabel
Friend WithEvents SimpleButton1 As DevExpress.XtraEditors.SimpleButton Friend WithEvents SimpleButton1 As DevExpress.XtraEditors.SimpleButton
Friend WithEvents Label3 As Label
Friend WithEvents Label4 As Label
Friend WithEvents lblID As Label
Friend WithEvents lblTitle As Label
End Class End Class

View File

@@ -121,7 +121,7 @@
<data name="btnCancel.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="btnCancel.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wQAADsEBuJFr7QAAAUlJREFUOE+lU6GOg1AQ5BP6Cf2E+4QLnqQWV4EHjUJhGzxJJbICDxpFQvCHg4DA wAAADsABataJCQAAAUlJREFUOE+lU6GOg1AQ5BP6Cf2E+4QLnqQWV4EHjUJhGzxJJbICDxpFQvCHg4DA
Yd/tLPvK4wJ34iaZ9GVndxh4WwtYluVCfBIVcSYGLPwA1SPp0bxpIaiqSjmOw2zbdhMJdL4S6yzLlG3b Yd/tLPvK4wJ34iaZ9GVndxh4WwtYluVCfBIVcSYGLPwA1SPp0bxpIaiqSjmOw2zbdhMJdL4S6yzLlG3b
qigK6JHI3FCmacoi6HmeGscRSZAswDmOY9bQR7WXjK5AExJoAzBJEjTOXdexIWowoVpNvMjoChQg5Hm+ qigK6JHI3FCmacoi6HmeGscRSZAswDmOY9bQR7WXjK5AExJoAzBJEjTOXdexIWowoVpNvMjoChQg5Hm+
M8HT8Eo4G6muMrbHmQkIk2ma8PRPaT8G3Ikc1TSAKdWf0nYMGT5M4Lrun/E/iDM+nDlofgPf9/kDysgG M8HT8Eo4G6muMrbHmQkIk2ma8PRPaT8G3Ikc1TSAKdWf0nYMGT5M4Lrun/E/iDM+nDlofgPf9/kDysgG

View File

@@ -22,6 +22,8 @@ Public Class frmRueckruf
txtReason.Text = "" txtReason.Text = ""
tsstatus.Text = "" tsstatus.Text = ""
Continue_Reject = False Continue_Reject = False
lblID.Text = CurrentEnvelopID.ToString
lblTitle.Text = CurrentEnvelopetitle
End Sub End Sub
Private Sub SimpleButton1_Click(sender As Object, e As EventArgs) Handles SimpleButton1.Click Private Sub SimpleButton1_Click(sender As Object, e As EventArgs) Handles SimpleButton1.Click
@@ -50,4 +52,8 @@ Public Class frmRueckruf
tsstatus.Text = "Please add a reason for aborting - " & Now tsstatus.Text = "Please add a reason for aborting - " & Now
End If End If
End Sub End Sub
Private Sub Label2_Click(sender As Object, e As EventArgs) Handles Label2.Click
End Sub
End Class End Class

View File

@@ -88,6 +88,10 @@ Public Class frmSplashScreen
SQL_REP_ENV_USER_Y = oROW.Item("SQL_COMMAND") SQL_REP_ENV_USER_Y = oROW.Item("SQL_COMMAND")
ElseIf oROW.Item("TITLE") = "REPORT ENV USER ALL" Then ElseIf oROW.Item("TITLE") = "REPORT ENV USER ALL" Then
SQL_REP_ENV_USER_ALL = oROW.Item("SQL_COMMAND") SQL_REP_ENV_USER_ALL = oROW.Item("SQL_COMMAND")
ElseIf oROW.Item("TITLE") = "REPORT ENV ALL_USER_THIS_MONTH" Then
SQL_REP_ENV_ALL_USER_MONTH = oROW.Item("SQL_COMMAND")
ElseIf oROW.Item("TITLE") = "REPORT ENV ALL_USER_LAST_MONTH" Then
SQL_REP_ENV_ALL_USER_LAST_MONTH = oROW.Item("SQL_COMMAND")
End If End If
Next Next

View File

@@ -1,201 +1,150 @@
using DigitalData.Core.Abstractions.Application; using DigitalData.Core.Abstractions.Application;
using DigitalData.UserManager.Application.Contracts; using DigitalData.UserManager.Application.Contracts;
using DigitalData.UserManager.Application.DTOs.User;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using DigitalData.UserManager.Application.DTOs.Auth;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using EnvelopeGenerator.GeneratorAPI.Models; using EnvelopeGenerator.GeneratorAPI.Models;
namespace EnvelopeGenerator.GeneratorAPI.Controllers namespace EnvelopeGenerator.GeneratorAPI.Controllers;
/// <summary>
/// Controller verantwortlich für die Benutzer-Authentifizierung, einschließlich Anmelden, Abmelden und Überprüfung des Authentifizierungsstatus.
/// </summary>
[Route("api/[controller]")]
[ApiController]
public partial class AuthController : ControllerBase
{ {
private readonly ILogger<AuthController> _logger;
private readonly IUserService _userService;
private readonly IDirectorySearchService _dirSearchService;
/// <summary> /// <summary>
/// Controller verantwortlich für die Benutzer-Authentifizierung, einschließlich Anmelden, Abmelden und Überprüfung des Authentifizierungsstatus. /// Initializes a new instance of the <see cref="AuthController"/> class.
/// </summary> /// </summary>
[Route("api/[controller]")] /// <param name="logger">The logger instance.</param>
[ApiController] /// <param name="userService">The user service instance.</param>
public partial class AuthController : ControllerBase /// <param name="dirSearchService">The directory search service instance.</param>
public AuthController(ILogger<AuthController> logger, IUserService userService, IDirectorySearchService dirSearchService)
{ {
private readonly ILogger<AuthController> _logger; _logger = logger;
private readonly IUserService _userService; _userService = userService;
private readonly IDirectorySearchService _dirSearchService; _dirSearchService = dirSearchService;
/// <summary>
/// Initializes a new instance of the <see cref="AuthController"/> class.
/// </summary>
/// <param name="logger">The logger instance.</param>
/// <param name="userService">The user service instance.</param>
/// <param name="dirSearchService">The directory search service instance.</param>
public AuthController(ILogger<AuthController> logger, IUserService userService, IDirectorySearchService dirSearchService)
{
_logger = logger;
_userService = userService;
_dirSearchService = dirSearchService;
}
/// <summary>
/// Authentifiziert einen Benutzer und generiert ein JWT-Token. Wenn 'cookie' wahr ist, wird das Token als HTTP-Only-Cookie zurückgegeben.
/// </summary>
/// <param name="login">Benutzeranmeldedaten (Benutzername und Passwort).</param>
/// <param name="cookie">Wenn wahr, wird das JWT-Token auch als HTTP-Only-Cookie gesendet.</param>
/// <returns>
/// Gibt eine HTTP 200 oder 401.
/// </returns>
/// <remarks>
/// Sample request:
///
/// POST /api/auth?cookie=true
/// {
/// "username": "MaxMustermann",
/// "password": "Geheim123!"
/// }
///
/// POST /api/auth?cookie=true
/// {
/// "id": "1",
/// "password": "Geheim123!"
/// }
///
/// </remarks>
/// <response code="200">Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist.</response>
/// <response code="401">Unbefugt. Ungültiger Benutzername oder Passwort.</response>
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> Login([FromBody] Login login, [FromQuery] bool cookie = false)
{
try
{
bool isValid = _dirSearchService.ValidateCredentials(login.Username, login.Password);
if (!isValid)
return Unauthorized();
//find the user
var uRes = await _userService.ReadByUsernameAsync(login.Username);
if (!uRes.IsSuccess || uRes.Data is null)
{
return Forbid();
}
UserReadDto user = uRes.Data;
// Create claims
var claims = new List<Claim>
{
new (ClaimTypes.NameIdentifier, user.Id.ToString()),
new (ClaimTypes.Name, user.Username),
new (ClaimTypes.Surname, user.Name!),
new (ClaimTypes.GivenName, user.Prename!),
new (ClaimTypes.Email, user.Email!),
};
// Create claimsIdentity
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
// Create authProperties
var authProperties = new AuthenticationProperties
{
IsPersistent = true,
AllowRefresh = true,
ExpiresUtc = DateTime.Now.AddMinutes(180)
};
// Sign in
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
return Ok();
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error occurred.\n{ErrorMessage}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
/// <summary>
/// Authentifiziert einen Benutzer und generiert ein JWT-Token. Das Token wird als HTTP-only-Cookie zurückgegeben.
/// </summary>
/// <param name="login">Benutzeranmeldedaten (Benutzername und Passwort).</param>
/// <returns>
/// Gibt eine HTTP 200 oder 401.
/// </returns>
/// <remarks>
/// Sample request:
///
/// POST /api/auth/form
/// {
/// "username": "MaxMustermann",
/// "password": "Geheim123!"
/// }
///
/// </remarks>
/// <response code="200">Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist.</response>
/// <response code="401">Unbefugt. Ungültiger Benutzername oder Passwort.</response>
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[AllowAnonymous]
[HttpPost]
[Route("form")]
public async Task<IActionResult> Login([FromForm] Login login)
{
return await Login(login, true);
}
/// <summary>
/// Entfernt das Authentifizierungs-Cookie des Benutzers (AuthCookie)
/// </summary>
/// <returns>
/// Gibt eine HTTP 200 oder 401.
/// </returns>
/// <remarks>
/// Sample request:
///
/// POST /api/auth/logout
///
/// </remarks>
/// <response code="200">Erfolgreich gelöscht, wenn der Benutzer ein berechtigtes Cookie hat.</response>
/// <response code="401">Wenn es kein zugelassenes Cookie gibt, wird „nicht zugelassen“ zurückgegeben.</response>
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[Authorize]
[HttpPost("logout")]
public async Task<IActionResult> Logout()
{
try
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Ok();
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error occurred.\n{ErrorMessage}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
/// <summary>
/// Prüft, ob der Benutzer ein autorisiertes Token hat.
/// </summary>
/// <returns>Wenn ein autorisiertes Token vorhanden ist HTTP 200 asynchron 401</returns>
/// <remarks>
/// Sample request:
///
/// GET /api/auth
///
/// </remarks>
/// <response code="200">Wenn es einen autorisierten Cookie gibt.</response>
/// <response code="401">Wenn kein Cookie vorhanden ist oder nicht autorisierte.</response>
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[Authorize]
[HttpGet]
public IActionResult IsAuthenticated() => Ok();
} }
/// <summary>
/// Authentifiziert einen Benutzer und generiert ein JWT-Token. Wenn 'cookie' wahr ist, wird das Token als HTTP-Only-Cookie zurückgegeben.
/// </summary>
/// <param name="login">Benutzeranmeldedaten (Benutzername und Passwort).</param>
/// <param name="cookie">Wenn wahr, wird das JWT-Token auch als HTTP-Only-Cookie gesendet.</param>
/// <returns>
/// Gibt eine HTTP 200 oder 401.
/// </returns>
/// <remarks>
/// Sample request:
///
/// POST /api/auth?cookie=true
/// {
/// "username": "MaxMustermann",
/// "password": "Geheim123!"
/// }
///
/// POST /api/auth?cookie=true
/// {
/// "id": "1",
/// "password": "Geheim123!"
/// }
///
/// </remarks>
/// <response code="200">Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist.</response>
/// <response code="401">Unbefugt. Ungültiger Benutzername oder Passwort.</response>
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[AllowAnonymous]
[HttpPost]
public Task<IActionResult> Login([FromBody] Login login, [FromQuery] bool cookie = false)
{
// added to configure open API (swagger and scalar)
throw new NotImplementedException();
}
/// <summary>
/// Authentifiziert einen Benutzer und generiert ein JWT-Token. Das Token wird als HTTP-only-Cookie zurückgegeben.
/// </summary>
/// <param name="login">Benutzeranmeldedaten (Benutzername und Passwort).</param>
/// <returns>
/// Gibt eine HTTP 200 oder 401.
/// </returns>
/// <remarks>
/// Sample request:
///
/// POST /api/auth/form
/// {
/// "username": "MaxMustermann",
/// "password": "Geheim123!"
/// }
///
/// </remarks>
/// <response code="200">Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist.</response>
/// <response code="401">Unbefugt. Ungültiger Benutzername oder Passwort.</response>
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[AllowAnonymous]
[HttpPost]
[Route("form")]
public Task<IActionResult> Login([FromForm] Login login)
{
// added to configure open API (swagger and scalar)
throw new NotImplementedException();
}
/// <summary>
/// Entfernt das Authentifizierungs-Cookie des Benutzers (AuthCookie)
/// </summary>
/// <returns>
/// Gibt eine HTTP 200 oder 401.
/// </returns>
/// <remarks>
/// Sample request:
///
/// POST /api/auth/logout
///
/// </remarks>
/// <response code="200">Erfolgreich gelöscht, wenn der Benutzer ein berechtigtes Cookie hat.</response>
/// <response code="401">Wenn es kein zugelassenes Cookie gibt, wird „nicht zugelassen“ zurückgegeben.</response>
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[Authorize]
[HttpPost("logout")]
public async Task<IActionResult> Logout()
{
try
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Ok();
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error occurred.\n{ErrorMessage}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
/// <summary>
/// Prüft, ob der Benutzer ein autorisiertes Token hat.
/// </summary>
/// <returns>Wenn ein autorisiertes Token vorhanden ist HTTP 200 asynchron 401</returns>
/// <remarks>
/// Sample request:
///
/// GET /api/auth
///
/// </remarks>
/// <response code="200">Wenn es einen autorisierten Cookie gibt.</response>
/// <response code="401">Wenn kein Cookie vorhanden ist oder nicht autorisierte.</response>
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[Authorize]
[HttpGet]
public IActionResult IsAuthenticated() => Ok();
} }

View File

@@ -5,10 +5,14 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers
{ {
public static class ControllerExtensions public static class ControllerExtensions
{ {
public static int? GetId(this ClaimsPrincipal user) public static int? GetIdOrDefault(this ClaimsPrincipal user)
=> int.TryParse(user.FindFirst(ClaimTypes.NameIdentifier)?.Value, out int result) => int.TryParse(user.FindFirstValue(ClaimTypes.NameIdentifier) ?? user.FindFirstValue("sub"), out int result)
? result : null; ? result : null;
public static int GetId(this ClaimsPrincipal user)
=> user.GetIdOrDefault()
?? throw new InvalidOperationException("User ID claim is missing or invalid. This may indicate a misconfigured or forged JWT token.");
public static string? GetUsername(this ClaimsPrincipal user) public static string? GetUsername(this ClaimsPrincipal user)
=> user.FindFirst(ClaimTypes.Name)?.Value; => user.FindFirst(ClaimTypes.Name)?.Value;

View File

@@ -1,8 +1,11 @@
using DigitalData.Core.DTO; using DigitalData.Core.DTO;
using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.Contracts.Services;
using EnvelopeGenerator.Application.Envelopes.Commands;
using EnvelopeGenerator.Application.Envelopes.Queries.Read; using EnvelopeGenerator.Application.Envelopes.Queries.Read;
using MediatR;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace EnvelopeGenerator.GeneratorAPI.Controllers; namespace EnvelopeGenerator.GeneratorAPI.Controllers;
@@ -27,16 +30,19 @@ public class EnvelopeController : ControllerBase
{ {
private readonly ILogger<EnvelopeController> _logger; private readonly ILogger<EnvelopeController> _logger;
private readonly IEnvelopeService _envelopeService; private readonly IEnvelopeService _envelopeService;
private readonly IMediator _mediator;
/// <summary> /// <summary>
/// Erstellt eine neue Instanz des EnvelopeControllers. /// Erstellt eine neue Instanz des EnvelopeControllers.
/// </summary> /// </summary>
/// <param name="logger">Der Logger, der für das Protokollieren von Informationen verwendet wird.</param> /// <param name="logger">Der Logger, der für das Protokollieren von Informationen verwendet wird.</param>
/// <param name="envelopeService">Der Dienst, der für die Verarbeitung von Umschlägen zuständig ist.</param> /// <param name="envelopeService">Der Dienst, der für die Verarbeitung von Umschlägen zuständig ist.</param>
public EnvelopeController(ILogger<EnvelopeController> logger, IEnvelopeService envelopeService) /// <param name="mediator"></param>
public EnvelopeController(ILogger<EnvelopeController> logger, IEnvelopeService envelopeService, IMediator mediator)
{ {
_logger = logger; _logger = logger;
_envelopeService = envelopeService; _envelopeService = envelopeService;
_mediator = mediator;
} }
/// <summary> /// <summary>
@@ -75,4 +81,33 @@ public class EnvelopeController : ControllerBase
return StatusCode(StatusCodes.Status500InternalServerError); return StatusCode(StatusCodes.Status500InternalServerError);
} }
} }
/// <summary>
///
/// </summary>
/// <param name="envelope"></param>
/// <returns></returns>
[Authorize]
[HttpPost]
public async Task<IActionResult> CreateAsync([FromQuery] CreateEnvelopeCommand envelope)
{
try
{
envelope.UserId = User.GetId();
var res = await _mediator.Send(envelope);
if (res is null)
{
_logger.LogError("Failed to create envelope. Envelope details: {EnvelopeDetails}", JsonConvert.SerializeObject(envelope));
return StatusCode(StatusCodes.Status500InternalServerError);
}
else
return Ok(res);
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
} }

View File

@@ -19,12 +19,13 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNetCore.Scalar" Version="1.1.8" /> <PackageReference Include="AspNetCore.Scalar" Version="1.1.8" />
<PackageReference Include="DigitalData.Auth.Client" Version="1.3.7" />
<PackageReference Include="DigitalData.Core.API" Version="2.1.1" /> <PackageReference Include="DigitalData.Core.API" Version="2.1.1" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.3" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.4" />
<PackageReference Include="Scalar.AspNetCore" Version="2.1.4" /> <PackageReference Include="Scalar.AspNetCore" Version="2.2.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" /> <PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" />
<PackageReference Include="DigitalData.Core.Application" Version="3.2.1" /> <PackageReference Include="DigitalData.Core.Application" Version="3.2.1" />
<PackageReference Include="DigitalData.Core.DTO" Version="2.0.1" /> <PackageReference Include="DigitalData.Core.DTO" Version="2.0.1" />
<PackageReference Include="DigitalData.EmailProfilerDispatcher.Abstraction" Version="3.0.0" /> <PackageReference Include="DigitalData.EmailProfilerDispatcher.Abstraction" Version="3.0.0" />

View File

@@ -0,0 +1,10 @@
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'dotnet build'
}
}
}
}

View File

@@ -0,0 +1,28 @@
namespace EnvelopeGenerator.GeneratorAPI.Models;
/// <summary>
/// Represents the keys and default values used for authentication token handling
/// within the Envelope Generator API.
/// </summary>
public class AuthTokenKeys
{
/// <summary>
/// Gets the name of the cookie used to store the authentication token.
/// </summary>
public string Cookie { get; init; } = "AuthToken";
/// <summary>
/// Gets the name of the query string parameter used to pass the authentication token.
/// </summary>
public string QueryString { get; init; } = "AuthToken";
/// <summary>
/// Gets the expected issuer value for the authentication token.
/// </summary>
public string Issuer { get; init; } = "auth.digitaldata.works";
/// <summary>
/// Gets the expected audience value for the authentication token.
/// </summary>
public string Audience { get; init; } = "sign-flow-gen.digitaldata.works";
}

View File

@@ -6,8 +6,8 @@ namespace EnvelopeGenerator.GeneratorAPI.Models;
/// Repräsentiert ein Login-Modell mit erforderlichem Passwort und optionaler ID und Benutzername. /// Repräsentiert ein Login-Modell mit erforderlichem Passwort und optionaler ID und Benutzername.
/// </summary> /// </summary>
/// <param name="Password">Das erforderliche Passwort für das Login.</param> /// <param name="Password">Das erforderliche Passwort für das Login.</param>
/// <param name="Id">Die optionale ID des Benutzers.</param> /// <param name="UserId">Die optionale ID des Benutzers.</param>
/// <param name="Username">Der optionale Benutzername.</param> /// <param name="Username">Der optionale Benutzername.</param>
public record Login([Required] string Password, int? Id = null, string? Username = null) public record Login([Required] string Password, int? UserId = null, string? Username = null)
{ {
} }

View File

@@ -1,6 +1,5 @@
using DigitalData.Core.API; using DigitalData.Core.API;
using DigitalData.Core.Application; using DigitalData.Core.Application;
using DigitalData.UserManager.Application;
using EnvelopeGenerator.Infrastructure; using EnvelopeGenerator.Infrastructure;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Localization;
@@ -10,11 +9,19 @@ using Scalar.AspNetCore;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using DigitalData.UserManager.DependencyInjection; using DigitalData.UserManager.DependencyInjection;
using EnvelopeGenerator.Application; using EnvelopeGenerator.Application;
using DigitalData.Auth.Client;
using DigitalData.Core.Abstractions;
using EnvelopeGenerator.GeneratorAPI.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using DigitalData.Core.Abstractions.Security.Extensions;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
var config = builder.Configuration; var config = builder.Configuration;
var deferredProvider = new DeferredServiceProvider();
builder.Services.AddControllers(); builder.Services.AddControllers();
//CORS Policy //CORS Policy
@@ -85,6 +92,49 @@ builder.Services.AddOpenApi();
var connStr = config.GetConnectionString("Default") ?? throw new InvalidOperationException("There is no default connection string in appsettings.json."); var connStr = config.GetConnectionString("Default") ?? throw new InvalidOperationException("There is no default connection string in appsettings.json.");
builder.Services.AddDbContext<EGDbContext>(options => options.UseSqlServer(connStr)); builder.Services.AddDbContext<EGDbContext>(options => options.UseSqlServer(connStr));
builder.Services.AddAuthHubClient(config.GetSection("AuthClientParams"));
var authTokenKeys = config.GetOrDefault<AuthTokenKeys>();
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(opt =>
{
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) =>
{
var clientParams = deferredProvider.GetOptions<ClientParams>();
var publicKey = clientParams!.PublicKeys.Get(authTokenKeys.Issuer, authTokenKeys.Audience);
return new List<SecurityKey>() { publicKey.SecurityKey };
},
ValidateIssuer = true,
ValidIssuer = authTokenKeys.Issuer,
ValidateAudience = true,
ValidAudience = authTokenKeys.Audience,
};
opt.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
// if there is no token read related cookie or query string
if (context.Token is null) // if there is no token
{
if (context.Request.Cookies.TryGetValue(authTokenKeys.Cookie, out var cookieToken) && cookieToken is not null)
context.Token = cookieToken;
else if (context.Request.Query.TryGetValue(authTokenKeys.QueryString, out var queryStrToken))
context.Token = queryStrToken;
}
return Task.CompletedTask;
}
};
});
// Authentication // Authentication
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options => .AddCookie(options =>
@@ -114,6 +164,8 @@ builder.Services
var app = builder.Build(); var app = builder.Build();
deferredProvider.Factory = () => app.Services;
app.MapOpenApi(); app.MapOpenApi();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.

View File

@@ -22,7 +22,7 @@
"https": { "https": {
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": true, "dotnetRunMessages": true,
"launchBrowser": true, "launchBrowser": false,
"launchUrl": "swagger", "launchUrl": "swagger",
"applicationUrl": "https://localhost:7174;http://localhost:5131", "applicationUrl": "https://localhost:7174;http://localhost:5131",
"environmentVariables": { "environmentVariables": {

View File

@@ -4,5 +4,15 @@
"Default": "Information", "Default": "Information",
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
},
"AuthClientParams": {
"Url": "https://localhost:7192/auth-hub",
"PublicKeys": [
{
"Issuer": "auth.digitaldata.works",
"Audience": "sign-flow-gen.digitaldata.works"
}
],
"RetryDelay": "00:00:05"
} }
} }

View File

@@ -20,5 +20,21 @@
"User": "(&(objectClass=user)(sAMAccountName=*))", "User": "(&(objectClass=user)(sAMAccountName=*))",
"Group": "(&(objectClass=group)(samAccountName=*))" "Group": "(&(objectClass=group)(samAccountName=*))"
} }
},
"AuthClientParams": {
"Url": "https://localhost:7192/auth-hub",
"PublicKeys": [
{
"Issuer": "auth.digitaldata.works",
"Audience": "sign-flow-gen.digitaldata.works"
}
],
"RetryDelay": "00:00:05"
},
"AuthTokenKeys": {
"Cookie": "AuthToken",
"QueryString": "AuthToken",
"Issuer": "auth.digitaldata.works",
"Audience": "work-flow.digitaldata.works"
} }
} }

View File

@@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore;
using DigitalData.Core.Infrastructure; using DigitalData.Core.Infrastructure;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using DigitalData.Core.Infrastructure.AutoMapper; using DigitalData.Core.Infrastructure.AutoMapper;
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
namespace EnvelopeGenerator.Infrastructure; namespace EnvelopeGenerator.Infrastructure;
@@ -59,6 +60,42 @@ public static class DIExtensions
services.AddDbRepository<EGDbContext, UserReceiver>(context => context.UserReceivers).UseAutoMapper(); services.AddDbRepository<EGDbContext, UserReceiver>(context => context.UserReceivers).UseAutoMapper();
services.AddDbRepository<EGDbContext, EnvelopeReceiverReadOnly>(context => context.EnvelopeReceiverReadOnlys).UseAutoMapper(); services.AddDbRepository<EGDbContext, EnvelopeReceiverReadOnly>(context => context.EnvelopeReceiverReadOnlys).UseAutoMapper();
services.AddSQLExecutor<Envelope>();
services.AddSQLExecutor<Receiver>();
services.AddSQLExecutor<EnvelopeDocument>();
services.AddSQLExecutor<DocumentReceiverElement>();
services.AddSQLExecutor<DocumentStatus>();
return services;
}
public static IServiceCollection AddSQLExecutor<T>(this IServiceCollection services) where T : class
{
services.AddScoped<ISQLExecutor<T>, SQLExecutor<T>>();
var interfaceType = typeof(ISQL<>);
var targetGenericType = interfaceType.MakeGenericType(typeof(T));
var implementations = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a =>
{
try { return a.GetTypes(); }
catch { return Array.Empty<Type>(); }
})
.Where(t =>
t is { IsClass: true, IsAbstract: false } &&
t.GetInterfaces().Any(i =>
i.IsGenericType &&
i.GetGenericTypeDefinition() == interfaceType &&
i.GenericTypeArguments[0] == typeof(T)
)
);
foreach (var impl in implementations)
{
services.AddSingleton(impl);
}
return services; return services;
} }
} }

View File

@@ -7,7 +7,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" /> <PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" />
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.0.4" /> <PackageReference Include="DigitalData.Core.Infrastructure" Version="2.0.4" />
<PackageReference Include="DigitalData.Core.Infrastructure.AutoMapper" Version="1.0.2" /> <PackageReference Include="DigitalData.Core.Infrastructure.AutoMapper" Version="1.0.2" />
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.0.0" /> <PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.0.0" />

View File

@@ -0,0 +1,42 @@
using AngleSharp.Dom;
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
using Microsoft.EntityFrameworkCore;
namespace EnvelopeGenerator.Infrastructure;
public sealed record Query<TEntity> : IQuery<TEntity>
{
private readonly IQueryable<TEntity> _query;
internal Query(IQueryable<TEntity> queryable)
{
_query = queryable;
}
public TEntity First() => _query.First();
public Task<TEntity> FirstAsync() => _query.FirstAsync();
public TEntity? FirstOrDefault() => _query.FirstOrDefault();
public Task<TEntity?> FirstOrDefaultAsync() => _query.FirstOrDefaultAsync();
public TEntity Single() => _query.Single();
public Task<TEntity> SingleAsync() => _query.SingleAsync();
public TEntity? SingleOrDefault() => _query.SingleOrDefault();
public Task<TEntity?> SingleOrDefaultAsync() => _query.SingleOrDefaultAsync();
public IEnumerable<TEntity> ToList() => _query.ToList();
public async Task<IEnumerable<TEntity>> ToListAsync() => await _query.ToListAsync();
}

View File

@@ -0,0 +1,9 @@
namespace EnvelopeGenerator.Infrastructure;
public static class QueryExtension
{
public static Query<TEntity> ToQuery<TEntity>(this IQueryable<TEntity> queryable) where TEntity : class
{
return new Query<TEntity>(queryable);
}
}

View File

@@ -0,0 +1,31 @@
using Dapper;
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.DependencyInjection;
namespace EnvelopeGenerator.Infrastructure;
public class SQLExecutor : ISQLExecutor
{
private readonly string _cnnStr = "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;";
private readonly IServiceProvider _provider;
public SQLExecutor(IServiceProvider provider)
{
_provider = provider;
}
public async Task<IEnumerable<TEntity>> Execute<TEntity>(string sql, DynamicParameters parameters, CancellationToken cancellation = default)
{
using var connection = new SqlConnection(_cnnStr);
await connection.OpenAsync(cancellation);
return await connection.QueryAsync<TEntity>(sql, parameters);
}
public Task<IEnumerable<TEntity>> Execute<TEntity, TSQL>(DynamicParameters parameters, CancellationToken cancellation = default) where TSQL : ISQL
{
var sql = _provider.GetRequiredService<TSQL>();
return Execute<TEntity>(sql.Raw, parameters, cancellation);
}
}

View File

@@ -0,0 +1,30 @@
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace EnvelopeGenerator.Infrastructure;
public sealed class SQLExecutor<T> : SQLExecutor, ISQLExecutor<T> where T : class
{
private readonly EGDbContext _context;
private readonly IServiceProvider _provider;
public SQLExecutor(EGDbContext context, IServiceProvider provider) : base(provider)
{
_context = context;
_provider = provider;
}
public IQuery<T> Execute(string sql, CancellationToken cancellation = default, params object[] parameters)
=> _context
.Set<T>()
.FromSqlRaw(sql, parameters)
.ToQuery();
public IQuery<T> Execute<TSQL>(CancellationToken cancellation = default, params object[] parameters) where TSQL : ISQL<T>
{
var sql = _provider.GetRequiredService<TSQL>();
return Execute(sql.Raw);
}
}

View File

@@ -1,16 +1,13 @@
Imports DigitalData.Modules.Config.ConfigAttributes Imports DigitalData.Modules.Config.ConfigAttributes
Imports EnvelopeGenerator.Common.Jobs.FinalizeDocument
Public Class Config Public Class Config
<ConnectionString> <ConnectionString>
Public Property ConnectionString As String = "" Public Property ConnectionString As String = ""
Public Property Debug As Boolean = False Public Property Debug As Boolean = False
Public Property IntervalInMin As Integer = 1 Public Property IntervalInMin As Integer = 1
Public Property IgnoredLabels As List(Of String) = New List(Of String) From { Public Property PDFBurnerParams As PDFBurnerParams = New PDFBurnerParams()
"Date", "Datum",
"ZIP", "PLZ",
"Place", "Ort",
"Position", "Stellung"
}
End Class End Class

View File

@@ -3,6 +3,7 @@ Imports DigitalData.Modules.Base
Imports DigitalData.Modules.Database Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Logging
Imports EnvelopeGenerator.Common.Jobs Imports EnvelopeGenerator.Common.Jobs
Imports EnvelopeGenerator.Common.Jobs.FinalizeDocument
Imports Quartz Imports Quartz
Public Class Scheduler Public Class Scheduler
@@ -11,15 +12,15 @@ Public Class Scheduler
Private Scheduler As IScheduler Private Scheduler As IScheduler
Private ReadOnly ConnectionString As String Private ReadOnly ConnectionString As String
Private ReadOnly LicenseKey As String Private ReadOnly LicenseKey As String
Private Property _ignoredLabels As List(Of String) Private Property _pdfBurnerParams As PDFBurnerParams
Private Const JobName = "CertificateDocumentJob" Private Const JobName = "CertificateDocumentJob"
Public Sub New(pLogConfig As LogConfig, pConnectionString As String, pLicenseKey As String, ignoredLabels As List(Of String)) Public Sub New(pLogConfig As LogConfig, pConnectionString As String, pLicenseKey As String, pdfBurnerParams As PDFBurnerParams)
MyBase.New(pLogConfig) MyBase.New(pLogConfig)
ConnectionString = pConnectionString ConnectionString = pConnectionString
LicenseKey = pLicenseKey LicenseKey = pLicenseKey
_ignoredLabels = ignoredLabels _pdfBurnerParams = pdfBurnerParams
Dim oLogProvider = New LogProvider(Logger) Dim oLogProvider = New LogProvider(Logger)
Logging.LogProvider.SetCurrentLogProvider(oLogProvider) Logging.LogProvider.SetCurrentLogProvider(oLogProvider)
@@ -40,7 +41,7 @@ Public Class Scheduler
{Common.Constants.GDPICTURE, LicenseKey}, {Common.Constants.GDPICTURE, LicenseKey},
{Common.Constants.LOGCONFIG, LogConfig}, {Common.Constants.LOGCONFIG, LogConfig},
{Common.Constants.DATABASE, ConnectionString}, {Common.Constants.DATABASE, ConnectionString},
{Common.Constants.IGNORED_LABELS, _ignoredLabels} {Common.Constants.PDF_BURNER_PARAMS, _pdfBurnerParams}
} }
Logger.Debug("Initialized Job [{0}]", JobName) Logger.Debug("Initialized Job [{0}]", JobName)

View File

@@ -55,7 +55,7 @@ Public Class Service
Logger.Debug("Inititalize Quartz") Logger.Debug("Inititalize Quartz")
Scheduler = New Scheduler(LogConfig, Config.ConnectionString, oKey, Config.IgnoredLabels) Scheduler = New Scheduler(LogConfig, Config.ConnectionString, oKey, Config.PDFBurnerParams)
Await Scheduler.Start(Config.IntervalInMin) Await Scheduler.Start(Config.IntervalInMin)
Logger.Info("Started [{0}] !", ServiceName) Logger.Info("Started [{0}] !", ServiceName)

View File

@@ -32,11 +32,27 @@ public class CommandManager
[Subcommand] [Subcommand]
public IEnvelopeReceiverService EnvelopeReceiver => _envelopeReceiverService; public IEnvelopeReceiverService EnvelopeReceiver => _envelopeReceiverService;
[Command] [Command(ArgumentSeparatorStrategy = ArgumentSeparatorStrategy.EndOfOptions)]
public async Task ReadDocument(IConsole console, int? id = null, int? envelopeId = null) public async Task ReadDocument(IConsole console,
[Option(Description = "ID of the document.")] int? id = null,
[Option(Description = "ID of the envelope containing the document.")] int? envelopeId = null,
[Option(Description = "Path to save the PDF")] bool save = false,
[Option(Description = "Directory to save the PDF")] string? dir = null,
[Option(Description = "Name of file to save the PDF")] string? fileName = null)
{ {
ReadDocumentQuery query = new(id, envelopeId); ReadDocumentQuery query = new(id, envelopeId);
var document = await _mediator.Send(query); var document = await _mediator.Send(query);
console.WriteLine(JsonSerializer.Serialize(document, Options)); console.WriteLine(JsonSerializer.Serialize(save ? document as ReadDocumentResponseBase : document, Options));
if (save)
{
dir ??= AppContext.BaseDirectory;
fileName ??= $"D{document?.Guid}E{document?.EnvelopeId}.pdf";
var path = Path.Combine(dir, fileName);
console.WriteLine("Save to " + path);
File.WriteAllBytes(path, document?.ByteData ?? Array.Empty<byte>());
}
} }
} }

View File

@@ -19,7 +19,7 @@
<PackageReference Include="CommandDotNet" Version="7.0.5" /> <PackageReference Include="CommandDotNet" Version="7.0.5" />
<PackageReference Include="CommandDotNet.IoC.MicrosoftDependencyInjection" Version="5.0.1" /> <PackageReference Include="CommandDotNet.IoC.MicrosoftDependencyInjection" Version="5.0.1" />
<PackageReference Include="CommandDotNet.NameCasing" Version="4.0.2" /> <PackageReference Include="CommandDotNet.NameCasing" Version="4.0.2" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" /> <PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" />
<PackageReference Include="DigitalData.Core.Application" Version="3.2.1" /> <PackageReference Include="DigitalData.Core.Application" Version="3.2.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.20" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.20" />
<PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="7.0.20" /> <PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="7.0.20" />

View File

@@ -1,4 +1,5 @@
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
namespace EnvelopeGenerator.Terminal; namespace EnvelopeGenerator.Terminal;
@@ -8,6 +9,10 @@ public class Program
{ {
var builder = Host.CreateApplicationBuilder(args); var builder = Host.CreateApplicationBuilder(args);
builder.Configuration
.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
var config = builder.Configuration; var config = builder.Configuration;
builder.Services.AddCommandManagerRunner(config); builder.Services.AddCommandManagerRunner(config);

View File

@@ -23,7 +23,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" /> <PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" /> <PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" />
<PackageReference Include="DigitalData.Core.API" Version="2.1.1" /> <PackageReference Include="DigitalData.Core.API" Version="2.1.1" />
<PackageReference Include="DigitalData.Core.Application" Version="3.2.1" /> <PackageReference Include="DigitalData.Core.Application" Version="3.2.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.20" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.20" />

View File

@@ -5,7 +5,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<PackageId>EnvelopeGenerator.Web</PackageId> <PackageId>EnvelopeGenerator.Web</PackageId>
<Version>3.1.1</Version> <Version>3.1.2</Version>
<Authors>Digital Data GmbH</Authors> <Authors>Digital Data GmbH</Authors>
<Company>Digital Data GmbH</Company> <Company>Digital Data GmbH</Company>
<Product>EnvelopeGenerator.Web</Product> <Product>EnvelopeGenerator.Web</Product>
@@ -13,8 +13,8 @@
<PackageTags>digital data envelope generator web</PackageTags> <PackageTags>digital data envelope generator web</PackageTags>
<Description>EnvelopeGenerator.Web is an ASP.NET MVC application developed to manage signing processes. It uses Entity Framework Core (EF Core) for database operations. The user interface for signing processes is developed with Razor View Engine (.cshtml files) and JavaScript under wwwroot, integrated with PSPDFKit. This integration allows users to view and sign documents seamlessly.</Description> <Description>EnvelopeGenerator.Web is an ASP.NET MVC application developed to manage signing processes. It uses Entity Framework Core (EF Core) for database operations. The user interface for signing processes is developed with Razor View Engine (.cshtml files) and JavaScript under wwwroot, integrated with PSPDFKit. This integration allows users to view and sign documents seamlessly.</Description>
<ApplicationIcon>Assets\icon.ico</ApplicationIcon> <ApplicationIcon>Assets\icon.ico</ApplicationIcon>
<AssemblyVersion>3.1.1</AssemblyVersion> <AssemblyVersion>3.1.2</AssemblyVersion>
<FileVersion>3.1.1</FileVersion> <FileVersion>3.1.2</FileVersion>
<Copyright>Copyright © 2025 Digital Data GmbH. All rights reserved.</Copyright> <Copyright>Copyright © 2025 Digital Data GmbH. All rights reserved.</Copyright>
</PropertyGroup> </PropertyGroup>
@@ -2101,7 +2101,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" /> <PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="BuildBundlerMinifier2022" Version="2.9.9" /> <PackageReference Include="BuildBundlerMinifier2022" Version="2.9.9" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" /> <PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" />
<PackageReference Include="DigitalData.Core.API" Version="2.1.1" /> <PackageReference Include="DigitalData.Core.API" Version="2.1.1" />
<PackageReference Include="DigitalData.Core.Application" Version="3.2.1" /> <PackageReference Include="DigitalData.Core.Application" Version="3.2.1" />
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.0.0" /> <PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.0.0" />