Merge pull request #47 from GoteoFoundation/fix/state_stack
[fix] State stack and data mappings
This commit is contained in:
@@ -10,6 +10,9 @@ jobs:
|
||||
phpunit:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
STRIPE_API_KEY: ${{ secrets.STRIPE_API_KEY }}
|
||||
|
||||
services:
|
||||
mariadb:
|
||||
image: mariadb:10.11.2
|
||||
@@ -25,8 +28,6 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: php-actions/composer@v6
|
||||
env:
|
||||
STRIPE_API_KEY: ${{ secrets.STRIPE_API_KEY }}
|
||||
with:
|
||||
php_version: ${{ env.PHP_VERSION }}
|
||||
php_extensions: ${{ env.PHP_EXTENSIONS }}
|
||||
|
||||
@@ -20,6 +20,8 @@ services:
|
||||
tags: ['app.lib.economy.currency.exchange']
|
||||
AutoMapper\Provider\ProviderInterface:
|
||||
tags: ['app.mapping.map_provider']
|
||||
AutoMapper\Transformer\PropertyTransformer\PropertyTransformerInterface:
|
||||
tags: ['app.mapping.map_transformer']
|
||||
|
||||
# makes classes in src/ available to be used as services
|
||||
# this creates a service per class whose id is the fully-qualified class name
|
||||
@@ -71,6 +73,7 @@ services:
|
||||
arguments:
|
||||
- '%kernel.cache_dir%'
|
||||
- !tagged 'app.mapping.map_provider'
|
||||
- !tagged 'app.mapping.map_transformer'
|
||||
|
||||
# add more service definitions when explicit configuration is needed
|
||||
# please note that last definitions always *replace* previous ones
|
||||
|
||||
@@ -11,8 +11,10 @@ use App\Entity\Money;
|
||||
use App\Entity\Project\Project;
|
||||
use App\Entity\Tipjar;
|
||||
use App\Entity\User\User;
|
||||
use App\Mapping\Transformer\AccountingBalanceMapTransformer;
|
||||
use App\State\Accounting\AccountingStateProcessor;
|
||||
use App\State\Accounting\AccountingStateProvider;
|
||||
use AutoMapper\Attribute\MapFrom;
|
||||
|
||||
/**
|
||||
* v4 features an advanced economy model under the hood.
|
||||
@@ -41,18 +43,15 @@ class AccountingApiResource
|
||||
*/
|
||||
public string $currency;
|
||||
|
||||
/**
|
||||
* The money currently held by the Accounting.
|
||||
*/
|
||||
#[MapFrom(Accounting::class, transformer: AccountingBalanceMapTransformer::class)]
|
||||
public Money $balance;
|
||||
|
||||
#[API\ApiProperty(readable: false, writable: false)]
|
||||
public string $ownerClass;
|
||||
|
||||
#[API\ApiProperty(readable: false, writable: false)]
|
||||
public ?UserApiResource $user = null;
|
||||
|
||||
#[API\ApiProperty(readable: false, writable: false)]
|
||||
public ?ProjectApiResource $project = null;
|
||||
|
||||
#[API\ApiProperty(readable: false, writable: false)]
|
||||
public ?Tipjar $tipjar = null;
|
||||
|
||||
/**
|
||||
* The resource owning this Accounting.
|
||||
*
|
||||
@@ -70,8 +69,12 @@ class AccountingApiResource
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The money currently held by the Accounting.
|
||||
*/
|
||||
public Money $balance;
|
||||
#[API\ApiProperty(readable: false, writable: false)]
|
||||
public ?UserApiResource $user = null;
|
||||
|
||||
#[API\ApiProperty(readable: false, writable: false)]
|
||||
public ?ProjectApiResource $project = null;
|
||||
|
||||
#[API\ApiProperty(readable: false, writable: false)]
|
||||
public ?Tipjar $tipjar = null;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,11 @@ use App\Entity\Gateway\Checkout;
|
||||
use App\Gateway\CheckoutStatus;
|
||||
use App\Gateway\Link;
|
||||
use App\Gateway\Tracking;
|
||||
use App\Mapping\Transformer\GatewayNameMapTransformer;
|
||||
use App\State\ApiResourceStateProvider;
|
||||
use App\State\Gateway\CheckoutStateProcessor;
|
||||
use AutoMapper\Attribute\MapFrom;
|
||||
use AutoMapper\Attribute\MapTo;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
@@ -35,6 +37,8 @@ class CheckoutApiResource
|
||||
* The desired Gateway to checkout with.
|
||||
*/
|
||||
#[Assert\NotBlank()]
|
||||
#[MapFrom(property: 'gatewayName', transformer: GatewayNameMapTransformer::class)]
|
||||
#[MapTo(property: 'gatewayName', transformer: 'source.gateway.name')]
|
||||
public GatewayApiResource $gateway;
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,7 +51,7 @@ class Charge
|
||||
* The Accounting receiving the consequent Transaction for this GatewayCharge.
|
||||
*/
|
||||
#[Assert\NotBlank()]
|
||||
#[ORM\ManyToOne]
|
||||
#[ORM\ManyToOne(cascade: ['persist'])]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private ?Accounting $target = null;
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class Checkout
|
||||
* The Accounting that will issue the Transactions of the GatewayCharges after a successful checkout.
|
||||
*/
|
||||
#[Assert\NotBlank()]
|
||||
#[ORM\ManyToOne]
|
||||
#[ORM\ManyToOne(cascade: ['persist'])]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private ?Accounting $origin = null;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace App\Gateway\Stripe;
|
||||
|
||||
use ApiPlatform\Api\IriConverterInterface;
|
||||
use App\Entity\Gateway\Checkout;
|
||||
use App\Entity\User;
|
||||
use App\Entity\User\User;
|
||||
use App\Gateway\ChargeType;
|
||||
use App\Gateway\CheckoutStatus;
|
||||
use App\Gateway\GatewayInterface;
|
||||
@@ -136,7 +136,10 @@ class StripeGateway implements GatewayInterface
|
||||
{
|
||||
$owner = $checkout->getOrigin()->getOwner();
|
||||
if (!$owner instanceof User) {
|
||||
return '';
|
||||
throw new \Exception(\sprintf(
|
||||
"Checkout with Stripe must be performed by an User, instance of '%s' supplied",
|
||||
$owner::class
|
||||
));
|
||||
}
|
||||
|
||||
return $owner->getEmail();
|
||||
|
||||
@@ -18,10 +18,12 @@ class AutoMapper implements AutoMapperInterface
|
||||
public function __construct(
|
||||
?string $cacheDirectory = null,
|
||||
iterable $mapProviders = [],
|
||||
iterable $mapTransformers = [],
|
||||
) {
|
||||
$this->innerMapper = InnerMapper::create(
|
||||
cacheDirectory: \sprintf('%s%s%s', $cacheDirectory, \DIRECTORY_SEPARATOR, self::CACHE_DIR),
|
||||
providers: $mapProviders,
|
||||
propertyTransformers: $mapTransformers,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Mapping\Transformer;
|
||||
|
||||
use App\Entity\Accounting\Accounting;
|
||||
use App\Service\AccountingService;
|
||||
use AutoMapper\Transformer\PropertyTransformer\PropertyTransformerInterface;
|
||||
|
||||
class AccountingBalanceMapTransformer implements PropertyTransformerInterface
|
||||
{
|
||||
public function __construct(
|
||||
private AccountingService $accountingService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @param Accounting $source
|
||||
*/
|
||||
public function transform(mixed $value, object|array $source, array $context): mixed
|
||||
{
|
||||
return $this->accountingService->calcBalance($source);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Mapping\Transformer;
|
||||
|
||||
use App\ApiResource\Gateway\GatewayApiResource;
|
||||
use App\Gateway\GatewayLocator;
|
||||
use AutoMapper\Transformer\PropertyTransformer\PropertyTransformerInterface;
|
||||
|
||||
class GatewayNameMapTransformer implements PropertyTransformerInterface
|
||||
{
|
||||
public function __construct(
|
||||
private GatewayLocator $gatewayLocator,
|
||||
) {}
|
||||
|
||||
public function transform(mixed $value, object|array $source, array $context): mixed
|
||||
{
|
||||
$gateway = $this->gatewayLocator->get($value);
|
||||
|
||||
$resource = new GatewayApiResource();
|
||||
$resource->name = $gateway::getName();
|
||||
$resource->supports = $gateway::getSupportedChargeTypes();
|
||||
|
||||
return $resource;
|
||||
}
|
||||
}
|
||||
@@ -10,12 +10,6 @@ use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\Pagination\TraversablePaginator;
|
||||
use ApiPlatform\State\ProviderInterface;
|
||||
use App\ApiResource\Accounting\AccountingApiResource;
|
||||
use App\ApiResource\Project\ProjectApiResource;
|
||||
use App\ApiResource\User\UserApiResource;
|
||||
use App\Entity\Accounting\Accounting;
|
||||
use App\Entity\Project\Project;
|
||||
use App\Entity\Tipjar;
|
||||
use App\Entity\User\User;
|
||||
use App\Mapping\AutoMapper;
|
||||
use App\Service\AccountingService;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
@@ -39,7 +33,7 @@ class AccountingStateProvider implements ProviderInterface
|
||||
|
||||
$resources = [];
|
||||
foreach ($accountings as $accounting) {
|
||||
$resources[] = $this->toResource($accounting);
|
||||
$resources[] = $this->autoMapper->map($accounting, AccountingApiResource::class);
|
||||
}
|
||||
|
||||
return new TraversablePaginator(
|
||||
@@ -56,30 +50,6 @@ class AccountingStateProvider implements ProviderInterface
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->toResource($accounting);
|
||||
}
|
||||
|
||||
private function toResource(Accounting $accounting): AccountingApiResource
|
||||
{
|
||||
/** @var AccountingApiResource */
|
||||
$resource = $this->autoMapper->map($accounting, AccountingApiResource::class);
|
||||
$resource->balance = $this->accountingService->calcBalance($accounting);
|
||||
|
||||
$owner = $accounting->getOwner();
|
||||
|
||||
switch ($owner::class) {
|
||||
case User::class:
|
||||
$resourceClass = UserApiResource::class;
|
||||
break;
|
||||
case Project::class:
|
||||
$resourceClass = ProjectApiResource::class;
|
||||
break;
|
||||
case Tipjar::class:
|
||||
$resourceClass = Tipjar::class;
|
||||
}
|
||||
|
||||
$resource->owner = $this->autoMapper->map($owner, $resourceClass);
|
||||
|
||||
return $resource;
|
||||
return $this->autoMapper->map($accounting, AccountingApiResource::class);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user