More Related Content Similar to [PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić siebie z przeszłości (20) More from Mateusz Zalewski (9) [PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić siebie z przeszłości1. „KTO TO PISAŁ?!… A, TO JA.”
czyli sposoby, żeby znienawidzić
siebie z przeszłości
5. czyli jak wiedźmin i angielski teolog
mogą pomóc Ci pisać lepszy kod
„KTO TO PISAŁ?! A, TO JA…”
6. „KTO TO PISAŁ?! A, TO JA…”
czyli jak wiedźmin i angielski teolog
mogą pomóc Ci pisać lepszy kod
albo przynajmniej zrozumieć, czemu nie
jest tak dobry, jak byś chciał(a)
17. final class ProductVariantPriceCalculatorSpec extends ObjectBehavior
{
function it_implements_product_variant_price_calculator_interface(): void
{
$this->shouldImplement(ProductVariantPricesCalculatorInterface::class);
}
function it_gets_price_for_product_variant_in_given_channel(
ChannelInterface $channel,
ChannelPricingInterface $channelPricing,
ProductVariantInterface $productVariant,
): void {
$productVariant->getChannelPricingForChannel($channel)->willReturn($channelPricing);
$channelPricing->getPrice()->willReturn(1000);
$this->calculate($productVariant, ['channel' => $channel])->shouldReturn(1000);
}
}
18. final class ProductVariantPriceCalculatorSpec extends ObjectBehavior
{
function it_implements_product_variant_price_calculator_interface(): void
{
$this->shouldImplement(ProductVariantPricesCalculatorInterface::class);
}
function it_gets_price_for_product_variant_in_given_channel(
ChannelInterface $channel,
ChannelPricingInterface $channelPricing,
ProductVariantInterface $productVariant,
): void {
$productVariant->getChannelPricingForChannel($channel)->willReturn($channelPricing);
$channelPricing->getPrice()->willReturn(1000);
$this->calculate($productVariant, ['channel' => $channel])->shouldReturn(1000);
}
}
😡
19. 1 . P O P R A W N O Ś Ć
2 . S P Ó J N O Ś Ć
21. P U Ł A P K A
S P Ó J N O Ś C I
22. D O K U M E N T A C J A
31. P Ł O T C H E S T E R T O N A
32. final class GrossPriceCalculatorTest extends TestCase
{
/** @dataProvider provideGrossCalculationData */
public function testItCountsGrossPriceForGivenNetPriceAndTaxRate(
int $netPrice,
float $taxRate,
int $expectedGrossPrice
): void {
self::assertSame(
$expectedGrossPrice,
GrossPriceCalculator::calculateGrossPrice($netPrice, $taxRate)
);
}
private function provideGrossCalculationData(): iterable
{
yield 'net price 500, tax rate 7.0%' => [
'netPrice' => 500,
'taxRate' => 0.07,
'expectedGrossPrice' => 535,
];
yield 'net price 750, tax rate 7.7%' => [
'netPrice' => 750,
'taxRate' => 0.077,
'expectedGrossPrice' => 808,
];
yield 'net price 1500, tax rate 8.5%' => [
'netPrice' => 1500,
'taxRate' => 0.085,
'expectedGrossPrice' => 1628,
];
}
}
33. final class GrossPriceCalculatorTest extends TestCase
{
/** @dataProvider provideGrossCalculationData */
public function testItCountsGrossPriceForGivenNetPriceAndTaxRate(
int $netPrice,
float $taxRate,
int $expectedGrossPrice
): void {
self::assertSame(
$expectedGrossPrice,
GrossPriceCalculator::calculateGrossPrice($netPrice, $taxRate)
);
}
private function provideGrossCalculationData(): iterable
{
yield 'net price 500, tax rate 7.0%' => [
'netPrice' => 500,
'taxRate' => 0.07,
'expectedGrossPrice' => 535,
];
yield 'net price 750, tax rate 7.7%' => [
'netPrice' => 750,
'taxRate' => 0.077,
'expectedGrossPrice' => 808,
];
yield 'net price 1500, tax rate 8.5%' => [
'netPrice' => 1500,
'taxRate' => 0.085,
'expectedGrossPrice' => 1628,
];
}
}
❗
❗
34. final class GrossPriceCalculatorTest extends TestCase
{
/** @dataProvider provideGrossCalculationData */
public function testItCountsGrossPriceForGivenNetPriceAndTaxRate(
int $netPrice,
float $taxRate,
int $expectedGrossPrice
): void {
self::assertSame(
$expectedGrossPrice,
GrossPriceCalculator::calculateGrossPrice($netPrice, $taxRate)
);
}
private function provideGrossCalculationData(): iterable
{
yield 'net price 500, tax rate 7.0%' => [
'netPrice' => 500,
'taxRate' => 0.07,
'expectedGrossPrice' => 535,
];
yield 'net price 750, tax rate 7.7%' => [
'netPrice' => 750,
'taxRate' => 0.077,
'expectedGrossPrice' => 810,
];
yield 'net price 1500, tax rate 8.5%' => [
'netPrice' => 1500,
'taxRate' => 0.085,
'expectedGrossPrice' => 1630,
];
}
}
✅
✅
🤨
37. K O N T E K S T
W I E D Z Y I
C Z A S U
38. D Ł U G
T E C H N I C Z N Y
40. final class OrderTaxesProcessor implements OrderProcessorInterface
{
public function __construct(
private ZoneProviderInterface $defaultTaxZoneProvider,
private ZoneMatcherInterface $zoneMatcher,
private PrioritizedServiceRegistryInterface $strategyRegistry,
private ?TaxationAddressResolverInterface $taxationAddressResolver = null,
) {
}
public function process(BaseOrderInterface $order): void
{
if (OrderInterface::STATE_CART !== $order->getState()) {
return;
}
$this->clearTaxes($order);
if ($order->isEmpty()) {
return;
}
$zone = $this->getTaxZone($order);
if (null === $zone) {
return;
}
/** @var TaxCalculationStrategyInterface $strategy */
foreach ($this->strategyRegistry->all() as $strategy) {
if ($strategy->supports($order, $zone)) {
$strategy->applyTaxes($order, $zone);
46. 2 0 2 0
/api/v2 header /new-api
😂
47. 2 0 2 0
/api/v2 header
/new-api
🤡
49. P O S T Ę P J E S T
J A K S T A D O
Ś W I Ń
50. R E F A C T O R I N G
53. Z A S A D A S K A U T A
57. S O L I D
K I S S
D R Y
Y A G N I
C U P I D
59. public function process(BaseOrderInterface $order): void
{
/** @var OrderInterface $order */
Assert::isInstanceOf($order, OrderInterface::class);
if (OrderInterface::STATE_CART !== $order->getState()) {
return;
}
$this->clearTaxes($order);
if ($order->isEmpty()) {
return;
}
$zone = $this->getTaxZone($order);
if (null === $zone) {
return;
}
/** @var TaxCalculationStrategyInterface $strategy */
foreach ($this->strategyRegistry->all() as $strategy) {
if ($strategy->supports($order, $zone)) {
$strategy->applyTaxes($order, $zone);
return;
}
}
throw new UnsupportedTaxCalculationStrategyException();
}
private function getTaxZone(OrderInterface $order): ?ZoneInterface
{
$taxationAddress = $order->getBillingAddress();
$zone = $this->zoneMatcher->match($taxationAddress, Scope::TAX);
return $zone ?: $this->defaultTaxZoneProvider->getZone($order);
}
private function clearTaxes(OrderInterface $order): void
{
$order->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
foreach ($order->getItems() as $item) {
$item->removeAdjustmentsRecursively(AdjustmentInterface::TAX_ADJUSTMENT);
}
/** @var ShipmentInterface $shipment */
foreach ($order->getShipments() as $shipment) {
$shipment->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
}
}
60. public function process(BaseOrderInterface $order): void
{
/** @var OrderInterface $order */
Assert::isInstanceOf($order, OrderInterface::class);
if (OrderInterface::STATE_CART !== $order->getState()) {
return;
}
$this->clearTaxes($order);
if ($order->isEmpty()) {
return;
}
$zone = $this->getTaxZone($order);
if (null === $zone) {
return;
}
/** @var TaxCalculationStrategyInterface $strategy */
foreach ($this->strategyRegistry->all() as $strategy) {
if ($strategy->supports($order, $zone)) {
$strategy->applyTaxes($order, $zone);
return;
}
}
throw new UnsupportedTaxCalculationStrategyException();
}
private function getTaxZone(OrderInterface $order): ?ZoneInterface
{
$taxationAddress = $order->getBillingAddress();
$zone = $this->zoneMatcher->match($taxationAddress, Scope::TAX);
return $zone ?: $this->defaultTaxZoneProvider->getZone($order);
}
private function clearTaxes(OrderInterface $order): void
{
$order->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
foreach ($order->getItems() as $item) {
$item->removeAdjustmentsRecursively(AdjustmentInterface::TAX_ADJUSTMENT);
}
/** @var ShipmentInterface $shipment */
foreach ($order->getShipments() as $shipment) {
$shipment->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
}
}
61. public function process(BaseOrderInterface $order): void
{
/** @var OrderInterface $order */
Assert::isInstanceOf($order, OrderInterface::class);
if (OrderInterface::STATE_CART !== $order->getState()) {
return;
}
$this->clearTaxes($order);
if ($order->isEmpty()) {
return;
}
$zone = $this->getTaxZone($order);
if (null === $zone) {
return;
}
/** @var TaxCalculationStrategyInterface $strategy */
foreach ($this->strategyRegistry->all() as $strategy) {
if ($strategy->supports($order, $zone)) {
$strategy->applyTaxes($order, $zone);
return;
}
}
throw new UnsupportedTaxCalculationStrategyException();
}
private function getTaxZone(OrderInterface $order): ?ZoneInterface
{
$taxationAddress = $order->getBillingAddress();
$zone = $this->zoneMatcher->match($taxationAddress, Scope::TAX);
return $zone ?: $this->defaultTaxZoneProvider->getZone($order);
}
private function clearTaxes(OrderInterface $order): void
{
$order->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
foreach ($order->getItems() as $item) {
$item->removeAdjustmentsRecursively(AdjustmentInterface::TAX_ADJUSTMENT);
}
/** @var ShipmentInterface $shipment */
foreach ($order->getShipments() as $shipment) {
$shipment->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
}
}
62. I M P L E M E N T A C J A
Z P R Z Y P A D K U
67. D I S C O M F O R T
D R I V E N
D E V E L O P M E N T