Skip to content

Commit

Permalink
implementação do processamento assíncrono de extratos com API REST, g…
Browse files Browse the repository at this point in the history
…eração de XML, persistência e documentação Swagger
  • Loading branch information
kaiquedu committed Dec 19, 2024
1 parent 952340f commit 304e20e
Show file tree
Hide file tree
Showing 21 changed files with 567 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>

<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

Expand Down
27 changes: 27 additions & 0 deletions TheatricalPlayersRefactoringKata/API/API.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
<ProjectReference Include="..\TheatricalPlayersRefactoringKata.csproj" />
</ItemGroup>



</Project>
6 changes: 6 additions & 0 deletions TheatricalPlayersRefactoringKata/API/API.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@API_HostAddress = http://localhost:5295

GET {{API_HostAddress}}/weatherforecast/
Accept: application/json

###
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using Microsoft.AspNetCore.Mvc;
using TheatricalPlayersRefactoringKata.API.Data;
using TheatricalPlayersRefactoringKata.API.DTOs;
using TheatricalPlayersRefactoringKata.API.Queue;
using System.Text.Json;

namespace TheatricalPlayersRefactoringKata.API.Controllers
{
[ApiController]
[Route("api/v1/statements")]
public class StatementController : ControllerBase
{
private readonly IStatementProcessingQueue _queue;
private readonly AppDbContext _dbContext;
private readonly IStatementExportService _exportService;

public StatementController(
IStatementProcessingQueue queue,
AppDbContext dbContext,
IStatementExportService exportService)
{
_queue = queue;
_dbContext = dbContext;
_exportService = exportService;
}

[HttpPost("create")]
public async Task<IActionResult> PostInvoice([FromBody] InvoiceRequestDTO invoiceRequest)
{
if (invoiceRequest == null ||
string.IsNullOrEmpty(invoiceRequest.Customer) ||
invoiceRequest.Performances == null || !invoiceRequest.Performances.Any())
{
return BadRequest(new { message = "Customer and performances are required." });
}

string invoiceJson = JsonSerializer.Serialize(invoiceRequest);

try
{
await _queue.EnqueueAsync(invoiceJson);
return Accepted(new { message = "Invoice enqueued for processing." });
}
catch (Exception ex)
{
return StatusCode(500, new { message = $"An error occurred while enqueuing the invoice: {ex.Message}" });
}
}

[HttpGet("{id:int}")]
public IActionResult GetInvoice(int id)
{
if (id <= 0)
{
return BadRequest(new { message = "Invalid invoice ID." });
}

var invoice = _dbContext.Invoices.Find(id);
if (invoice == null)
{
return NotFound(new { message = "Invoice not found." });
}

var invoiceDto = new InvoiceResponseDTO
{
InvoiceId = invoice.Id,
Customer = invoice.Customer,
StatementXml = invoice.StatementXml,
ProcessedAt = invoice.ProcessedAt
};

return Ok(invoiceDto);
}

[HttpGet("{id:int}/xml")]
public IActionResult GetInvoiceXml(int id)
{
if (id <= 0)
{
return BadRequest(new { message = "Invalid invoice ID." });
}

var invoice = _dbContext.Invoices.Find(id);
if (invoice == null)
{
return NotFound(new { message = "Invoice not found." });
}

var invoiceDto = new InvoiceResponseDTO
{
InvoiceId = invoice.Id,
Customer = invoice.Customer,
StatementXml = invoice.StatementXml,
ProcessedAt = invoice.ProcessedAt
};

try
{
var xml = _exportService.GerarExtratoXml(invoiceDto);
return Content(xml, "application/xml");
}
catch (Exception ex)
{
return StatusCode(500, new { message = $"An error occurred while generating the XML: {ex.Message}" });
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace TheatricalPlayersRefactoringKata.API.DTOs
{
public class InvoiceRequestDTO
{
public string Customer { get; set; } = string.Empty;
public List<Performance> Performances { get; set; } = new List<Performance>();
}
}
12 changes: 12 additions & 0 deletions TheatricalPlayersRefactoringKata/API/DTOs/InvoiceResponseDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace TheatricalPlayersRefactoringKata.API.DTOs
{
public class InvoiceResponseDTO
{
public int InvoiceId { get; set; }
public string Customer { get; set; }
public string StatementXml { get; set; }
public DateTime ProcessedAt { get; set; }

public List<Performance> Performances { get; set; } = new List<Performance>();
}
}
14 changes: 14 additions & 0 deletions TheatricalPlayersRefactoringKata/API/Data/AppDbContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Microsoft.EntityFrameworkCore;

namespace TheatricalPlayersRefactoringKata.API.Data
{
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
{
}

public DbSet<InvoiceEntity> Invoices { get; set; }
}
}
12 changes: 12 additions & 0 deletions TheatricalPlayersRefactoringKata/API/Data/InvoiceEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace TheatricalPlayersRefactoringKata.API.Data
{
public class InvoiceEntity
{
public int Id { get; set; }
public string Customer { get; set; }
public string StatementXml { get; set; }
public DateTime ProcessedAt { get; set; }

public List<Performance> Performances { get; set; } = new List<Performance>();
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace API.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Invoices",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Customer = table.Column<string>(type: "TEXT", nullable: false),
StatementXml = table.Column<string>(type: "TEXT", nullable: false),
ProcessedAt = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Invoices", x => x.Id);
});
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Invoices");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using TheatricalPlayersRefactoringKata.API.Data;

#nullable disable

namespace API.Migrations
{
[DbContext(typeof(AppDbContext))]
partial class AppDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "9.0.0");

modelBuilder.Entity("TheatricalPlayersRefactoringKata.API.Data.InvoiceEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");

b.Property<string>("Customer")
.IsRequired()
.HasColumnType("TEXT");

b.Property<DateTime>("ProcessedAt")
.HasColumnType("TEXT");

b.Property<string>("StatementXml")
.IsRequired()
.HasColumnType("TEXT");

b.HasKey("Id");

b.ToTable("Invoices");
});
#pragma warning restore 612, 618
}
}
}
52 changes: 52 additions & 0 deletions TheatricalPlayersRefactoringKata/API/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using Microsoft.EntityFrameworkCore;
using TheatricalPlayersRefactoringKata.API.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");

if (builder.Environment.IsDevelopment())
{
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlite(connectionString));
}
else
{
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(connectionString));
}

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
{
Title = "Theatrical Players Refactoring API",
Version = "v1",
Description = "API for processing theatrical performances and generating invoices"
});

options.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
});

builder.Services.AddAuthorization();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Theatrical Players Refactoring API v1");
});
}

app.UseHttpsRedirection();
app.UseAuthorization();

app.MapControllers();

app.Run();
Loading

0 comments on commit 304e20e

Please sign in to comment.