Skip to content

Commit 6ae9d3c

Browse files
authored
Merge pull request #93 from VadymHrechukha/HP-1751_create_configurations_for_billing_types
HP-1751 Create configurations for billing types
2 parents 6252806 + 48f501d commit 6ae9d3c

File tree

61 files changed

+1815
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1815
-5
lines changed

.github/workflows/behat-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
name: PHP ${{ matrix.php }}
1717
steps:
1818
- name: Checkout
19-
uses: actions/checkout@v2
19+
uses: actions/checkout@v4
2020

2121
- name: Install PHP
2222
uses: shivammathur/setup-php@v2
@@ -28,7 +28,7 @@ jobs:
2828

2929
- name: Cache Composer packages
3030
id: composer-cache
31-
uses: actions/cache@v2
31+
uses: actions/cache@v4
3232
with:
3333
path: vendor
3434
key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}

.github/workflows/phpunit-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
name: PHP ${{ matrix.php }}
1717
steps:
1818
- name: Checkout
19-
uses: actions/checkout@v2
19+
uses: actions/checkout@v4
2020

2121
- name: Install PHP
2222
uses: shivammathur/setup-php@v2
@@ -28,7 +28,7 @@ jobs:
2828

2929
- name: Cache Composer packages
3030
id: composer-cache
31-
uses: actions/cache@v2
31+
uses: actions/cache@v4
3232
with:
3333
path: vendor
3434
key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}

composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@
6161
"hiqdev/hidev-hiqdev": "dev-master",
6262
"hiqdev/php-data-mapper": "dev-master",
6363
"vimeo/psalm": "^5.0",
64+
"opis/closure": "3.x-dev as 3.6.x-dev",
6465
"cache/array-adapter": "*",
65-
"matthiasnoback/behat-expect-exception": "^v0.3.0"
66+
"matthiasnoback/behat-expect-exception": "^v0.3.0",
67+
"behat/gherkin": "~v4.11.0"
6668
},
6769
"suggest": {
6870
"ext-intl": "intl extension is required for formula support",

src/Exception/LogicException.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace hiqdev\php\billing\Exception;
4+
5+
class LogicException extends \LogicException
6+
{
7+
8+
}

src/product/AggregateInterface.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace hiqdev\php\billing\product;
4+
5+
interface AggregateInterface
6+
{
7+
public function isMax(): bool;
8+
}

src/product/BillingRegistry.php

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace hiqdev\php\billing\product;
4+
5+
use hiqdev\php\billing\product\behavior\InvalidBehaviorException;
6+
use hiqdev\php\billing\product\Exception\AggregateNotFoundException;
7+
use hiqdev\php\billing\product\invoice\InvalidRepresentationException;
8+
use hiqdev\php\billing\product\invoice\RepresentationInterface;
9+
use hiqdev\php\billing\product\price\PriceTypeDefinition;
10+
use hiqdev\php\billing\product\quantity\QuantityFormatterInterface;
11+
use hiqdev\php\billing\product\quantity\QuantityFormatterNotFoundException;
12+
use hiqdev\php\billing\product\quantity\FractionQuantityData;
13+
use hiqdev\php\billing\product\behavior\BehaviorInterface;
14+
use hiqdev\php\billing\product\behavior\BehaviorNotFoundException;
15+
use hiqdev\php\billing\product\trait\HasLock;
16+
use hiqdev\php\billing\type\Type;
17+
use hiqdev\php\billing\type\TypeInterface;
18+
19+
class BillingRegistry implements BillingRegistryInterface
20+
{
21+
use HasLock;
22+
23+
/** @var TariffTypeDefinitionInterface[] */
24+
private array $tariffTypeDefinitions = [];
25+
private bool $locked = false;
26+
27+
public function addTariffType(TariffTypeDefinitionInterface $tariffTypeDefinition): void
28+
{
29+
$this->ensureNotLocked();
30+
31+
$this->tariffTypeDefinitions[] = $tariffTypeDefinition;
32+
}
33+
34+
public function priceTypes(): \Generator
35+
{
36+
foreach ($this->tariffTypeDefinitions as $tariffTypeDefinition) {
37+
foreach ($tariffTypeDefinition->withPrices() as $priceTypeDefinition) {
38+
yield $priceTypeDefinition;
39+
}
40+
}
41+
}
42+
43+
public function getRepresentationsByType(string $representationClass): array
44+
{
45+
if (!class_exists($representationClass)) {
46+
throw new InvalidRepresentationException("Class '$representationClass' does not exist");
47+
}
48+
49+
if (!is_subclass_of($representationClass, RepresentationInterface::class)) {
50+
throw new InvalidBehaviorException(
51+
sprintf('Representation class "%s" does not implement RepresentationInterface', $representationClass)
52+
);
53+
}
54+
55+
$representations = [];
56+
foreach ($this->priceTypes() as $priceTypeDefinition) {
57+
foreach ($priceTypeDefinition->documentRepresentation() as $representation) {
58+
if ($representation instanceof $representationClass) {
59+
$representations[] = $representation;
60+
}
61+
}
62+
}
63+
64+
return $representations;
65+
}
66+
67+
public function createQuantityFormatter(
68+
string $type,
69+
FractionQuantityData $data,
70+
): QuantityFormatterInterface {
71+
$type = $this->convertStringTypeToType($type);
72+
73+
foreach ($this->priceTypes() as $priceTypeDefinition) {
74+
if ($priceTypeDefinition->hasType($type)) {
75+
return $priceTypeDefinition->createQuantityFormatter($data);
76+
}
77+
}
78+
79+
throw new QuantityFormatterNotFoundException('Quantity formatter not found');
80+
}
81+
82+
private function convertStringTypeToType(string $type): TypeInterface
83+
{
84+
return Type::anyId($type);
85+
}
86+
87+
public function getBehavior(string $type, string $behaviorClassWrapper): BehaviorInterface
88+
{
89+
if (!class_exists($behaviorClassWrapper)) {
90+
throw new InvalidBehaviorException(
91+
sprintf('Behavior class "%s" does not exist', $behaviorClassWrapper)
92+
);
93+
}
94+
95+
if (!is_subclass_of($behaviorClassWrapper, BehaviorInterface::class)) {
96+
throw new InvalidBehaviorException(
97+
sprintf('Behavior class "%s" does not implement BehaviorInterface', $behaviorClassWrapper)
98+
);
99+
}
100+
101+
$billingType = $this->convertStringTypeToType($type);
102+
103+
foreach ($this->priceTypes() as $priceTypeDefinition) {
104+
if ($priceTypeDefinition->hasType($billingType)) {
105+
$behavior = $this->findBehaviorInPriceType($priceTypeDefinition, $behaviorClassWrapper);
106+
107+
if ($behavior) {
108+
return $behavior;
109+
}
110+
}
111+
}
112+
113+
throw new BehaviorNotFoundException(
114+
sprintf('Behavior of class "%s" not found for type "%s"', $behaviorClassWrapper, $type),
115+
);
116+
}
117+
118+
private function findBehaviorInPriceType(
119+
PriceTypeDefinition $priceTypeDefinition,
120+
string $behaviorClassWrapper
121+
): ?BehaviorInterface {
122+
foreach ($priceTypeDefinition->withBehaviors() as $behavior) {
123+
if ($behavior instanceof $behaviorClassWrapper) {
124+
return $behavior;
125+
}
126+
}
127+
128+
return null;
129+
}
130+
131+
public function getBehaviors(string $behaviorClassWrapper): \Generator
132+
{
133+
foreach ($this->tariffTypeDefinitions as $tariffTypeDefinition) {
134+
foreach ($tariffTypeDefinition->withBehaviors() as $behavior) {
135+
if ($behavior instanceof $behaviorClassWrapper) {
136+
yield $behavior;
137+
}
138+
}
139+
}
140+
141+
foreach ($this->priceTypes() as $priceTypeDefinition) {
142+
foreach ($priceTypeDefinition->withBehaviors() as $behavior) {
143+
if ($behavior instanceof $behaviorClassWrapper) {
144+
yield $behavior;
145+
}
146+
}
147+
}
148+
}
149+
150+
public function getAggregate(string $type): AggregateInterface
151+
{
152+
$type = $this->convertStringTypeToType($type);
153+
154+
foreach ($this->priceTypes() as $priceTypeDefinition) {
155+
if ($priceTypeDefinition->hasType($type)) {
156+
return $priceTypeDefinition->getAggregate();
157+
}
158+
}
159+
160+
throw new AggregateNotFoundException('Aggregate was not found');
161+
}
162+
163+
public function getTariffTypeDefinitions(): \Generator
164+
{
165+
foreach ($this->tariffTypeDefinitions as $tariffTypeDefinition) {
166+
yield $tariffTypeDefinition;
167+
}
168+
}
169+
170+
protected function afterLock(): void
171+
{
172+
$this->lockItems($this->tariffTypeDefinitions);
173+
}
174+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace hiqdev\php\billing\product;
4+
5+
use Generator;
6+
use hiqdev\php\billing\product\behavior\BehaviorInterface;
7+
use hiqdev\php\billing\product\behavior\BehaviorNotFoundException;
8+
use hiqdev\php\billing\product\behavior\InvalidBehaviorException;
9+
use hiqdev\php\billing\product\invoice\RepresentationInterface;
10+
use hiqdev\php\billing\product\price\PriceTypeDefinitionInterface;
11+
use hiqdev\php\billing\product\quantity\FractionQuantityData;
12+
use hiqdev\php\billing\product\quantity\QuantityFormatterInterface;
13+
use hiqdev\php\billing\product\trait\HasLockInterface;
14+
15+
interface BillingRegistryInterface extends HasLockInterface
16+
{
17+
/**
18+
* @return Generator
19+
* @psalm-return Generator<PriceTypeDefinitionInterface>
20+
*/
21+
public function priceTypes(): Generator;
22+
23+
public function addTariffType(TariffTypeDefinitionInterface $tariffTypeDefinition): void;
24+
25+
/**
26+
* @param string $representationClass
27+
* @return RepresentationInterface[]
28+
*/
29+
public function getRepresentationsByType(string $representationClass): array;
30+
31+
public function createQuantityFormatter(string $type, FractionQuantityData $data): QuantityFormatterInterface;
32+
33+
/**
34+
* @param string $type - full type like 'overuse,lb_capacity_unit'
35+
* @param string $behaviorClassWrapper
36+
* @return BehaviorInterface
37+
* @throws BehaviorNotFoundException
38+
* @throws InvalidBehaviorException
39+
*/
40+
public function getBehavior(string $type, string $behaviorClassWrapper): BehaviorInterface;
41+
42+
/**
43+
* @param string $behaviorClassWrapper
44+
* @return Generator
45+
* @psalm-return Generator<BehaviorInterface>
46+
*/
47+
public function getBehaviors(string $behaviorClassWrapper): Generator;
48+
49+
public function getAggregate(string $type): AggregateInterface;
50+
51+
/**
52+
* @return Generator
53+
* @psalm-return Generator<TariffTypeDefinitionInterface>
54+
*/
55+
public function getTariffTypeDefinitions(): Generator;
56+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace hiqdev\php\billing\product;
4+
5+
interface DocumentRepresentationInterface
6+
{
7+
8+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace hiqdev\php\billing\product\Domain\Model;
4+
5+
interface TariffTypeInterface
6+
{
7+
public function name(): string;
8+
9+
public function label(): string;
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace hiqdev\php\billing\product\Domain\Model\Unit;
4+
5+
interface FractionUnitInterface
6+
{
7+
8+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace hiqdev\php\billing\product\Domain\Model\Unit;
4+
5+
use \hiqdev\php\units\UnitInterface as BaseUnitInterface;
6+
7+
interface UnitInterface
8+
{
9+
public function createExternalUnit(): BaseUnitInterface;
10+
11+
public function fractionUnit(): FractionUnitInterface;
12+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace hiqdev\php\billing\product\Exception;
4+
5+
use hiqdev\php\billing\Exception\LogicException;
6+
7+
class AggregateNotDefinedException extends LogicException
8+
{
9+
10+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace hiqdev\php\billing\product\Exception;
4+
5+
use hiqdev\php\billing\Exception\RuntimeException;
6+
7+
class AggregateNotFoundException extends RuntimeException
8+
{
9+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace hiqdev\php\billing\product\Exception;
4+
5+
use LogicException;
6+
7+
class LockedException extends LogicException
8+
{
9+
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace hiqdev\php\billing\product\Exception;
4+
5+
use hiqdev\php\billing\Exception\LogicException;
6+
7+
class ProductNotDefinedException extends LogicException
8+
{
9+
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace hiqdev\php\billing\product\Exception;
4+
5+
use hiqdev\php\billing\Exception\RuntimeException;
6+
7+
class TariffTypeDefinitionNotFoundException extends RuntimeException
8+
{
9+
10+
}

0 commit comments

Comments
 (0)