Skip to content

HP-2419 extended functional of BillingRegistry for easier use #99

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

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a9e3868
HP-2419 extended functional of BillingRegistry for easier use
VadymHrechukha May 6, 2025
055c135
HP-2419 extended functional of BillingRegistry for easier use
VadymHrechukha May 6, 2025
02f0958
HP-2419 tiny
VadymHrechukha May 7, 2025
d7937d3
HP-2419 tiny
VadymHrechukha May 7, 2025
8fad103
HP-2419 tiny
VadymHrechukha May 7, 2025
d993cd0
HP-2419 tiny
VadymHrechukha May 7, 2025
405f064
HP-2419 tiny
VadymHrechukha May 7, 2025
d7b0e2a
HP-2419 tiny
VadymHrechukha May 7, 2025
f48a47a
HP-2419 tiny
VadymHrechukha May 7, 2025
3cf9e05
HP-2419 fixing Psalm error
VadymHrechukha May 7, 2025
f062de0
HP-2419 removed dependency between php-billing and BillingRegistry pa…
VadymHrechukha May 7, 2025
be55965
HP-2419 created TrafCollectorInterface
VadymHrechukha May 7, 2025
0856451
HP-2419 fixing PHPUnit tests
VadymHrechukha May 7, 2025
167436f
HP-2419 fixing PHPUnit tests
VadymHrechukha May 7, 2025
27bec10
HP-2419 implemented Service for BillingRegistry and allow client code…
VadymHrechukha May 7, 2025
8eba047
HP-2419 Created PHPUnit test for BillingRegistryService
VadymHrechukha May 7, 2025
254739f
HP-2419 fixing scrutinizer
VadymHrechukha May 14, 2025
47af1db
HP-2419 fixing scrutinizer
VadymHrechukha May 14, 2025
964147f
HP-2419 fixing scrutinizer
VadymHrechukha May 14, 2025
b92bf22
HP-2419 fixing scrutinizer
VadymHrechukha May 14, 2025
e39a529
HP-2419 fixing scrutinizer
VadymHrechukha May 14, 2025
a699807
HP-2419 fixing scrutinizer
VadymHrechukha May 14, 2025
e6ad068
HP-2419 fixing scrutinizer
VadymHrechukha May 14, 2025
dea56cf
HP-2419 exclude vendor and tests from scrutinizer
VadymHrechukha May 14, 2025
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
139 changes: 27 additions & 112 deletions src/product/BillingRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,24 @@

namespace hiqdev\php\billing\product;

use hiqdev\php\billing\product\behavior\InvalidBehaviorException;
use hiqdev\php\billing\product\Exception\AggregateNotFoundException;
use hiqdev\php\billing\product\invoice\InvalidRepresentationException;
use hiqdev\php\billing\product\invoice\RepresentationInterface;
use hiqdev\php\billing\product\price\PriceTypeDefinition;
use hiqdev\php\billing\product\quantity\QuantityFormatterInterface;
use hiqdev\php\billing\product\quantity\QuantityFormatterNotFoundException;
use hiqdev\php\billing\product\quantity\FractionQuantityData;
use hiqdev\php\billing\product\behavior\BehaviorInterface;
use hiqdev\php\billing\product\behavior\BehaviorNotFoundException;
use hiqdev\php\billing\product\trait\HasLock;
use hiqdev\php\billing\type\Type;
use hiqdev\php\billing\type\TypeInterface;

class BillingRegistry implements BillingRegistryInterface
{
use HasLock;

/** @var TariffTypeDefinitionInterface[] */
private array $tariffTypeDefinitions = [];
private bool $locked = false;

private BillingRegistryService $service;

public function __construct()
{
$this->service = new BillingRegistryService($this);
}

public function addTariffType(TariffTypeDefinitionInterface $tariffTypeDefinition): void
{
Expand All @@ -31,9 +28,14 @@ public function addTariffType(TariffTypeDefinitionInterface $tariffTypeDefinitio
$this->tariffTypeDefinitions[] = $tariffTypeDefinition;
}

public function getTariffTypeDefinitions(): array
{
return $this->tariffTypeDefinitions;
}

public function priceTypes(): \Generator
{
foreach ($this->tariffTypeDefinitions as $tariffTypeDefinition) {
foreach ($this->getTariffTypeDefinitions() as $tariffTypeDefinition) {
foreach ($tariffTypeDefinition->withPrices() as $priceTypeDefinition) {
yield $priceTypeDefinition;
}
Expand All @@ -42,129 +44,42 @@ public function priceTypes(): \Generator

public function getRepresentationsByType(string $representationClass): array
{
if (!class_exists($representationClass)) {
throw new InvalidRepresentationException("Class '$representationClass' does not exist");
}

if (!is_subclass_of($representationClass, RepresentationInterface::class)) {
throw new InvalidBehaviorException(
sprintf('Representation class "%s" does not implement RepresentationInterface', $representationClass)
);
}

$representations = [];
foreach ($this->priceTypes() as $priceTypeDefinition) {
foreach ($priceTypeDefinition->documentRepresentation() as $representation) {
if ($representation instanceof $representationClass) {
$representations[] = $representation;
}
}
}

return $representations;
return $this->service->getRepresentationsByType($representationClass);
}

public function createQuantityFormatter(
string $type,
FractionQuantityData $data,
): QuantityFormatterInterface {
$type = $this->convertStringTypeToType($type);

foreach ($this->priceTypes() as $priceTypeDefinition) {
if ($priceTypeDefinition->hasType($type)) {
return $priceTypeDefinition->createQuantityFormatter($data);
}
}

throw new QuantityFormatterNotFoundException('Quantity formatter not found');
}

private function convertStringTypeToType(string $type): TypeInterface
{
return Type::anyId($type);
return $this->service->createQuantityFormatter($type, $data);
}

public function getBehavior(string $type, string $behaviorClassWrapper): BehaviorInterface
{
if (!class_exists($behaviorClassWrapper)) {
throw new InvalidBehaviorException(
sprintf('Behavior class "%s" does not exist', $behaviorClassWrapper)
);
}

if (!is_subclass_of($behaviorClassWrapper, BehaviorInterface::class)) {
throw new InvalidBehaviorException(
sprintf('Behavior class "%s" does not implement BehaviorInterface', $behaviorClassWrapper)
);
}

$billingType = $this->convertStringTypeToType($type);

foreach ($this->priceTypes() as $priceTypeDefinition) {
if ($priceTypeDefinition->hasType($billingType)) {
$behavior = $this->findBehaviorInPriceType($priceTypeDefinition, $behaviorClassWrapper);

if ($behavior) {
return $behavior;
}
}
}

throw new BehaviorNotFoundException(
sprintf('Behavior of class "%s" not found for type "%s"', $behaviorClassWrapper, $type),
);
}

private function findBehaviorInPriceType(
PriceTypeDefinition $priceTypeDefinition,
string $behaviorClassWrapper
): ?BehaviorInterface {
foreach ($priceTypeDefinition->withBehaviors() as $behavior) {
if ($behavior instanceof $behaviorClassWrapper) {
return $behavior;
}
}

return null;
return $this->service->getBehavior($type, $behaviorClassWrapper);
}

/**
* @inerhitDoc
*/
public function getBehaviors(string $behaviorClassWrapper): \Generator
{
foreach ($this->tariffTypeDefinitions as $tariffTypeDefinition) {
foreach ($tariffTypeDefinition->withBehaviors() as $behavior) {
if ($behavior instanceof $behaviorClassWrapper) {
yield $behavior;
}
}
}

foreach ($this->priceTypes() as $priceTypeDefinition) {
foreach ($priceTypeDefinition->withBehaviors() as $behavior) {
if ($behavior instanceof $behaviorClassWrapper) {
yield $behavior;
}
}
}
return $this->service->getBehaviors($behaviorClassWrapper);
}

public function getAggregate(string $type): AggregateInterface
{
$type = $this->convertStringTypeToType($type);

foreach ($this->priceTypes() as $priceTypeDefinition) {
if ($priceTypeDefinition->hasType($type)) {
return $priceTypeDefinition->getAggregate();
}
}
return $this->service->getAggregate($type);
}

throw new AggregateNotFoundException('Aggregate was not found');
public function findTariffTypeDefinitionByBehavior(BehaviorInterface $behavior): TariffTypeDefinitionInterface
{
return $this->service->findTariffTypeDefinitionByBehavior($behavior);
}

public function getTariffTypeDefinitions(): \Generator
public function findPriceTypeDefinitionsByBehavior(string $behaviorClassWrapper): \Generator
{
foreach ($this->tariffTypeDefinitions as $tariffTypeDefinition) {
yield $tariffTypeDefinition;
}
return $this->service->findPriceTypeDefinitionsByBehavior($behaviorClassWrapper);
}

protected function afterLock(): void
Expand Down
22 changes: 14 additions & 8 deletions src/product/BillingRegistryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
interface BillingRegistryInterface extends HasLockInterface
{
/**
* @return Generator
* @psalm-return Generator<PriceTypeDefinitionInterface>
* @return Generator<PriceTypeDefinitionInterface>
*/
public function priceTypes(): Generator;

public function getTariffTypeDefinitions(): array;

public function addTariffType(TariffTypeDefinitionInterface $tariffTypeDefinition): void;

/**
Expand All @@ -40,17 +41,22 @@ public function createQuantityFormatter(string $type, FractionQuantityData $data
public function getBehavior(string $type, string $behaviorClassWrapper): BehaviorInterface;

/**
* Find all behaviors attached to any TariffType or PriceType by specified Behavior class.
*
* @param string $behaviorClassWrapper
* @return Generator
* @psalm-return Generator<BehaviorInterface>
* @return Generator<BehaviorInterface>
*/
public function getBehaviors(string $behaviorClassWrapper): Generator;

public function getAggregate(string $type): AggregateInterface;
public function findTariffTypeDefinitionByBehavior(BehaviorInterface $behavior): TariffTypeDefinitionInterface;

/**
* @return Generator
* @psalm-return Generator<TariffTypeDefinitionInterface>
* Find all PriceTypeDefinition in registry by specified Behavior class.
*
* @param string $behaviorClassWrapper
* @return \Generator<PriceTypeDefinitionInterface>
*/
public function getTariffTypeDefinitions(): Generator;
public function findPriceTypeDefinitionsByBehavior(string $behaviorClassWrapper): \Generator;

public function getAggregate(string $type): AggregateInterface;
}
Loading
Loading