Skip to content

Commit

Permalink
feat: Comparing Prices
Browse files Browse the repository at this point in the history
  • Loading branch information
4513 committed Aug 27, 2023
1 parent 1bb996d commit 8d3f13a
Show file tree
Hide file tree
Showing 10 changed files with 1,435 additions and 490 deletions.
109 changes: 105 additions & 4 deletions src/Calculators/PriceCalc.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

namespace MiBo\Prices\Calculators;

use BadMethodCallException;
use DomainException;
use MiBo\Prices\Contracts\PriceCalculatorHelper;
use MiBo\Prices\Contracts\PriceComparer;
use MiBo\Prices\Contracts\PriceInterface;
use MiBo\VAT\Enums\VATRate;
use MiBo\VAT\Resolvers\ProxyResolver;
Expand All @@ -19,9 +23,16 @@
* @since 0.1
*
* @no-named-arguments Parameter names are not covered by the backward compatibility promise.
*
* @mixin \MiBo\Prices\Contracts\PriceCalculatorHelper
* @mixin \MiBo\Prices\Contracts\PriceComparer
*/
class PriceCalc
{
private static ?PriceCalculatorHelper $calculatorHelper = null;

private static ?PriceComparer $comparerHelper = null;

/**
* Returns the value of the VAT of the amount.
*
Expand All @@ -35,12 +46,17 @@ public static function getValueOfVAT(PriceInterface $price): int|float
return 0;
}

return $price->getNumericalValue()->getValue(
$price->getUnit()->getMinorUnitRate() ?? 0
) * ProxyResolver::getPercentageOf(
$minorUnitRate = $price->getUnit()->getMinorUnitRate() ?? 0;
$vatValue = round(
$price->getNumericalValue()->getValue($price->getUnit()->getMinorUnitRate() ?? 0)
* ProxyResolver::getPercentageOf(
$price->getVAT(),
method_exists($price, 'getDateTime') ? $price->getDateTime() : null
);
),
$minorUnitRate
);

return $minorUnitRate === 0 ? (int) $vatValue : $vatValue;
}

/**
Expand Down Expand Up @@ -93,4 +109,89 @@ public static function add(PriceInterface $addend, PriceInterface ...$addends):
$vat,
];
}

/**
* @param PriceCalculatorHelper $calculatorHelper
*
* @return void
*/
public static function setCalculatorHelper(PriceCalculatorHelper $calculatorHelper): void
{
self::$calculatorHelper = $calculatorHelper;
}

/**
* @param \MiBo\Prices\Contracts\PriceComparer $comparerHelper
*
* @return void
*/
public static function setComparerHelper(PriceComparer $comparerHelper): void
{
self::$comparerHelper = $comparerHelper;
}

/**
* @param string $name
* @param array<int, mixed> $arguments
*
* @return array<string, int|float>|bool|object|float|int|null
*/
public static function __callStatic(string $name, array $arguments): mixed
{
$helper = [
'round',
'ceil',
'floor',
];

if (in_array($name, $helper)) {
if (self::$calculatorHelper === null) {
throw new DomainException('The PriceCalculatorHelper is not set.');
}

return self::$calculatorHelper->$name(...$arguments);
}

$helper = [
'checkThat',
'isLessThan',
'isNotLessThan',
'isLessThanOrEqual',
'isNotLessThanOrEqual',
'isGreaterThan',
'isNotGreaterThan',
'isGreaterThanOrEqual',
'isNotGreaterThanOrEqual',
'isEqual',
'isNotEqual',
'isBetween',
'isNotBetween',
'isBetweenOrEqual',
'isNotBetweenOrEqual',
'isInteger',
'isNotInteger',
'isFloat',
'isNotFloat',
'isEvent',
'isNotEvent',
'isOdd',
'isNotOdd',
'hasSameValueAs',
'hasNotSameValueAs',
'is',
'isNot',
'hasSameValueWithVATAs',
'hasNotSameValueWithVATAs',
];

if (in_array($name, $helper)) {
if (self::$comparerHelper === null) {
throw new DomainException('The PriceComparer is not set.');
}

return self::$comparerHelper->$name(...$arguments);
}

throw new BadMethodCallException('Method ' . $name . ' does not exist.');
}
}
50 changes: 50 additions & 0 deletions src/Contracts/PriceCalculatorHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace MiBo\Prices\Contracts;

/**
* Interface PriceCalculatorHelper
*
* @package MiBo\Prices\Contracts
*
* @author Michal Boris <[email protected]>
*
* @since 1.2
*
* @no-named-arguments Parameter names are not covered by the backward compatibility promise.
*/
interface PriceCalculatorHelper
{
/**
* Rounds the price.
*
* @param \MiBo\Prices\Contracts\PriceInterface $price Price to round.
* @param int $precision Precision of the rounding.
* @param int<1, 4> $mode Rounding mode.
*
* @return array<string, int|float> Rounded prices for each VAT category.
*/
public function round(PriceInterface $price, int $precision = 0, int $mode = PHP_ROUND_HALF_UP): array;

/**
* Rounds the price up.
*
* @param \MiBo\Prices\Contracts\PriceInterface $price Price to round.
* @param int $precision Precision of the rounding.
*
* @return array<string, int|float> Rounded prices for each VAT category.
*/
public function ceil(PriceInterface $price, int $precision = 0): array;

/**
* Rounds the price down.
*
* @param \MiBo\Prices\Contracts\PriceInterface $price Price to round.
* @param int $precision Precision of the rounding.
*
* @return array<string, int|float> Rounded prices for each VAT category.
*/
public function floor(PriceInterface $price, int $precision = 0): array;
}
84 changes: 84 additions & 0 deletions src/Contracts/PriceComparer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

declare(strict_types=1);

namespace MiBo\Prices\Contracts;

use MiBo\Prices\Price;
use MiBo\Properties\Contracts\NumericalProperty;

/**
* Class PriceComparer
*
* @package MiBo\Prices\Contracts
*
* @author Michal Boris <[email protected]>
*
* @since 1.2
*
* @no-named-arguments Parameter names are not covered by the backward compatibility promise.
*/
interface PriceComparer
{
public function checkThat(PriceInterface $price): static;

public function isLessThan(PriceInterface|int|float $price): bool;

public function isNotLessThan(PriceInterface|int|float $price): bool;

public function isLessThanOrEqualTo(PriceInterface|int|float $price): bool;

public function isNotLessThanOrEqualTo(PriceInterface|int|float $price): bool;

public function isGreaterThan(PriceInterface|int|float $price): bool;

public function isNotGreaterThan(PriceInterface|int|float $price): bool;

public function isGreaterThanOrEqualTo(PriceInterface|int|float $price): bool;

public function isNotGreaterThanOrEqualTo(PriceInterface|int|float $price): bool;

public function isEqualTo(PriceInterface|int|float $price): bool;

public function isNotEqualTo(PriceInterface|int|float $price): bool;

public function isBetween(PriceInterface|int|float $first, PriceInterface|int|float $second): bool;

public function isNotBetween(PriceInterface|int|float $first, PriceInterface|int|float $second): bool;

public function isBetweenOrEqualTo(PriceInterface|int|float $first, PriceInterface|int|float $second): bool;

public function isNotBetweenOrEqualTo(PriceInterface|int|float $first, PriceInterface|int|float $second): bool;

public function isInteger(): bool;

public function isNotInteger(): bool;

public function isFloat(): bool;

public function isNotFloat(): bool;

public function isEven(): bool;

public function isNotEven(): bool;

public function isOdd(): bool;

public function isNotOdd(): bool;

public function hasSameValueAs(NumericalProperty|int|float $price): bool;

public function hasNotSameValueAs(NumericalProperty|int|float $price): bool;

public function hasSameValueWithVATAs(NumericalProperty|int|float $price): bool;

public function hasNotSameValueWithVATAs(NumericalProperty|int|float $price): bool;

public function isWithVATEqualTo(PriceInterface|int|float $price): bool;

public function isWithVATNotEqualTo(PriceInterface|int|float $price): bool;

public function is(PriceInterface $price, bool $strict = false): bool;

public function isNot(PriceInterface $price, bool $strict = false): bool;
}
Loading

0 comments on commit 8d3f13a

Please sign in to comment.