Rename MatchStrategy to Matchfunding\Formula

This commit is contained in:
2025-04-21 15:06:37 +02:00
parent debdd5194b
commit fbb80df443
12 changed files with 160 additions and 164 deletions
+4 -4
View File
@@ -16,8 +16,8 @@ services:
tags: ['app.gateway.gateway']
App\Library\Economy\Currency\ExchangeInterface:
tags: ['app.lib.economy.currency.exchange']
App\Matchfunding\MatchStrategy\MatchStrategyInterface:
tags: ['app.matchfunding.strategy.strategy']
App\Matchfunding\Formula\FormulaInterface:
tags: ['app.matchfunding.formula.formula']
App\Service\Embed\Filter\EmbedFilterInterface:
tags: ['app.embed.embed_filter']
App\Service\Embed\Provider\EmbedProviderFactoryInterface:
@@ -61,9 +61,9 @@ services:
- '%env(STRIPE_API_KEY)%'
- '%env(STRIPE_WEBHOOK_SECRET)%'
App\Matchfunding\MatchStrategy\MatchStrategyLocator:
App\Matchfunding\Formula\FormulaLocator:
arguments:
- !tagged 'app.matchfunding.strategy.strategy'
- !tagged 'app.matchfunding.formula.formula'
App\Service\Auth\AuthService:
arguments:
@@ -0,0 +1,22 @@
<?php
namespace App\ApiResource\Matchfunding;
use ApiPlatform\Metadata as API;
use App\State\Matchfunding\FormulaStateProvider;
/**
* A MatchFormula is a predefined code implementation for matching funds in Transactions under a MatchCall.
* MatchFormulas can be chosen by the managers in a MatchCall and their behaviour fine-tuned.
*/
#[API\ApiResource(
shortName: 'MatchFormula',
provider: FormulaStateProvider::class
)]
#[API\GetCollection()]
#[API\Get()]
class FormulaApiResource
{
#[API\ApiProperty(identifier: true, writable: false)]
public string $name;
}
@@ -1,20 +0,0 @@
<?php
namespace App\ApiResource\Matchfunding;
use ApiPlatform\Metadata as API;
use App\State\Matchfunding\MatchStrategyStateProvider;
/**
* A MatchStrategy is a predefined code implementation for matching funds in Transactions under a MatchCall.
* MatchStrategies can be chosen by the managers in a MatchCall and their behaviour fine-tuned.
*/
#[API\ApiResource(
shortName: 'MatchStrategy',
provider: MatchStrategyStateProvider::class
)]
class MatchStrategyApiResource
{
#[API\ApiProperty(identifier: true, writable: false)]
public string $name;
}
@@ -5,7 +5,7 @@ namespace App\EventListener;
use App\Entity\Accounting\Transaction;
use App\Entity\Matchfunding\MatchCallSubmissionStatus;
use App\Entity\Project\Project;
use App\Matchfunding\MatchStrategy\MatchStrategyLocator;
use App\Matchfunding\Formula\FormulaLocator;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
use Doctrine\ORM\Event\PostPersistEventArgs;
use Doctrine\ORM\Events;
@@ -18,7 +18,7 @@ use Doctrine\ORM\Events;
final class MatchfundingTransactionsListener
{
public function __construct(
private MatchStrategyLocator $matchStrategyLocator,
private FormulaLocator $formulaLocator,
) {}
/**
@@ -41,16 +41,16 @@ final class MatchfundingTransactionsListener
continue;
}
$call = $submission->getMatchCall();
$strategy = $this->matchStrategyLocator->getForCall($call);
$match = $strategy->match($transaction);
// $call = $submission->getCall();
// $strategy = $this->formulaLocator->get($call->getFormulaName());
// $match = $strategy->match($transaction->getMoney());
if ($match->getId() !== null) {
return;
}
// if ($match->getId() !== null) {
// return;
// }
$event->getObjectManager()->persist($match);
$event->getObjectManager()->flush();
// $event->getObjectManager()->persist($match);
// $event->getObjectManager()->flush();
}
}
}
@@ -1,22 +1,22 @@
<?php
namespace App\Matchfunding\MatchStrategy\Exception;
namespace App\Matchfunding\Formula\Exception;
class MatchStrategyDuplicatedException extends \Exception
class FormulaDuplicatedException extends \Exception
{
public const DUPLICATED_NAME = "Duplicate MatchStrategy name '%s' by class '%s', value already in use by class '%s'";
public const DUPLICATED_NAME = "Duplicate Formula name '%s' by class '%s', value already in use by class '%s'";
public function __construct(
string $duplicatedName,
string $duplicatedClass,
string $strategyClass,
string $formulaClass,
string $message = self::DUPLICATED_NAME,
) {
parent::__construct(\sprintf(
$message,
$duplicatedName,
$duplicatedClass,
$strategyClass
$formulaClass
));
}
}
@@ -1,10 +1,10 @@
<?php
namespace App\Matchfunding\MatchStrategy\Exception;
namespace App\Matchfunding\Formula\Exception;
class MatchStrategyNotFoundException extends \Exception
class FormulaNotFoundException extends \Exception
{
public const MISSING_NAME = "Could not find a MatchStrategy by the name '%s', value does not exist";
public const MISSING_NAME = "Could not find a Formula by the name '%s', value does not exist";
public function __construct(
string $name,
@@ -0,0 +1,22 @@
<?php
namespace App\Matchfunding\Formula;
use App\Entity\Money;
interface FormulaInterface
{
/**
* A unique name for the formula.
*/
public static function getName(): string;
/**
* Process an input Money and obtain a delta Money, which is the Money to be given by the Matcher.
*
* @param Money $money The Money input that is to be matched
*
* @return Money A Money delta
*/
public function match(Money $money): Money;
}
@@ -0,0 +1,47 @@
<?php
namespace App\Matchfunding\Formula;
use App\Matchfunding\Formula\Exception\FormulaDuplicatedException;
use App\Matchfunding\Formula\Exception\FormulaNotFoundException;
class FormulaLocator
{
/** @var array<string, FormulaInterface> */
private array $strategiesByName = [];
public function __construct(
iterable $strategies,
) {
foreach ($strategies as $Formula) {
$FormulaName = $Formula::getName();
if (\array_key_exists($FormulaName, $this->strategiesByName)) {
throw new FormulaDuplicatedException(
$FormulaName,
$Formula::class,
$this->strategiesByName[$FormulaName]::class
);
}
$this->strategiesByName[$FormulaName] = $Formula;
}
}
/**
* @return array<string, FormulaInterface>
*/
public function getAll(): array
{
return $this->strategiesByName;
}
public function get(string $FormulaName): ?FormulaInterface
{
if (!array_key_exists($FormulaName, $this->strategiesByName)) {
throw new FormulaNotFoundException($FormulaName);
}
return $this->strategiesByName[$FormulaName];
}
}
@@ -1,22 +0,0 @@
<?php
namespace App\Matchfunding\MatchStrategy;
use App\Entity\Accounting\Transaction;
interface MatchStrategyInterface
{
/**
* A unique name for the strategy.
*/
public static function getName(): string;
/**
* Process a Transaction targeting a Matchfunding that uses this strategy.
*
* @param Transaction $transaction The input Transaction that is eligible for matching
*
* @return Transaction A new output Transaction for the matching
*/
public function match(Transaction $transaction): Transaction;
}
@@ -1,53 +0,0 @@
<?php
namespace App\Matchfunding\MatchStrategy;
use App\Entity\Matchfunding\MatchCall;
use App\Matchfunding\MatchStrategy\Exception\MatchStrategyDuplicatedException;
use App\Matchfunding\MatchStrategy\Exception\MatchStrategyNotFoundException;
class MatchStrategyLocator
{
/** @var array<string, MatchStrategyInterface> */
private array $strategiesByName = [];
public function __construct(
iterable $strategies,
) {
foreach ($strategies as $strategy) {
$strategyName = $strategy::getName();
if (\array_key_exists($strategyName, $this->strategiesByName)) {
throw new MatchStrategyDuplicatedException(
$strategyName,
$strategy::class,
$this->strategiesByName[$strategyName]::class
);
}
$this->strategiesByName[$strategyName] = $strategy;
}
}
/**
* @return array<string, MatchStrategyInterface>
*/
public function getAll(): array
{
return $this->strategiesByName;
}
public function get(string $strategyName): ?MatchStrategyInterface
{
if (!array_key_exists($strategyName, $this->strategiesByName)) {
throw new MatchStrategyNotFoundException($strategyName);
}
return $this->strategiesByName[$strategyName];
}
public function getForCall(MatchCall $call): ?MatchStrategyInterface
{
return $this->get($call->getStrategyName());
}
}
@@ -0,0 +1,47 @@
<?php
namespace App\State\Matchfunding;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\ApiResource\Matchfunding\FormulaApiResource;
use App\Matchfunding\Formula\Exception\FormulaNotFoundException;
use App\Matchfunding\Formula\FormulaInterface;
use App\Matchfunding\Formula\FormulaLocator;
class FormulaStateProvider implements ProviderInterface
{
public function __construct(
private FormulaLocator $formulaLocator,
) {}
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
if (\array_key_exists('name', $uriVariables)) {
try {
$formula = $this->formulaLocator->get($uriVariables['name']);
return $this->getApiResource($formula);
} catch (FormulaNotFoundException $e) {
return null;
}
}
$strategies = $this->formulaLocator->getAll();
$resources = [];
foreach ($strategies as $formula) {
$resources[] = $this->getApiResource($formula);
}
return $resources;
}
private function getApiResource(FormulaInterface $formula): FormulaApiResource
{
$resource = new FormulaApiResource();
$resource->name = $formula::getName();
return $resource;
}
}
@@ -1,47 +0,0 @@
<?php
namespace App\State\Matchfunding;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\ApiResource\Matchfunding\MatchStrategyApiResource;
use App\Matchfunding\MatchStrategy\Exception\MatchStrategyNotFoundException;
use App\Matchfunding\MatchStrategy\MatchStrategyInterface;
use App\Matchfunding\MatchStrategy\MatchStrategyLocator;
class MatchStrategyStateProvider implements ProviderInterface
{
public function __construct(
private MatchStrategyLocator $matchStrategyLocator,
) {}
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
if (\array_key_exists('name', $uriVariables)) {
try {
$strategy = $this->matchStrategyLocator->get($uriVariables['name']);
return $this->getApiResource($strategy);
} catch (MatchStrategyNotFoundException $e) {
return null;
}
}
$strategies = $this->matchStrategyLocator->getAll();
$resources = [];
foreach ($strategies as $strategy) {
$resources[] = $this->getApiResource($strategy);
}
return $resources;
}
private function getApiResource(MatchStrategyInterface $strategy): MatchStrategyApiResource
{
$resource = new MatchStrategyApiResource();
$resource->name = $strategy::getName();
return $resource;
}
}