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/danilo daltro #81

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<Folder Include="Interfaces\" />
<Folder Include="Services\" />
</ItemGroup>

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

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Xml.Serialization;
using System.Xml;
using TheatricalPlayersRefactoringKata.Application.Utils;
using TheatricalPlayersRefactoringKata.Domain;
using TheatricalPlayersRefactoringKata.Domain.Entities;
using TheatricalPlayersRefactoringKata.Domain.ValueObjects;

namespace TheatricalPlayersRefactoringKata.Application;

public class StatementPrinter
{
public string Print(Invoice invoice)
{
return invoice.PrintInvoiceStatement();
}

public string PrintXmlStatement(Invoice invoice)
{
var items = new List<StatementItem>();

foreach (var performance in invoice.Performances)
{
decimal amountOwed = performance.GetPlayAmountValue();
int earnedCredits = performance.GetPlayCreditsValue();
int seats = performance.Audience;
var item = StatementItem.Create(amountOwed, earnedCredits, seats);
items.Add(item);
}

var invoiceStatement = Statement.Create(invoice.Customer, items);

var xmlSerializer = new XmlSerializer(typeof(Statement));

using (var stringWriter = new Utf8StringWriter())
{
using (var writer = XmlWriter.Create(stringWriter, new XmlWriterSettings { Indent = true }))
{
xmlSerializer.Serialize(writer, invoiceStatement);
return stringWriter.ToString();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Text;

namespace TheatricalPlayersRefactoringKata.Application.Utils
{
public class Utf8StringWriter : StringWriter
{
public override Encoding Encoding => new UTF8Encoding(false);
}
}
11 changes: 11 additions & 0 deletions TheatricalPlayersRefactoringKata.Domain/Entities/Entity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

using System.Xml.Serialization;

namespace TheatricalPlayersRefactoringKata.Domain.Entities
{
public abstract class Entity
{
[XmlIgnore]
public Guid Id { get; protected set; }
}
}
48 changes: 48 additions & 0 deletions TheatricalPlayersRefactoringKata.Domain/Entities/Invoice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System.Globalization;
using TheatricalPlayersRefactoringKata.Domain.Entities;
using TheatricalPlayersRefactoringKata.Domain.Validation;

namespace TheatricalPlayersRefactoringKata.Domain;

public class Invoice : Entity
{
private string _customer;
private List<Performance> _performances;

public string Customer { get => _customer; set => _customer = value; }
public List<Performance> Performances { get => _performances; set => _performances = value; }

public Invoice(string customer, List<Performance> performance)
{
ValidateDomain(customer);
this._performances = performance;
}

private void ValidateDomain(string customer)
{
DomainExceptionValidation.When(string.IsNullOrWhiteSpace(customer), "Invalid customer. Customer is required.");
this._customer = customer;
}

public string PrintInvoiceStatement()
{
decimal totalAmount = 0;
int volumeCredits = 0;
var result = string.Format("Statement for {0}\n", _customer);
CultureInfo cultureInfo = new CultureInfo("en-US");

foreach (Performance performance in _performances)
{
decimal thisAmount = performance.Play.CalculateAmountValueByAudience(performance.Audience);
result += String.Format(cultureInfo, " {0}: {1:C} ({2} seats)\n", performance.Play.Name, thisAmount, performance.Audience);

totalAmount += thisAmount;
volumeCredits += performance.Play.CalculateCreditsByAudience(performance.Audience);
}

result += String.Format(cultureInfo, "Amount owed is {0:C}\n", totalAmount);
result += String.Format("You earned {0} credits\n", volumeCredits);
return result;
}

}
35 changes: 35 additions & 0 deletions TheatricalPlayersRefactoringKata.Domain/Entities/Performance.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using TheatricalPlayersRefactoringKata.Domain.Entities;
using TheatricalPlayersRefactoringKata.Domain.Validation;

namespace TheatricalPlayersRefactoringKata.Domain;

public class Performance : Entity
{
private Play _play;
private int _audience;

public Play Play { get => _play; set => _play = value; }
public int Audience { get => _audience; set => _audience = value; }

public Performance(Play play, int audience)
{
ValidateDomain(audience);
this._play = play;
}

private void ValidateDomain(int audience)
{
DomainExceptionValidation.When(audience < 0, "Invalid value. Audience must be equal or higher than 0.");
this._audience = audience;
}

public decimal GetPlayAmountValue()
{
return _play.CalculateAmountValueByAudience(_audience);
}

public int GetPlayCreditsValue()
{
return _play.CalculateCreditsByAudience(_audience);
}
}
50 changes: 50 additions & 0 deletions TheatricalPlayersRefactoringKata.Domain/Entities/Play.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using TheatricalPlayersRefactoringKata.Domain.Entities;
using TheatricalPlayersRefactoringKata.Domain.Enums;
using TheatricalPlayersRefactoringKata.Domain.Interfaces;
using TheatricalPlayersRefactoringKata.Domain.Validation;
using TheatricalPlayersRefactoringKata.Domain.ValueObjects;

namespace TheatricalPlayersRefactoringKata.Domain;

public class Play : Entity
{
private string _name;
private int _lines;
private PlayType _playType;
private IPlayTypeStrategy _playTypeStrategy;

public string Name { get => _name; set => _name = value; }
public int Lines { get => _lines; set => _lines = value; }
public string TypeName { get => _playType.Name; }
public PlayType PlayType { get => _playType; set => _playType = value; }

public Play(string name, int lines, PlayTypeEnum playType)
{
ValidateDomain(name, lines, playType);
_playType = new PlayType(playType);
_playTypeStrategy = _playType.GetStrategies();
}

private void ValidateDomain(string name, int lines, PlayTypeEnum playType)
{
DomainExceptionValidation.When(string.IsNullOrWhiteSpace(name), "Invalid name. Name is required.");
this._name = name;

DomainExceptionValidation.When(lines < 0, "Invalid value. Lines must be equal or higher than 0.");
this._lines = lines;
}

public decimal CalculateAmountValueByAudience(int audience)
{
int lines = Math.Clamp(this.Lines, 1000, 4000);
int baseValue = lines * 10;
decimal totalAmount = _playTypeStrategy.CalculateTotalAmountByAudience(baseValue, audience);
return decimal.Round(totalAmount / 100, 2);
}

public int CalculateCreditsByAudience(int audience)
{
int valueBase = Math.Max(audience - 30, 0);
return _playTypeStrategy.CalculateCreditsByAudience(valueBase, audience);
}
}
48 changes: 48 additions & 0 deletions TheatricalPlayersRefactoringKata.Domain/Entities/Statement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System.Xml.Serialization;
using TheatricalPlayersRefactoringKata.Domain.Validation;
using TheatricalPlayersRefactoringKata.Domain.ValueObjects;

namespace TheatricalPlayersRefactoringKata.Domain.Entities
{
public class Statement : Entity
{
private List<StatementItem> _items { get; set; }
private string _customer { get; set; }
private decimal _amoutOwed { get; set; }
private int _earnedCredits { get; set; }

[XmlElement("Customer")]
public string Customer { get => _customer; set => _customer = value; }

[XmlArray("Items")]
[XmlArrayItem("Item")]
public List<StatementItem> Items { get => _items; set => _items = value; }

[XmlElement("AmountOwed")]
public decimal AmountOwed { get => _amoutOwed; set => _amoutOwed = value; }

[XmlElement("EarnedCredits")]
public int EarnedCredits { get => _earnedCredits; set => _earnedCredits = value; }

public Statement() { }

private Statement(string customer, List<StatementItem> items)
{
ValidateDomain(customer);
_items = items;
_amoutOwed = _items.Sum(x => x.AmountOwed);
_earnedCredits = _items.Sum(x => x.EarnedCredits);
}

public static Statement Create(string customer, List<StatementItem> items)
{
return new Statement(customer, items);
}

private void ValidateDomain(string customer)
{
DomainExceptionValidation.When(string.IsNullOrWhiteSpace(customer), "Invalid customer. Customer is required.");
_customer = customer;
}
}
}
25 changes: 25 additions & 0 deletions TheatricalPlayersRefactoringKata.Domain/Enums/PlayTypeEnum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

namespace TheatricalPlayersRefactoringKata.Domain.Enums
{
public enum PlayTypeEnum
{
[PlayTypeEnumAttributes("Comedy")]
Comedy = 0,

[PlayTypeEnumAttributes("Tragedy")]
Tragedy = 1,

[PlayTypeEnumAttributes("History")]
History = 2
}

public class PlayTypeEnumAttributes : Attribute
{
public string Name { get; private set; }

internal PlayTypeEnumAttributes(string name)
{
this.Name = name;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TheatricalPlayersRefactoringKata.Domain.Enums;

namespace TheatricalPlayersRefactoringKata.Domain.Extensions
{
public static class EnumExtensions
{
public static string GetPlayTypeName(this Enum value)
{
var field = value.GetType().GetField(value.ToString());

if (field == null) { return value.ToString(); }

var attribute = Attribute.GetCustomAttribute(field, typeof(PlayTypeEnumAttributes)) as PlayTypeEnumAttributes;

return attribute != null ? attribute.Name : value.ToString();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@


namespace TheatricalPlayersRefactoringKata.Domain.Interfaces
{
public interface IPlayTypeStrategy
{
public int CalculateTotalAmountByAudience(int baseValue, int audience);
public int CalculateCreditsByAudience(int valueBase, int audience);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TheatricalPlayersRefactoringKata.Domain.Interfaces;

namespace TheatricalPlayersRefactoringKata.Domain.Strategies
{
internal class ComedyPlayTypeStrategies : IPlayTypeStrategy
{
public int CalculateTotalAmountByAudience(int baseValue, int audience)
{
int amount = baseValue;
if (audience > 20)
{
amount += 10000 + 500 * (audience - 20);
}
amount += 300 * audience;
return amount;
}

public int CalculateCreditsByAudience(int valueBase, int audience)
{
int credits = valueBase;
credits += (int)Math.Floor((decimal)audience / 5);
return credits;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TheatricalPlayersRefactoringKata.Domain.Interfaces;

namespace TheatricalPlayersRefactoringKata.Domain.Strategies
{
internal class HistoryPlayTypeStrategies : IPlayTypeStrategy
{
public int CalculateTotalAmountByAudience(int baseValue, int audience)
{
var comedyCalcAmountStrategy = new ComedyPlayTypeStrategies();
var tragedyCalcAmoutStrategy = new TragedyPlayTypeStrategies();

int totalAmount = 0;

totalAmount += comedyCalcAmountStrategy.CalculateTotalAmountByAudience(baseValue, audience);
totalAmount += tragedyCalcAmoutStrategy.CalculateTotalAmountByAudience(baseValue, audience);

return totalAmount;
}

public int CalculateCreditsByAudience(int valueBase, int audience)
{
return valueBase;
}
}
}
Loading