Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Teste/ivan-lempek #85

Open
wants to merge 41 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
d31c0c8
Update README.md
Sep 16, 2024
62e285b
Merge pull request #1 from ivanlmpk/teste/ivan-lempek
Sep 16, 2024
e7b1de8
feat: Adicionado método para realizar cálculo do valor do genêro de h…
Sep 17, 2024
c6af7b9
Merge pull request #2 from ivanlmpk/teste/ivan-lempek
Sep 17, 2024
91dbe58
feat: Refatorado calculos dos gêneros de tragedia e comedia em novos …
Sep 17, 2024
9e1f3c2
Merge pull request #3 from ivanlmpk/teste/ivan-lempek
Sep 17, 2024
8c9c8bf
refactor: Ajustado cases de tragedia e comédia com os novos métodos.
Sep 17, 2024
333109a
Merge pull request #4 from ivanlmpk/teste/ivan-lempek
Sep 17, 2024
caf7958
feat: Adicionado novo case para o gênero de história com seu método d…
Sep 17, 2024
69ce5fd
Merge pull request #5 from ivanlmpk/teste/ivan-lempek
Sep 17, 2024
963d238
refactor: Alterado tipagem das variaveis totalAmount e thisAmount no …
Sep 17, 2024
962ea52
Merge pull request #6 from ivanlmpk/teste/ivan-lempek
Sep 17, 2024
f9c6ea8
feat: Implementado método para gerar o XML. Adicionado nova classe pa…
Sep 17, 2024
bbafe8a
Merge pull request #7 from ivanlmpk/teste/ivan-lempek
Sep 17, 2024
216e844
feat: Adicionado pasta DTO com nova classe StatementResult para encap…
Sep 18, 2024
dd48337
feat: Adicionado nova pasta UseCases na camada de application com a c…
Sep 18, 2024
b22caa4
feat: Adicionado camada de dominio com as entidades. Adicionado novo …
Sep 18, 2024
2b62cd9
feat: adicionado camada de interfaces com IPlayRepository e IPlayType…
Sep 18, 2024
ead7e39
feat: adicionado camada de serviços com classes para fazer os calculo…
Sep 18, 2024
d8f9cd9
feat: Adicionado camada de Helper com classe Utf8StringWriter que aux…
Sep 18, 2024
49ea762
feat: adicionado camada Infra e repositórios com a implementação conc…
Sep 18, 2024
c3a7347
feat: Adicionado camada de apresentação com as classes de impressão d…
Sep 18, 2024
8e71fed
feat: Ajustado arquivo de teste para funcionar com refatorações. Adic…
Sep 18, 2024
26d2ab2
Merge pull request #8 from ivanlmpk/teste/ivan-lempek
Sep 18, 2024
e179147
feat: Adicionado interface com contrato para as impressões.
Sep 18, 2024
bc470ac
feat: Adicionado factorys para que, tanto a escolha do arquivo de tes…
Sep 18, 2024
b100578
refactor: Ajustado classes de impressão para funcionarem com nova int…
Sep 18, 2024
20fd3c0
feat: Adicionado novo teste TestGeneralStatement que pode testar qual…
Sep 18, 2024
34009f0
Merge pull request #9 from ivanlmpk/teste/ivan-lempek
Sep 18, 2024
a854fd9
feat: Adicionado novas camadas para a execução de filas. Adicionado s…
Sep 18, 2024
88a96be
feat: Adicionado teste para processar duas impressões com filas e de …
Sep 18, 2024
86a561c
fix: removido linha desnecessaria.
Sep 18, 2024
22f473b
Merge pull request #10 from ivanlmpk/teste/ivan-lempek
Sep 18, 2024
e1a8eff
fix: ajustado nome no construtor da classe Invoice.
Sep 18, 2024
8a6a236
feat: Adicionado projeto de API com dois end-points. Um para gerar o …
Sep 18, 2024
a1f4f25
feat: Adicionado documentação para os end-points e API.
Sep 18, 2024
de3d42e
fix: Ajustado documentação do end-point de geração de extrato.
Sep 18, 2024
5dc36c6
Merge pull request #11 from ivanlmpk/teste/ivan-lempek
Sep 18, 2024
2cfde3e
feat: Adicionado novo service para salvar os extratos no banco de dad…
Sep 18, 2024
33a45bd
fix: ajustado lógica de save do extrato para a API - evitando conflit…
Sep 18, 2024
14d7e7e
Merge pull request #12 from ivanlmpk/teste/ivan-lempek
Sep 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 1 addition & 110 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,110 +1 @@
# Teste Backend

![Aiko](img/logo.png)

## Apresentação e estado atual da aplicação

Essa aplicação é usada por uma companhia de teatro para gerar extratos
impressos a partir das faturas de seus clientes.

A companhia é contratada pelos clientes para múltiplas apresentações e a
cobrança é feita baseada no número de linhas de cada peça apresentada, no
tamanho da platéia e no gênero da peça. Atualmente os gêneros trabalhados pela
companhia são tragédia e comédia.

Para cada apresentação são também gerados créditos, que são um tipo de
mecanismo de fidelização que os clientes podem usar para obter descontos em
futuras apresentações. O total de créditos gerados é também mostrado no
extrato.

## Novas funcionalidades desejadas

A companhia de teatro pretende adicionar o gênero histórico ao seu repertório,
então o software deve ser capaz de calcular os valores e créditos também para
esse gênero. Provavelmente virão mais gêneros no futuro, então o design deve
estar pronto para acomodar novos gêneros sem muita dificuldade.

Também desejam que o extrato possa ser gerado como um XML, além do formato
de texto atualmente suportado. Novamente, é bom que o design facilite que
futuramente esse extrato seja emitido em novos formatos, pois certamente é uma
questão de tempo até surgir essa demanda.

## Especificação da atividade

Este é um exercício de refatoração. O design inicial da aplicação é pouco
testável, portanto os únicos testes que a aplicação possui no momento são os
[ApprovalTests](https://approvaltests.com/) para validar a saída final. É
esperado que você torne o código mais testável e então adicione testes
unitários que validem a aplicação de forma mais granular e que dêem segurança
para futuras refatorações e para o acréscimo das novas funcionalidades.

Também serão avaliados a abordagem para desenvolvimento da solução (Desing
Patters, DDD, Solid, etc.) e a arquitetura utilizada (Clean Architecture, Onion
Architecture, etc.).

O projeto de testes possui três ApprovalTests.

* O teste TestStatementExampleLegacy, está passando no estado atual do
código. Este teste servirá para te dar segurança das primeiras refatorações
até que você escreva os testes unitários, mas ao final, com as
funcionalidades novas implementadas, este teste se torna obsoleto.
* O teste TestTextStatementExample está implementado, porém não executa, pois o
gênero histórico ainda não está implementado.
* O teste TestXmlStatementExample não está implementado e deve ser implementado
por você e gerar a saída aprovada que está no projeto de testes.

O código dos testes pode ser refatorado, desde que a saída continue a
mesma e os testes continuem cumprindo o mesmo propósito. É esperado que você
implemente as novas funcionalidades pedidas para que todos os ApprovalTests
passem.

Faça commits com frequência para que sua abordagem de refatoração seja mostrada
pelo histórico de versões.

## Extras

Não é mandatório, mas de maneira opcional os seguintes requisitos poderão ser
implementados:

* Implementar processamento assincrono de extratos, os dados devem ser imputados,
enfileirados, processados assincronicamente e gerar o XML resultante em um
diretório
* API rest para expor os métodos para futuras integrações
* Expor documentação da API por Swagger
* Persistencia dos dados em um banco de dados para salvar o extrato com suas
respectivas peças

## Regras de negócio

* O valor base para a cobrança de todas as peças é o número de linhas da peça
dividido por 10
* O número de linhas da peça considerado para o cálculo do valor base deve ser
forçado a estar no intervalo entre 1000 e 4000
* O valor para uma peça de tragédia é igual ao valor base caso a platéia seja
menor ou igual a 30, somando mais 10.00 para cada espectador adicional a
esses 30
* Para uma peça de comédia, o cálculo base é sempre somado a 3.00 por
espectador. Além disso, se a platéia for maior que 20, o valor deve ser
aumentado em 100.00 e deve se somar mais 5.00 por espectador adicional aos 20
de base
* Todas performances dão 1 crédito para cada espectador acima de 30, não
valendo nenhum crédito para uma platéia menor ou igual a 30
* Existe um bônus de créditos de um quinto da platéia arredondados para baixo,
exclusivo para peças de comédia
* As peças históricas são, por algum motivo, mais complicadas e têm o valor
igual à soma dos valores correspondentes a uma peça de tragédia e uma de
comédia
* A estrutura do XML deve seguir como referência a saída aprovada no
ApprovalTest correspondente

## Entregas

Para realizar a entrega do teste você deve:

* Relizar o fork e clonar esse repositório para sua máquina.

* Criar uma branch com o nome de `teste/[NOME]`.
* `[NOME]`: Seu nome.
* Exemplos: `teste/fulano-da-silva`; `teste/beltrano-primeiro-gomes`.

* Realize o pull request da sua branch nesse repositório.
Sistema para gerenciar pagamentos de um teatro.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using TheatricalPlayersRefactoringKata.Application.Services;
using TheatricalPlayersRefactoringKata.Application.UseCases;
using TheatricalPlayersRefactoringKata.Domain.Entities;

namespace TheatricalPlayersRefactoringKata.API.Controllers
{
[ApiController]
[Route("api/[controller]")]
[SwaggerTag("API responsável por operações de extrato.")]
public class StatementController : ControllerBase
{
private readonly EnqueueStatementUseCase _enqueueStatementUseCase;
private readonly GenerateStatementUseCase _generateStatementUseCase;
private readonly ExtractService _extractService;

public StatementController(EnqueueStatementUseCase enqueueStatementUseCase, GenerateStatementUseCase generateStatementUseCase, ExtractService extractService)
{
_enqueueStatementUseCase = enqueueStatementUseCase;
_generateStatementUseCase = generateStatementUseCase;
_extractService = extractService;
}

/// <summary>
/// Gera um extrato - Teste com os PlayIds: "hamlet", "as-like", "othello", "henry-v" ou "richard-iii"
/// </summary>
/// <param name="invoice">Extrato a ser criado.</param>
[HttpPost("GenerateExtract")]
public async Task<IActionResult> GenerateExtract([FromBody] Invoice invoice)
{
var response = _generateStatementUseCase.GenerateExtractValues(invoice);

// Save the extract in SQLite DB
await _extractService.AddExtract(response);

return Ok(response);
}

/// <summary>
/// Enfileira um extrato para processamento.
/// </summary>
/// <param name="invoice">Extrato a ser enfileirado.</param>
[HttpPost("enqueue")]
public IActionResult EnqueueInvoice([FromBody] Invoice invoice)
{
_enqueueStatementUseCase.Execute(invoice);

return Accepted("Invoice enqueued for processing.");
}
}
}

63 changes: 63 additions & 0 deletions TheatricalPlayersRefactoringKata.API/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using Microsoft.EntityFrameworkCore;
using System.Reflection;
using TheatricalPlayersRefactoringKata.Application.Services;
using TheatricalPlayersRefactoringKata.Application.UseCases;
using TheatricalPlayersRefactoringKata.Domain.Entities;
using TheatricalPlayersRefactoringKata.Domain.Interfaces;
using TheatricalPlayersRefactoringKata.Infrastructure.Data;
using TheatricalPlayersRefactoringKata.Infrastructure.Queues;
using TheatricalPlayersRefactoringKata.Infrastructure.Repositories;
using TheatricalPlayersRefactoringKata.Presentation;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();

builder.Services.AddSingleton(provider => new Dictionary<string, Play>
{
{ "hamlet", new Play("Hamlet", 4024, "tragedy") },
{ "as-like", new Play("As You Like It", 2670, "comedy") },
{ "othello", new Play("Othello", 3560, "tragedy") },
{ "henry-v", new Play("Henry V", 3227, "history") },
{ "richard-iii", new Play("Richard III", 3718, "history") }
});

builder.Services.AddSingleton<IPlayRepository, PlayRepository>();
builder.Services.AddSingleton<IStatementQueue, StatementQueue>();

builder.Services.AddTransient<GenerateStatementUseCase>();
builder.Services.AddTransient<EnqueueStatementUseCase>();

builder.Services.AddTransient<XmlStatementPrinter>();
builder.Services.AddScoped<ExtractService>();

builder.Services.AddEndpointsApiExplorer();

builder.Services.AddSwaggerGen(options =>
{
options.EnableAnnotations();

var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
});

builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite("Data Source=TheatricalPlayersRefactoringKataDb.sqlite"));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:49369",
"sslPort": 44358
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5235",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7123;http://localhost:5235",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.33" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.33" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.33">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.3" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.7.3" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\TheatricalPlayersRefactoringKata\TheatricalPlayersRefactoringKata.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ActiveDebugProfile>https</ActiveDebugProfile>
<Controller_SelectedScaffolderID>MvcControllerEmptyScaffolder</Controller_SelectedScaffolderID>
<Controller_SelectedScaffolderCategoryPath>root/Common/MVC/Controller</Controller_SelectedScaffolderCategoryPath>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@TheatricalPlayersRefactoringKata.API_HostAddress = http://localhost:5235

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

###
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
9 changes: 9 additions & 0 deletions TheatricalPlayersRefactoringKata.API/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Statement for BigCo
Hamlet: $650.00 (55 seats)
As You Like It: $547.00 (35 seats)
Othello: $456.00 (40 seats)
Henry V: $705.40 (20 seats)
King John: $931.60 (39 seats)
Henry V: $705.40 (20 seats)
Amount owed is $3,995.40
You earned 56 credits
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<Statement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Customer>BigCo</Customer>
<Items>
<Item>
<AmountOwed>650</AmountOwed>
<EarnedCredits>25</EarnedCredits>
<Seats>55</Seats>
</Item>
<Item>
<AmountOwed>547</AmountOwed>
<EarnedCredits>12</EarnedCredits>
<Seats>35</Seats>
</Item>
<Item>
<AmountOwed>456</AmountOwed>
<EarnedCredits>10</EarnedCredits>
<Seats>40</Seats>
</Item>
<Item>
<AmountOwed>705.4</AmountOwed>
<EarnedCredits>0</EarnedCredits>
<Seats>20</Seats>
</Item>
<Item>
<AmountOwed>931.6</AmountOwed>
<EarnedCredits>9</EarnedCredits>
<Seats>39</Seats>
</Item>
<Item>
<AmountOwed>705.4</AmountOwed>
<EarnedCredits>0</EarnedCredits>
<Seats>20</Seats>
</Item>
</Items>
<AmountOwed>3995.4</AmountOwed>
<EarnedCredits>56</EarnedCredits>
</Statement>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Statement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Customer>BigCo</Customer>
<Items>
Expand Down
Loading