Excel export
This commit is contained in:
@@ -61,4 +61,6 @@ public class ApplicantModel
|
|||||||
/// <inheritdoc cref="Applicant.IsNonResident" />
|
/// <inheritdoc cref="Applicant.IsNonResident" />
|
||||||
[Required]
|
[Required]
|
||||||
public bool IsNonResident { get; set; }
|
public bool IsNonResident { get; set; }
|
||||||
|
|
||||||
|
public override string ToString() => Name.ToString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,4 +16,6 @@ public class NameModel
|
|||||||
|
|
||||||
[MaxLength(ConfigurationConstraints.NameLength)]
|
[MaxLength(ConfigurationConstraints.NameLength)]
|
||||||
public string? Patronymic { get; set; }
|
public string? Patronymic { get; set; }
|
||||||
|
|
||||||
|
public override string ToString() => $"{FirstName} {Surname} {Patronymic}".TrimEnd();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,5 +23,9 @@ public interface IVisaApplicationRequestsHandler
|
|||||||
/// Sets application status to closed
|
/// Sets application status to closed
|
||||||
Task HandleCloseRequestAsync(Guid applicationId, CancellationToken cancellationToken);
|
Task HandleCloseRequestAsync(Guid applicationId, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// Sets application status to approved or rejected
|
||||||
Task SetApplicationStatusFromAuthorityAsync(Guid applicationId, AuthorityRequestStatuses status, CancellationToken cancellationToken);
|
Task SetApplicationStatusFromAuthorityAsync(Guid applicationId, AuthorityRequestStatuses status, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// Returns stream with file with formatted application data to download
|
||||||
|
Task<Stream> ApplicationToStreamAsync(Guid applicationId, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ public class VisaApplicationRequestsHandler(
|
|||||||
IUnitOfWork unitOfWork,
|
IUnitOfWork unitOfWork,
|
||||||
IMapper mapper,
|
IMapper mapper,
|
||||||
IDateTimeProvider dateTimeProvider,
|
IDateTimeProvider dateTimeProvider,
|
||||||
IUserIdProvider userIdProvider) : IVisaApplicationRequestsHandler
|
IUserIdProvider userIdProvider,
|
||||||
|
IEntityWriter entityWriter) : IVisaApplicationRequestsHandler
|
||||||
{
|
{
|
||||||
async Task<List<VisaApplicationPreview>> IVisaApplicationRequestsHandler.GetPendingAsync(CancellationToken cancellationToken)
|
async Task<List<VisaApplicationPreview>> IVisaApplicationRequestsHandler.GetPendingAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
@@ -34,7 +35,8 @@ public class VisaApplicationRequestsHandler(
|
|||||||
return mapper.Map<List<VisaApplicationPreview>>(visaApplications);
|
return mapper.Map<List<VisaApplicationPreview>>(visaApplications);
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task<VisaApplicationModel> IVisaApplicationRequestsHandler.GetApplicationForApplicantAsync(Guid id, CancellationToken cancellationToken)
|
/// <summary> <inheritdoc cref="IVisaApplicationRequestsHandler.GetApplicationForApplicantAsync"/> </summary>
|
||||||
|
public async Task<VisaApplicationModel> GetApplicationForApplicantAsync(Guid id, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var applicant = await applicants.FindByUserIdAsync(userIdProvider.GetUserId(), cancellationToken);
|
var applicant = await applicants.FindByUserIdAsync(userIdProvider.GetUserId(), cancellationToken);
|
||||||
var application = await applications.GetByApplicantAndApplicationIdAsync(applicant.Id, id, cancellationToken);
|
var application = await applications.GetByApplicantAndApplicationIdAsync(applicant.Id, id, cancellationToken);
|
||||||
@@ -104,4 +106,10 @@ public class VisaApplicationRequestsHandler(
|
|||||||
|
|
||||||
await unitOfWork.SaveAsync(cancellationToken);
|
await unitOfWork.SaveAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async Task<Stream> IVisaApplicationRequestsHandler.ApplicationToStreamAsync(Guid applicationId, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var application = await GetApplicationForApplicantAsync(applicationId, cancellationToken);
|
||||||
|
return await entityWriter.WriteEntityToStream(application, cancellationToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text;
|
||||||
using ApplicationLayer.Services.Applicants.Models;
|
using ApplicationLayer.Services.Applicants.Models;
|
||||||
using Domains.VisaApplicationDomain;
|
using Domains.VisaApplicationDomain;
|
||||||
|
|
||||||
@@ -33,8 +34,7 @@ public class VisaApplicationModel
|
|||||||
/// <inheritdoc cref="VisaApplication.PermissionToDestCountry" />
|
/// <inheritdoc cref="VisaApplication.PermissionToDestCountry" />
|
||||||
public PermissionToDestCountryModel? PermissionToDestCountry { get; set; }
|
public PermissionToDestCountryModel? PermissionToDestCountry { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required] public List<PastVisitModel> PastVisits { get; set; } = null!;
|
||||||
public List<PastVisitModel> PastVisits { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.VisaCategory" />
|
/// <inheritdoc cref="VisaApplication.VisaCategory" />
|
||||||
[Required]
|
[Required]
|
||||||
@@ -55,4 +55,35 @@ public class VisaApplicationModel
|
|||||||
/// <inheritdoc cref="VisaApplication.ValidDaysRequested" />
|
/// <inheritdoc cref="VisaApplication.ValidDaysRequested" />
|
||||||
[Required]
|
[Required]
|
||||||
public int ValidDaysRequested { get; set; }
|
public int ValidDaysRequested { get; set; }
|
||||||
|
|
||||||
|
public string ForGroupToString() => ForGroup ? "For group" : "Individual";
|
||||||
|
|
||||||
|
public string PastVisasToString()
|
||||||
|
{
|
||||||
|
var stringBuilder = new StringBuilder();
|
||||||
|
foreach (var visa in PastVisas)
|
||||||
|
{
|
||||||
|
stringBuilder.AppendLine($"{visa.Name} issued at {visa.IssueDate.ToShortDateString()} and valid for {visa.ExpirationDate.ToShortDateString()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringBuilder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string PastVisitsToString()
|
||||||
|
{
|
||||||
|
var stringBuilder = new StringBuilder();
|
||||||
|
foreach (var visit in PastVisits)
|
||||||
|
{
|
||||||
|
stringBuilder.AppendLine($"Visit to {visit.DestinationCountry} started at {visit.StartDate.ToShortDateString()} and ends {visit.EndDate.ToShortDateString()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringBuilder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string PermissionToDestCountryToString()
|
||||||
|
{
|
||||||
|
return VisaCategory is VisaCategory.Transit
|
||||||
|
? $"Issued by{PermissionToDestCountry!.Issuer}, expires at {PermissionToDestCountry.ExpirationDate.ToShortDateString()}"
|
||||||
|
: "Non-transit";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace ApplicationLayer.Services.VisaApplications.NeededServices
|
||||||
|
{
|
||||||
|
public interface IEntityWriter
|
||||||
|
{
|
||||||
|
Task<Stream> WriteEntityToStream(object entity, CancellationToken cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td colspan="3">
|
<td colspan="3">
|
||||||
Country and city of birth:<br/>
|
Country and city of birth:<br/>
|
||||||
<em>@application.Applicant.Passport.Number</em>
|
<em>@application.Applicant.CountryOfBirth, @application.Applicant.CityOfBirth</em>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
Citizenship:<br/>
|
Citizenship:<br/>
|
||||||
<em>@application.Applicant.Citizenship</em>
|
<em>@application.Applicant.Citizenship</em>
|
||||||
</td>
|
</td>
|
||||||
<td >
|
<td>
|
||||||
Citizenship by birth:<br/>
|
Citizenship by birth:<br/>
|
||||||
<em>@application.Applicant.CitizenshipByBirth</em>
|
<em>@application.Applicant.CitizenshipByBirth</em>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -40,12 +40,17 @@
|
|||||||
<td>@application.Status.GetDisplayName()</td>
|
<td>@application.Status.GetDisplayName()</td>
|
||||||
<td>
|
<td>
|
||||||
<NavLink href="@($"/applications/{application.Id}")">
|
<NavLink href="@($"/applications/{application.Id}")">
|
||||||
<button class="btn-outline-primary">See</button>
|
<button class="btn-primary">See</button>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
@if (currentRole == Constants.ApplicantRole && application.Status is ApplicationStatus.Pending)
|
@if (currentRole == Constants.ApplicantRole)
|
||||||
{
|
{
|
||||||
<span> | </span>
|
<span> | </span>
|
||||||
<input type="button" class="border-danger" @onclick="() => CloseApplication(application)" value="Close"/>
|
<input type="button" class="btn-outline-primary" @onclick="() => DownloadApplication(application)" value="Download"/>
|
||||||
|
if (application.Status is ApplicationStatus.Pending)
|
||||||
|
{
|
||||||
|
<span> | </span>
|
||||||
|
<input type="button" class="border-danger" @onclick="() => CloseApplication(application)" value="Close"/>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -53,12 +58,28 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table >
|
</table >
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.downloadFileFromStream = async (contentStreamReference) => {
|
||||||
|
const arrayBuffer = await contentStreamReference.arrayBuffer();
|
||||||
|
const blob = new Blob([arrayBuffer]);
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const anchorElement = document.createElement('a');
|
||||||
|
anchorElement.href = url;
|
||||||
|
anchorElement.download = 'Application.xlsx';
|
||||||
|
anchorElement.click();
|
||||||
|
anchorElement.remove();
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string currentRole = null!;
|
private string currentRole = null!;
|
||||||
private List<VisaApplicationPreview> applications = [];
|
private List<VisaApplicationPreview> applications = [];
|
||||||
|
|
||||||
[Inject] private IUserDataProvider UserDataProvider { get; set; } = null!;
|
[Inject] private IUserDataProvider UserDataProvider { get; set; } = null!;
|
||||||
|
|
||||||
|
[Inject] private IJSRuntime JavaScriptInterop { get; set; } = null!;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -69,6 +90,7 @@
|
|||||||
{
|
{
|
||||||
ErrorHandler.Handle(e);
|
ErrorHandler.Handle(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
await Fetch();
|
await Fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,4 +125,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task DownloadApplication(VisaApplicationPreview application)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var response = await Client.DownloadApplicationForApplicantAsync(application.Id);
|
||||||
|
using var streamRef = new DotNetStreamReference(stream: response.Stream);
|
||||||
|
|
||||||
|
await JavaScriptInterop.InvokeVoidAsync("downloadFileFromStream", streamRef);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
ErrorHandler.Handle(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Infrastructure.Database.Applicants.Repositories;
|
|||||||
using Infrastructure.Database.Generic;
|
using Infrastructure.Database.Generic;
|
||||||
using Infrastructure.Database.Users.Repositories;
|
using Infrastructure.Database.Users.Repositories;
|
||||||
using Infrastructure.Database.VisaApplications.Repositories;
|
using Infrastructure.Database.VisaApplications.Repositories;
|
||||||
|
using Infrastructure.EntityToExcelTemplateWriter;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@@ -37,6 +38,7 @@ public static class DependencyInjection
|
|||||||
services.AddScoped<IUsersRepository, UsersRepository>();
|
services.AddScoped<IUsersRepository, UsersRepository>();
|
||||||
|
|
||||||
services.AddSingleton<IDateTimeProvider, DateTimeProvider>();
|
services.AddSingleton<IDateTimeProvider, DateTimeProvider>();
|
||||||
|
services.AddSingleton<IEntityWriter, ExcelWriter>();
|
||||||
|
|
||||||
services.AddHttpContextAccessor();
|
services.AddHttpContextAccessor();
|
||||||
services.AddScoped<IUserIdProvider, UserIdProvider>();
|
services.AddScoped<IUserIdProvider, UserIdProvider>();
|
||||||
|
|||||||
@@ -0,0 +1,131 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using ApplicationLayer.Services.VisaApplications.NeededServices;
|
||||||
|
using DocumentFormat.OpenXml.Packaging;
|
||||||
|
using DocumentFormat.OpenXml.Spreadsheet;
|
||||||
|
using Microsoft.Extensions.Primitives;
|
||||||
|
|
||||||
|
namespace Infrastructure.EntityToExcelTemplateWriter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Writes object to excel using template.xlsx file and reflections
|
||||||
|
/// </summary>
|
||||||
|
public class ExcelWriter : IEntityWriter
|
||||||
|
{
|
||||||
|
private const char InsertionSymbol = '$';
|
||||||
|
private readonly char[] endChars = [',', ';'];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write object to stream in Excel table format
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity"> object to write </param>
|
||||||
|
/// <param name="cancellationToken"> cancellation token </param>
|
||||||
|
/// <returns> Stream with template.xlsx file with replaced entries like '$EntityPropName.AnotherProp' </returns>
|
||||||
|
/// <exception cref="NullReferenceException"> thrown when template file is incorrect </exception>
|
||||||
|
/// <exception cref="InvalidOperationException"> thrown if any property path in template is incorrect</exception>
|
||||||
|
public async Task<Stream> WriteEntityToStream(object entity, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var outStream = new MemoryStream();
|
||||||
|
await using (var stream = File.Open("template.xlsx", FileMode.Open, FileAccess.Read))
|
||||||
|
{
|
||||||
|
await stream.CopyToAsync(outStream, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
using var spreadsheetDocument = SpreadsheetDocument.Open(outStream, true);
|
||||||
|
|
||||||
|
var workbookPart = spreadsheetDocument.WorkbookPart
|
||||||
|
?? throw new NullReferenceException("There is no workbook part in document");
|
||||||
|
var shareStringTable = workbookPart.SharedStringTablePart?.SharedStringTable ??
|
||||||
|
throw new NullReferenceException("There is no data in document");
|
||||||
|
var shareStringTableItems = shareStringTable.Elements<SharedStringItem>().ToArray();
|
||||||
|
|
||||||
|
foreach (var item in shareStringTableItems)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(item.InnerText))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var entries = item.InnerText.Split();
|
||||||
|
for (var i = 0; i < entries.Length; i++)
|
||||||
|
{
|
||||||
|
var entry = entries[i];
|
||||||
|
if (entry.FirstOrDefault() is not InsertionSymbol || entry.Length <= 1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = entry[1..];
|
||||||
|
var trimmedCount = entry.Length - entry.TrimEnd(endChars).Length;
|
||||||
|
var trimmed = entry[^trimmedCount..];
|
||||||
|
entry = entry.TrimEnd(endChars);
|
||||||
|
|
||||||
|
var memberPath = entry.Split('.');
|
||||||
|
|
||||||
|
var value = GetValueFor(entity, memberPath.First());
|
||||||
|
var stringToInsert = "None";
|
||||||
|
foreach (var memberName in memberPath.Skip(1))
|
||||||
|
{
|
||||||
|
if (value is null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = GetValueFor(value, memberName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value is not null)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case DateTime date:
|
||||||
|
stringToInsert = date.ToShortDateString();
|
||||||
|
break;
|
||||||
|
case Enum val:
|
||||||
|
var enumString = val.ToString();
|
||||||
|
var stringBuilder = new StringBuilder();
|
||||||
|
for (var charIndex = 0; charIndex < enumString.Length - 1; charIndex++)
|
||||||
|
{
|
||||||
|
stringBuilder.Append(enumString[charIndex]);
|
||||||
|
if (char.IsUpper(enumString[charIndex + 1]))
|
||||||
|
{
|
||||||
|
stringBuilder.Append(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stringBuilder.Append(enumString.Last());
|
||||||
|
|
||||||
|
stringToInsert = stringBuilder.ToString();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
stringToInsert = value.ToString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entries[i] = stringToInsert! + trimmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.Text!.Text = string.Join(' ', entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
spreadsheetDocument.Save();
|
||||||
|
return outStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object? GetValueFor(object entity, string member)
|
||||||
|
{
|
||||||
|
var memberInfo = entity.GetType()
|
||||||
|
.GetMembers()
|
||||||
|
.FirstOrDefault(p => p.Name == member)
|
||||||
|
?? throw new InvalidOperationException(
|
||||||
|
$"Invalid member path in document. Not found: {member}");
|
||||||
|
return memberInfo switch
|
||||||
|
{
|
||||||
|
PropertyInfo propertyInfo => propertyInfo.GetValue(entity),
|
||||||
|
MethodInfo methodInfo => methodInfo.Invoke(entity, []),
|
||||||
|
_ => throw new InvalidOperationException("Only properties and methods allowed.")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="DocumentFormat.OpenXml" Version="3.1.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0-preview.7.24405.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0-preview.7.24405.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.0-preview.7.24405.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.0-preview.7.24405.3" />
|
||||||
|
|||||||
@@ -119,4 +119,20 @@ public class VisaApplicationController(
|
|||||||
await visaApplicationRequestsHandler.SetApplicationStatusFromAuthorityAsync(applicationId, status, cancellationToken);
|
await visaApplicationRequestsHandler.SetApplicationStatusFromAuthorityAsync(applicationId, status, cancellationToken);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Returns application </summary>
|
||||||
|
/// <remarks> Accessible only for applicant </remarks>
|
||||||
|
[HttpGet("/forApplicant/{applicationId:guid}/download")]
|
||||||
|
[Produces("application/octet-stream")]
|
||||||
|
[ProducesResponseType<object>(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
[Authorize(policy: PolicyConstants.ApplicantPolicy)]
|
||||||
|
public async Task<IActionResult> DownloadApplicationForApplicant(Guid applicationId, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var result = await visaApplicationRequestsHandler.ApplicationToStreamAsync(applicationId, cancellationToken);
|
||||||
|
result.Position = 0;
|
||||||
|
return File(result, "application/octet-stream", "Application.xlsx");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ public class GlobalExceptionsFilter : IAsyncExceptionFilter
|
|||||||
problemDetails.Status = StatusCodes.Status500InternalServerError;
|
problemDetails.Status = StatusCodes.Status500InternalServerError;
|
||||||
problemDetails.Title = "An unhandled error occured";
|
problemDetails.Title = "An unhandled error occured";
|
||||||
problemDetails.Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.6.1";
|
problemDetails.Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.6.1";
|
||||||
|
|
||||||
|
Console.WriteLine($"Error!!!: {exception.Message}");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
SchengenVisaApi/SchengenVisaApi/template.xlsx
Normal file
BIN
SchengenVisaApi/SchengenVisaApi/template.xlsx
Normal file
Binary file not shown.
@@ -1722,6 +1722,129 @@ namespace VisaApiClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns application
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Accessible only for applicant
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>Success</returns>
|
||||||
|
/// <exception cref="ApiException">A server side error occurred.</exception>
|
||||||
|
public virtual System.Threading.Tasks.Task<FileResponse> DownloadApplicationForApplicantAsync(System.Guid applicationId)
|
||||||
|
{
|
||||||
|
return DownloadApplicationForApplicantAsync(applicationId, System.Threading.CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
|
||||||
|
/// <summary>
|
||||||
|
/// Returns application
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Accessible only for applicant
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>Success</returns>
|
||||||
|
/// <exception cref="ApiException">A server side error occurred.</exception>
|
||||||
|
public virtual async System.Threading.Tasks.Task<FileResponse> DownloadApplicationForApplicantAsync(System.Guid applicationId, System.Threading.CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (applicationId == null)
|
||||||
|
throw new System.ArgumentNullException("applicationId");
|
||||||
|
|
||||||
|
var client_ = _httpClient;
|
||||||
|
var disposeClient_ = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var request_ = await CreateHttpRequestMessageAsync(cancellationToken).ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
request_.Method = new System.Net.Http.HttpMethod("GET");
|
||||||
|
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/octet-stream"));
|
||||||
|
|
||||||
|
var urlBuilder_ = new System.Text.StringBuilder();
|
||||||
|
if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
|
||||||
|
// Operation Path: "forApplicant/{applicationId}/download"
|
||||||
|
urlBuilder_.Append("forApplicant/");
|
||||||
|
urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(applicationId, System.Globalization.CultureInfo.InvariantCulture)));
|
||||||
|
urlBuilder_.Append("/download");
|
||||||
|
|
||||||
|
await PrepareRequestAsync(client_, request_, urlBuilder_, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
var url_ = urlBuilder_.ToString();
|
||||||
|
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
|
||||||
|
|
||||||
|
await PrepareRequestAsync(client_, request_, url_, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
|
||||||
|
var disposeResponse_ = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var headers_ = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>();
|
||||||
|
foreach (var item_ in response_.Headers)
|
||||||
|
headers_[item_.Key] = item_.Value;
|
||||||
|
if (response_.Content != null && response_.Content.Headers != null)
|
||||||
|
{
|
||||||
|
foreach (var item_ in response_.Content.Headers)
|
||||||
|
headers_[item_.Key] = item_.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ProcessResponseAsync(client_, response_, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
var status_ = (int)response_.StatusCode;
|
||||||
|
if (status_ == 200 || status_ == 206)
|
||||||
|
{
|
||||||
|
var responseStream_ = response_.Content == null ? System.IO.Stream.Null : await response_.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||||
|
var fileResponse_ = new FileResponse(status_, headers_, responseStream_, null, response_);
|
||||||
|
disposeClient_ = false; disposeResponse_ = false; // response and client are disposed by FileResponse
|
||||||
|
return fileResponse_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (status_ == 401)
|
||||||
|
{
|
||||||
|
var objectResponse_ = await ReadObjectResponseAsync<ProblemDetails>(response_, headers_, cancellationToken).ConfigureAwait(false);
|
||||||
|
if (objectResponse_.Object == null)
|
||||||
|
{
|
||||||
|
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||||
|
}
|
||||||
|
throw new ApiException<ProblemDetails>("Unauthorized", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (status_ == 403)
|
||||||
|
{
|
||||||
|
var objectResponse_ = await ReadObjectResponseAsync<ProblemDetails>(response_, headers_, cancellationToken).ConfigureAwait(false);
|
||||||
|
if (objectResponse_.Object == null)
|
||||||
|
{
|
||||||
|
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||||
|
}
|
||||||
|
throw new ApiException<ProblemDetails>("Forbidden", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (status_ == 404)
|
||||||
|
{
|
||||||
|
var objectResponse_ = await ReadObjectResponseAsync<ProblemDetails>(response_, headers_, cancellationToken).ConfigureAwait(false);
|
||||||
|
if (objectResponse_.Object == null)
|
||||||
|
{
|
||||||
|
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||||
|
}
|
||||||
|
throw new ApiException<ProblemDetails>("Not Found", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
|
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (disposeResponse_)
|
||||||
|
response_.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (disposeClient_)
|
||||||
|
client_.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected struct ObjectResponseResult<T>
|
protected struct ObjectResponseResult<T>
|
||||||
{
|
{
|
||||||
public ObjectResponseResult(T responseObject, string responseText)
|
public ObjectResponseResult(T responseObject, string responseText)
|
||||||
@@ -2443,6 +2566,41 @@ namespace VisaApiClient
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCode("NSwag", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")]
|
||||||
|
public partial class FileResponse : System.IDisposable
|
||||||
|
{
|
||||||
|
private System.IDisposable? _client;
|
||||||
|
private System.IDisposable? _response;
|
||||||
|
|
||||||
|
public int StatusCode { get; private set; }
|
||||||
|
|
||||||
|
public System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> Headers { get; private set; }
|
||||||
|
|
||||||
|
public System.IO.Stream Stream { get; private set; }
|
||||||
|
|
||||||
|
public bool IsPartial
|
||||||
|
{
|
||||||
|
get { return StatusCode == 206; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileResponse(int statusCode, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, System.IO.Stream stream, System.IDisposable? client, System.IDisposable? response)
|
||||||
|
{
|
||||||
|
StatusCode = statusCode;
|
||||||
|
Headers = headers;
|
||||||
|
Stream = stream;
|
||||||
|
_client = client;
|
||||||
|
_response = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Stream.Dispose();
|
||||||
|
if (_response != null)
|
||||||
|
_response.Dispose();
|
||||||
|
if (_client != null)
|
||||||
|
_client.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[System.CodeDom.Compiler.GeneratedCode("NSwag", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")]
|
[System.CodeDom.Compiler.GeneratedCode("NSwag", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")]
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user