<?php
//=============================================================================
// DEFINE coefficient:
//=============================================================================
define('DEFAULT_WEIGHT_COEFFICIENT', 11);
define('DEFAULT_DIMENSION_COEFFICIENT', 11);
Last active
February 19, 2021 09:39
-
-
Save vanthao03596/0dd0df8081f7419e8f9fc269aec96d32 to your computer and use it in GitHub Desktop.
OOP
<?php
namespace App;
class Item
{
protected float $weight;
protected float $width;
protected float $height;
protected float $depth;
protected float $amazonPrice;
protected float $weightCoefficient = DEFAULT_WEIGHT_COEFFICIENT;
protected float $dimensionCoefficient = DEFAULT_DIMENSION_COEFFICIENT;
protected $feeByProductType;
public function itemPrice()
{
return $this->amazonPrice + $this->shippingFee();
}
protected function shippingFee()
{
if ($this->feeByProductType) {
return max($this->feeByWeight(), $this->feeByDimensions(), $this->feeByProductType);
}
return max($this->feeByWeight(), $this->feeByDimensions());
}
protected function feeByWeight()
{
return $this->weight * $this->weightCoefficient;
}
protected function feeByDimensions()
{
return $this->width * $this->height * $this->depth * $this->dimensionCoefficient;
}
public function withWeight($weight)
{
$this->weight = $weight;
return $this;
}
public function withHeight($height)
{
$this->height = $height;
return $this;
}
public function withWidth($width)
{
$this->width = $width;
return $this;
}
public function withDepth($depth)
{
$this->depth = $depth;
return $this;
}
public function withAmazonPrice($amazonPrice)
{
$this->amazonPrice = $amazonPrice;
return $this;
}
public function withWeightCoefficient($weightCoefficient)
{
$this->weightCoefficient = $weightCoefficient;
return $this;
}
public function withDimensionCoefficient($dimensionCoefficient)
{
$this->dimensionCoefficient = $dimensionCoefficient;
return $this;
}
public static function make()
{
return new static();
}
}
<?php
namespace App;
class Order
{
/**
* @var Item[]
*/
protected $items = [];
public function addItem(Item $item)
{
$this->items[] = $item;
return $this;
}
public function calculateGrossPrice()
{
$total = 0;
foreach ($this->items as $item) {
$total += $item->itemPrice();
}
return $total;
}
public static function make()
{
return new static();
}
}
$item1 = new Item(1, 1, 2, 3, 11);
$item2 = new Item(1, 1, 2, 3, 12);
// Order 1
$order = new Order();
$order->addItem($item1);
$order->addItem($item2);
$order->calculateGrossPrice();
// Order 2
Order::make()
->addItem($item1)
->addItem($item2)
->calculateGrossPrice();
// Order 3 fluent
Order::make()
->addItem(
Item::make()
->withDepth(1)
->withHeight(2)
->withWeight(3)
->withWidth(3)
->withAmazonPrice(2)
)
->addItem(
Item::make()
->withDepth(1)
->withHeight(2)
->withWeight(3)
->withWidth(3)
->withAmazonPrice(3)
->withDimensionCoefficient(1)
->withWeightCoefficient(5)
)
->calculateGrossPrice();
<?php
namespace Tests;
use App\Item;
use PHPUnit\Framework\TestCase;
class ItemTest extends TestCase
{
protected Item $itemTest;
protected function setUp(): void
{
parent::setUp();
$this->itemTest = Item::make()
->withWidth(1)
->withHeight(2)
->withWeight(3)
->withDepth(4)
->withAmazonPrice(50);
}
public static function callMethod($obj, $name, array $args) {
$class = new \ReflectionClass($obj);
$method = $class->getMethod($name);
$method->setAccessible(true);
return $method->invokeArgs($obj, $args);
}
public function testWithAmazonPrice()
{
$item = Item::make();
$item->withAmazonPrice(1);
$this->assertEquals(1, $item->getAmazonPrice());
}
public function testWithWeight()
{
$item = Item::make();
$item->withWeight(1);
$this->assertEquals(1, $item->getWeight());
}
public function testWithDepth()
{
$item = Item::make();
$item->withDepth(1);
$this->assertEquals(1, $item->getDepth());
}
public function testWithWeightCoefficient()
{
$item = Item::make();
$this->assertEquals(DEFAULT_WEIGHT_COEFFICIENT, $item->getWeightCoefficient());
$item->withWeightCoefficient(1);
$this->assertEquals(1, $item->getWeightCoefficient());
}
public function testWithDimensionCoefficient()
{
$item = Item::make();
$this->assertEquals(DEFAULT_DIMENSION_COEFFICIENT, $item->getDimensionCoefficient());
$item->withDimensionCoefficient(1);
$this->assertEquals(1, $item->getDimensionCoefficient());
}
public function testWithHeight()
{
$item = Item::make();
$item->withHeight(1);
$this->assertEquals(1, $item->getHeight());
}
public function testWithWidth()
{
$item = Item::make();
$item->withWidth(1);
$this->assertEquals(1, $item->getWidth());
}
public function testMake()
{
$item = Item::make();
$this->assertInstanceOf(Item::class, $item);
}
public function testFeeByDimensions()
{
$expected = $this->itemTest->getWidth() * $this->itemTest->getHeight() * $this->itemTest->getDepth() * $this->itemTest->getDimensionCoefficient();
$feeByDimensions = static::callMethod(
$this->itemTest,
'feeByDimensions',
[]
);
$this->assertEquals($expected, $feeByDimensions);
}
public function testFeeByWeight()
{
$feeByWeight = static::callMethod(
$this->itemTest,
'feeByWeight',
[]
);
$expected = $this->itemTest->getWeight() * $this->itemTest->getWeightCoefficient();
$this->assertEquals($expected, $feeByWeight);
}
public function testShippingFee()
{
$shippingFee = static::callMethod(
$this->itemTest,
'shippingFee',
[]
);
$this->assertEquals(88, $shippingFee);
$this->itemTest->withFeeByProductType(100);
$shippingFeeByProductType = static::callMethod(
$this->itemTest,
'shippingFee',
[]
);
$this->assertEquals(100, $shippingFeeByProductType);
}
public function testItemPrice()
{
$expected = 88 + $this->itemTest->getAmazonPrice();
$this->assertEquals($expected, $this->itemTest->itemPrice());
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment