[Admin] Add payment request index and show pages

This commit is contained in:
Wojdylak 2024-09-25 13:42:27 +02:00
parent 859c87a278
commit 2d65680fb0
No known key found for this signature in database
GPG key ID: 7509E560A6821ABE
43 changed files with 376 additions and 12 deletions

View file

@ -124,6 +124,8 @@ twig_hooks:
template: '@SyliusAdmin/order/show/content/sections/payments/item/actions.html.twig'
'sylius_admin.order.show.content.sections.payments.item.actions':
list_payment_requests:
template: '@SyliusAdmin/order/show/content/sections/payments/item/actions/list_payment_requests.html.twig'
complete:
template: '@SyliusAdmin/order/show/content/sections/payments/item/actions/complete.html.twig'
refund:

View file

@ -0,0 +1,5 @@
twig_hooks:
hooks:
'sylius_admin.payment.payment_request.index.content.header':
breadcrumbs:
template: '@SyliusAdmin/payment/payment_request/index/content/header/breadcrumbs.html.twig'

View file

@ -0,0 +1,38 @@
twig_hooks:
hooks:
'sylius_admin.payment.payment_request.show.content':
sections:
template: '@SyliusAdmin/payment/payment_request/show/content/sections.html.twig'
'sylius_admin.payment.payment_request.show.content.header':
breadcrumbs:
template: '@SyliusAdmin/payment/payment_request/show/content/header/breadcrumbs.html.twig'
'sylius_admin.payment.payment_request.show.content.sections':
general:
template: '@SyliusAdmin/payment/payment_request/show/content/sections/general.html.twig'
'sylius_admin.payment.payment_request.show.content.sections#left':
payload:
template: '@SyliusAdmin/payment/payment_request/show/content/sections/payload.html.twig'
'sylius_admin.payment.payment_request.show.content.sections#right':
response_data:
template: '@SyliusAdmin/payment/payment_request/show/content/sections/response_data.html.twig'
'sylius_admin.payment.payment_request.show.content.sections.general':
hash:
template: '@SyliusAdmin/payment/payment_request/show/content/sections/general/hash.html.twig'
method:
template: '@SyliusAdmin/payment/payment_request/show/content/sections/general/method.html.twig'
action:
template: '@SyliusAdmin/payment/payment_request/show/content/sections/general/action.html.twig'
state:
template: '@SyliusAdmin/payment/payment_request/show/content/sections/general/state.html.twig'
created_at:
template: '@SyliusAdmin/payment/payment_request/show/content/sections/general/created_at.html.twig'
updated_at:
template: '@SyliusAdmin/payment/payment_request/show/content/sections/general/updated_at.html.twig'

View file

@ -69,6 +69,15 @@ sylius_grid:
class: "%sylius.model.channel.class%"
actions:
item:
show_payment_requests:
type: show
icon: list_letters
label: sylius.ui.list_payment_requests
options:
link:
route: sylius_admin_payment_payment_request_index
parameters:
id: resource.id
complete:
type: apply_transition
label: sylius.ui.complete

View file

@ -0,0 +1,93 @@
sylius_grid:
grids:
sylius_admin_payment_payment_request:
driver:
name: doctrine/orm
options:
class: "%sylius.model.payment_request.class%"
repository:
method: createForPaymentQueryBuilder
arguments:
paymentId: $id
sorting:
createdAt: desc
fields:
hash:
type: string
label: sylius.ui.hash
sortable: ~
method:
type: twig
label: sylius.ui.payment_method
path: .
options:
template: "@SyliusAdmin/payment/payment_request/grid/field/method.html.twig"
action:
type: twig
label: sylius.ui.action
options:
template: "@SyliusAdmin/payment/payment_request/grid/field/action.html.twig"
state:
type: twig
label: sylius.ui.state
options:
template: "@SyliusAdmin/payment/payment_request/grid/field/state.html.twig"
createdAt:
type: twig
label: sylius.ui.creation_date
sortable: ~
options:
template: "@SyliusAdmin/shared/grid/field/date.html.twig"
vars:
th_class: "w-1 text-center"
updatedAt:
type: twig
label: sylius.ui.updating_date
sortable: ~
options:
template: "@SyliusAdmin/shared/grid/field/date.html.twig"
vars:
th_class: "w-1 text-center"
filters:
payment_method:
type: ux_translatable_autocomplete
label: sylius.ui.payment_method
form_options:
extra_options:
class: "%sylius.model.payment_method.class%"
translation_fields: [ name ]
choice_label: name
options:
fields: [ method.id ]
action:
type: select
label: sylius.ui.action
form_options:
choices:
sylius.ui.authorize: authorize
sylius.ui.cancel: cancel
sylius.ui.capture: capture
sylius.ui.payout: payout
sylius.ui.refund: refund
sylius.ui.status: status
sylius.ui.sync: sync
state:
type: select
label: sylius.ui.state
form_options:
choices:
sylius.ui.cancelled: cancelled
sylius.ui.completed: completed
sylius.ui.failed: failed
sylius.ui.new: new
sylius.ui.processing: processing
actions:
item:
show:
type: show
options:
link:
route: sylius_admin_payment_payment_request_show
parameters:
hash: resource.hash
paymentId: resource.payment.id

View file

@ -27,3 +27,29 @@ sylius_admin_payment_complete:
transition: complete
redirect: sylius_admin_payment_index
flash: sylius.payment.completed
sylius_admin_payment_payment_request_index:
path: /payments/{id}/payment_requests
methods: [GET]
defaults:
_controller: sylius.controller.payment_request::indexAction
_sylius:
section: admin
permission: true
template: "@SyliusAdmin/payment/payment_request/index.html.twig"
grid: sylius_admin_payment_payment_request
sylius_admin_payment_payment_request_show:
path: /payments/{paymentId}/payment_requests/{hash}
methods: [GET]
defaults:
_controller: sylius.controller.payment_request::showAction
_sylius:
section: admin
permission: true
template: "@SyliusAdmin/payment/payment_request/show.html.twig"
repository:
method: findOneByPaymentId
arguments:
hash: $hash
paymentId: $paymentId

View file

@ -1,5 +1,5 @@
<td>
<div class="d-flex justify-content-end">
<div class="d-flex gap-1 justify-content-end">
{% hook 'actions' %}
</div>
</td>

View file

@ -0,0 +1,7 @@
{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %}
{% set payment = hookable_metadata.context.payment %}
<a title="details" href="{{ path('sylius_admin_payment_payment_request_index', {'id': payment.id}) }}" class="btn btn-icon" data-bs-toggle="tooltip" data-bs-title="{{ 'sylius.ui.list_payment_requests'|trans }}" {{ sylius_test_html_attribute('list_payment_requests') }}>
{{ icon({ icon: 'list_letters', class: 'icon icon-tabler' }) }}
</a>

View file

@ -0,0 +1,3 @@
<span class="badge bg-red-lt">
{{ 'sylius.ui.cancelled'|trans }}
</span>

View file

@ -0,0 +1,3 @@
<span class="badge bg-green-lt">
{{ 'sylius.ui.completed'|trans }}
</span>

View file

@ -0,0 +1,3 @@
<span class="badge bg-red-lt">
{{ 'sylius.ui.failed'|trans }}
</span>

View file

@ -0,0 +1,3 @@
<span class="badge">
{{ 'sylius.ui.new'|trans }}
</span>

View file

@ -0,0 +1,3 @@
<span class="badge bg-blue-lt">
{{ 'sylius.ui.processing'|trans }}
</span>

View file

@ -0,0 +1 @@
{{ ('sylius.ui.' ~ data)|trans }}

View file

@ -0,0 +1 @@
<a class="fw-medium" href="{{ path('sylius_admin_payment_method_update', {'id' : data.method.id }) }}">{{ data.method.name }}</a>

View file

@ -0,0 +1 @@
{{ include('@SyliusAdmin/payment/payment_request/common/label/state/' ~ data ~ '.html.twig') }}

View file

@ -0,0 +1,3 @@
{% extends '@SyliusAdmin/shared/crud/index.html.twig' %}
{% set resource_name = 'payment.payment_request' %}

View file

@ -0,0 +1,10 @@
{% from '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' import breadcrumbs %}
{% set configuration = hookable_metadata.context.resources.requestConfiguration %}
{{ breadcrumbs([
{ name: 'sylius.ui.dashboard', url: path('sylius_admin_dashboard'), active: false },
{ name: 'sylius.ui.payments'|trans, url: path('sylius_admin_payment_index'), active: false },
{ name: configuration.request.get('id'), active: false },
{ name: 'sylius.ui.payment_requests'|trans, active: true },
]) }}

View file

@ -0,0 +1,3 @@
{% extends '@SyliusAdmin/shared/crud/show.html.twig' %}
{% set resource_name = 'payment.payment_request' %}

View file

@ -0,0 +1,12 @@
{% from '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' import breadcrumbs %}
{% set payment_request = hookable_metadata.context.resource %}
{% set payment_id = payment_request.payment.id %}
{{ breadcrumbs([
{ name: 'sylius.ui.dashboard', url: path('sylius_admin_dashboard'), active: false },
{ name: 'sylius.ui.payments'|trans, url: path('sylius_admin_payment_index'), active: false },
{ name: payment_id, active: false },
{ name: 'sylius.ui.payment_requests'|trans, url: path('sylius_admin_payment_payment_request_index', {'id': payment_id}), active: false },
{ name: payment_request.hash, active: true },
]) }}

View file

@ -0,0 +1,13 @@
<div class="page-body">
<div class="container-xl">
{% hook 'sections' %}
<div class="row">
<div class="col-12 col-lg-6">
{% hook 'sections#left' %}
</div>
<div class="col-12 col-lg-6">
{% hook 'sections#right' %}
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,12 @@
<div class="card mb-3">
<div class="card-header">
<div class="card-title">
{{ 'sylius.ui.general'|trans }}
</div>
</div>
<div class="card-body">
<div class="divide-y">
{% hook 'general' %}
</div>
</div>
</div>

View file

@ -0,0 +1,6 @@
<div class="row">
<div class="col-12 col-md-4 fw-bold">{{ 'sylius.ui.action'|trans }}</div>
<div class="col-12 col-md-8" {{ sylius_test_html_attribute('action') }}>
{{ ('sylius.ui.' ~ hookable_metadata.context.resource.action)|trans }}
</div>
</div>

View file

@ -0,0 +1,8 @@
{% set date_format = hookable_metadata.configuration.date_format|default('YYYY-MM-dd HH:mm:ss') %}
<div class="row">
<div class="col-12 col-md-4 fw-bold">{{ 'sylius.ui.created_at'|trans }}</div>
<div class="col-12 col-md-8" {{ sylius_test_html_attribute('created-at') }}>
{{ hookable_metadata.context.resource.createdAt|format_datetime(pattern=date_format) }}
</div>
</div>

View file

@ -0,0 +1,4 @@
<div class="row">
<div class="col-12 col-md-4 fw-bold">{{ 'sylius.ui.hash'|trans }}</div>
<div class="col-12 col-md-8" {{ sylius_test_html_attribute('hash') }}>{{ hookable_metadata.context.resource.hash }}</div>
</div>

View file

@ -0,0 +1,8 @@
{% set payment_method = hookable_metadata.context.resource.method %}
<div class="row">
<div class="col-12 col-md-4 fw-bold">{{ 'sylius.ui.payment_method'|trans }}</div>
<div class="col-12 col-md-8" {{ sylius_test_html_attribute('method') }}>
<a href="{{ path('sylius_admin_payment_method_update', {'id' : payment_method.id }) }}">{{ payment_method.name }}</a>
</div>
</div>

View file

@ -0,0 +1,6 @@
<div class="row">
<div class="col-12 col-md-4 fw-bold">{{ 'sylius.ui.state'|trans }}</div>
<div class="col-12 col-md-8" {{ sylius_test_html_attribute('state') }}>
{{ include('@SyliusAdmin/payment/payment_request/common/label/state/' ~ hookable_metadata.context.resource.state ~ '.html.twig') }}
</div>
</div>

View file

@ -0,0 +1,8 @@
{% set date_format = hookable_metadata.configuration.date_format|default('YYYY-MM-dd HH:mm:ss') %}
<div class="row">
<div class="col-12 col-md-4 fw-bold">{{ 'sylius.ui.updated_at'|trans }}</div>
<div class="col-12 col-md-8" {{ sylius_test_html_attribute('updated-at') }}>
{{ hookable_metadata.context.resource.updatedAt|format_datetime(pattern=date_format) }}
</div>
</div>

View file

@ -0,0 +1,10 @@
<div class="card mb-3">
<div class="card-header">
<div class="card-title">
{{ 'sylius.ui.payload'|trans }}
</div>
</div>
<div class="card-body">
<pre {{ sylius_test_html_attribute('payload') }}>{{ hookable_metadata.context.resource.payload|json_encode(constant('JSON_PRETTY_PRINT')) }}</pre>
</div>
</div>

View file

@ -0,0 +1,10 @@
<div class="card mb-3">
<div class="card-header">
<div class="card-title">
{{ 'sylius.ui.response_data'|trans }}
</div>
</div>
<div class="card-body">
<pre {{ sylius_test_html_attribute('response-data') }}>{{ hookable_metadata.context.resource.responseData|json_encode(constant('JSON_PRETTY_PRINT')) }}</pre>
</div>
</div>

View file

@ -15,11 +15,10 @@ namespace Sylius\Bundle\ApiBundle\Command\Payment;
use Sylius\Bundle\ApiBundle\Command\IriToIdentifierConversionAwareInterface;
/** @experimental */
class AddPaymentRequest implements IriToIdentifierConversionAwareInterface
{
public function __construct(
public readonly int|string $paymentId,
public readonly mixed $paymentId,
public readonly string $paymentMethodCode,
public readonly ?string $action = null,
public readonly mixed $payload = null,

View file

@ -27,7 +27,6 @@ use Sylius\Component\Payment\Model\PaymentRequestInterface;
use Sylius\Component\Payment\Repository\PaymentRequestRepositoryInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
/** @experimental */
#[AsMessageHandler]
final class AddPaymentRequestHandler
{

View file

@ -19,7 +19,6 @@ use Sylius\Component\Payment\Model\PaymentRequestInterface;
use Sylius\Component\Payment\Repository\PaymentRequestRepositoryInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
/** @experimental */
#[AsMessageHandler]
final class UpdatePaymentRequestHandler
{

View file

@ -15,5 +15,5 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://api-platform.com/schema/metadata/properties-3.0 https://api-platform.com/schema/metadata/properties-3.0.xsd"
>
<property resource="Sylius\Component\Payment\Model\PaymentRequest" name="hash" identifier="true" />
<property resource="%sylius.model.payment_request.class%" name="hash" identifier="true" />
</properties>

View file

@ -16,7 +16,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0 https://api-platform.com/schema/metadata/resources-3.0.xsd"
>
<resource class="Sylius\Component\Payment\Model\PaymentRequest">
<resource class="%sylius.model.payment_request.class%">
<operations>
<operation
name="sylius_api_admin_payment_request_get"
@ -32,9 +32,9 @@
</operations>
</resource>
<resource class="Sylius\Component\Payment\Model\PaymentRequest" uriTemplate="/admin/payments/{paymentId}/payment-requests">
<resource class="%sylius.model.payment_request.class%" uriTemplate="/admin/payments/{paymentId}/payment-requests">
<uriVariables>
<uriVariable parameterName="paymentId" fromClass="Sylius\Component\Core\Model\Payment" fromProperty="id" toClass="Sylius\Component\Payment\Model\PaymentRequest" toProperty="payment"/>
<uriVariable parameterName="paymentId" fromClass="%sylius.model.payment.class%" fromProperty="paymentRequests"/>
</uriVariables>
<operations>
<operation name="sylius_api_admin_payment_payment_request_get_collection" class="ApiPlatform\Metadata\GetCollection">
@ -47,6 +47,9 @@
</value>
</values>
</normalizationContext>
<filters>
<filter>sylius_api.search_filter.admin.payment_request</filter>
</filters>
</operation>
</operations>
</resource>

View file

@ -16,7 +16,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0 https://api-platform.com/schema/metadata/resources-3.0.xsd"
>
<resource class="Sylius\Component\Payment\Model\PaymentRequest">
<resource class="%sylius.model.payment_request.class%">
<operations>
<operation
name="sylius_api_show_payment_request_get"

View file

@ -35,6 +35,15 @@
<tag name="api_platform.filter" />
</service>
<service id="sylius_api.search_filter.admin.payment_request" parent="api_platform.doctrine.orm.search_filter" public="true">
<argument type="collection">
<argument key="action">exact</argument>
<argument key="method.code">exact</argument>
<argument key="state">exact</argument>
</argument>
<tag name="api_platform.filter" />
</service>
<service id="sylius_api.search_filter.product_attribute" parent="api_platform.doctrine.orm.search_filter" public="true">
<argument type="collection">
<argument key="code">partial</argument>

View file

@ -13,6 +13,8 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\PaymentRequest\Announcer;
use Sylius\Bundle\CoreBundle\Command\Admin\Account\RequestResetPasswordEmail;
use Sylius\Bundle\CoreBundle\Command\CapturePaymentRequest;
use Sylius\Bundle\CoreBundle\PaymentRequest\CommandProvider\PaymentRequestCommandProviderInterface;
use Sylius\Component\Payment\Model\PaymentRequestInterface;
use Symfony\Component\Messenger\MessageBusInterface;

View file

@ -18,7 +18,6 @@ use Sylius\Bundle\CoreBundle\PaymentRequest\Provider\PaymentRequestProviderInter
use Sylius\Component\Payment\Model\PaymentRequestInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
/** @experimental */
#[AsMessageHandler]
final class CapturePaymentRequestHandler
{

View file

@ -13,9 +13,11 @@ declare(strict_types=1);
namespace Sylius\Bundle\PaymentBundle\Doctrine\ORM;
use Doctrine\ORM\QueryBuilder;
use Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository;
use Sylius\Component\Payment\Model\PaymentRequestInterface;
use Sylius\Component\Payment\Repository\PaymentRequestRepositoryInterface;
use Symfony\Bridge\Doctrine\Types\UuidType;
/**
* @template T of PaymentRequestInterface
@ -24,6 +26,31 @@ use Sylius\Component\Payment\Repository\PaymentRequestRepositoryInterface;
*/
class PaymentRequestRepository extends EntityRepository implements PaymentRequestRepositoryInterface
{
public function findOneByPaymentId(mixed $hash, mixed $paymentId): ?PaymentRequestInterface
{
$queryBuilder = $this->createQueryBuilder('o');
return $queryBuilder
->andWhere($queryBuilder->expr()->eq('o.hash', ':hash'))
->andWhere($queryBuilder->expr()->eq('o.payment', ':paymentId'))
->setParameter('hash', $hash, UuidType::NAME)
->setParameter('paymentId', $paymentId)
->getQuery()
->getOneOrNullResult()
;
}
public function createForPaymentQueryBuilder(string $paymentId): QueryBuilder
{
$queryBuilder = $this->createQueryBuilder('o');
$queryBuilder
->andWhere($queryBuilder->expr()->eq('o.payment', ':paymentId'))
->setParameter('paymentId', $paymentId)
;
return $queryBuilder;
}
public function duplicateExists(PaymentRequestInterface $paymentRequest): bool
{
/** @var PaymentRequestInterface[] $paymentRequests */

View file

@ -24,7 +24,7 @@
<join-column name="method_id" referenced-column-name="id" nullable="false" on-delete="CASCADE" />
</many-to-one>
<many-to-one field="payment" target-entity="Sylius\Component\Payment\Model\PaymentInterface">
<many-to-one field="payment" target-entity="Sylius\Component\Payment\Model\PaymentInterface" inversed-by="paymentRequests">
<join-column name="payment_id" referenced-column-name="id" nullable="false" />
</many-to-one>

View file

@ -75,6 +75,7 @@ sylius:
assortment: 'Assortment'
attributes: 'Attributes'
author: 'Author'
authorize: 'Authorize'
authorized: 'Authorized'
authorized_payment: 'Authorized payment'
availability: 'Availability'
@ -110,6 +111,7 @@ sylius:
call_us: 'Call us!'
cancel: 'Cancel'
cancelled: 'Cancelled'
capture: 'Capture'
cart: 'Cart'
cart_locked: 'Cart locked'
cart_summary: 'Cart summary'
@ -397,6 +399,7 @@ sylius:
guest: 'Guest'
guest_customer: 'Guest customer'
have_an_account_already: 'Have an account already?'
hash: 'Hash'
height: 'Height'
hello: 'Hello'
hello_name: 'Hello <b>%name%</b>'
@ -448,6 +451,7 @@ sylius:
license: 'License'
links: 'Links'
list_coupons: 'List coupons'
list_payment_requests: 'List payment requests'
list_variants: 'List variants'
loading: 'Loading'
locale: 'Locale'
@ -646,14 +650,18 @@ sylius:
password: 'Password'
pay: 'Pay'
pay_again: 'Click pay to try again'
payload: 'Payload'
payment: 'Payment'
payment_details: 'Payment details'
payment_method: 'Payment method'
payment_methods: 'Payment methods'
payment_mode: 'Payment mode'
payment_ready_to_pay: 'You can now make your payment'
payment_request: 'Payment request'
payment_requests: 'Payment requests'
payment_state: 'Payment state'
payments: 'Payments'
payout: 'Payout'
pending: 'Pending'
per_customer_usage_limit: 'Per customer usage limit'
percent: 'Percent'
@ -751,6 +759,7 @@ sylius:
reset: 'Reset'
reset_button: 'Reset'
reset_password: 'Reset password'
response_data: 'Response data'
restore: 'Restore'
retail_price: 'Retail price'
return: 'Return'
@ -852,6 +861,7 @@ sylius:
summary_of_your_order: 'Summary of your order'
support: 'Support'
sylius_logo: 'Sylius'
sync: 'Sync'
target_currency: 'Target currency'
tax: 'Tax'
tax_categories: 'Tax Categories'
@ -951,6 +961,7 @@ sylius:
update_cart: 'Update cart'
update_product_association_type: 'Update product association type'
updated: 'Updated'
updated_at: 'Updated at'
updating_date: 'Updating date'
updating_tax_rate: 'Updating tax rate'
usage: 'Usage'

View file

@ -13,6 +13,7 @@ declare(strict_types=1);
namespace Sylius\Component\Payment\Repository;
use Doctrine\ORM\QueryBuilder;
use Sylius\Component\Payment\Model\PaymentRequestInterface;
use Sylius\Resource\Doctrine\Persistence\RepositoryInterface;
@ -23,5 +24,9 @@ use Sylius\Resource\Doctrine\Persistence\RepositoryInterface;
*/
interface PaymentRequestRepositoryInterface extends RepositoryInterface
{
public function findOneByPaymentId(mixed $hash, mixed $paymentId): ?PaymentRequestInterface;
public function createForPaymentQueryBuilder(string $paymentId): QueryBuilder;
public function duplicateExists(PaymentRequestInterface $paymentRequest): bool;
}