Skip to content

Commit b774346

Browse files
PT-3219: SW6: Support new ZUGFeRD invoice feature (#85)
1 parent 3ab2949 commit b774346

File tree

56 files changed

+3274
-294
lines changed

Some content is hidden

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

56 files changed

+3274
-294
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "mondu/shopware6-payment",
33
"description": "Mondu payment for Shopware 6",
4-
"version": "1.5.0",
4+
"version": "1.6.0",
55
"type": "shopware-platform-plugin",
66
"license": "proprietary",
77
"authors": [

src/Bootstrap/PaymentMethods.php

Lines changed: 23 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -19,121 +19,96 @@ class PaymentMethods extends AbstractBootstrap
1919
public const PAYMENT_METHODS = [
2020
MonduHandler::class => [
2121
'handlerIdentifier' => MonduHandler::class,
22-
'name' => 'Rechnungskauf - Später per Banküberweisung bezahlen',
23-
'description' => 'Hinweise zur Verarbeitung Ihrer personenbezogenen Daten durch die Mondu GmbH finden Sie [url=https://www.mondu.ai/de/gdpr-notification-for-buyers/]hier[/url].',
22+
'name' => 'Rechnungskauf (30 Tage)',
2423
'afterOrderEnabled' => true,
2524
'translations' => [
2625
'de-DE' => [
27-
'name' => 'Rechnungskauf - Später per Banküberweisung bezahlen',
28-
'description' => 'Hinweise zur Verarbeitung Ihrer personenbezogenen Daten durch die Mondu GmbH finden Sie [url=https://www.mondu.ai/de/gdpr-notification-for-buyers/]hier[/url].',
26+
'name' => 'Rechnungskauf (30 Tage)'
2927
],
3028
'en-GB' => [
31-
'name' => 'Invoice - Pay later by bank transfer',
32-
'description' => 'Information on the processing of your personal data by Mondu GmbH can be found [url=https://www.mondu.ai/de/gdpr-notification-for-buyers/]here[/url].',
29+
'name' => 'Business net 30'
3330
],
3431
'nl-NL' => [
35-
'name' => 'Aankoop op rekening - nu kopen, later betalen',
36-
'description' => 'Informatie over de verwerking van uw persoonsgegevens door Mondu GmbH vindt u [url=https://mondu.ai/nl/gdpr-notification-for-buyers]hier[/url].'
32+
'name' => 'Factuur (30 dagen)'
3733
],
3834
'fr-FR' => [
39-
'name' => 'Achat sur facture - Payer plus tard par virement bancaire',
40-
'description' => "Plus d'informations sur la façon dont Mondu GmbH traite vos données personnelles peuvent être trouvées [url=https://mondu.ai/fr/gdpr-notification-for-buyers]ici[/url]."
35+
'name' => 'Facture (30 jours)'
4136
]
4237
],
4338
],
4439
MonduSepaHandler::class => [
4540
'handlerIdentifier' => MonduSepaHandler::class,
46-
'name' => 'SEPA - Später zahlen per Bankeinzug',
47-
'description' => 'Hinweise zur Verarbeitung Ihrer personenbezogenen Daten durch die Mondu GmbH finden Sie [url=https://www.mondu.ai/de/datenschutzgrundverordnung-kaeufer/]hier[/url].',
41+
'name' => 'SEPA-Lastschrift (30 Tage)',
4842
'afterOrderEnabled' => true,
4943
'translations' => [
5044
'de-DE' => [
51-
'name' => 'SEPA - Später zahlen per Bankeinzug',
52-
'description' => 'Hinweise zur Verarbeitung Ihrer personenbezogenen Daten durch die Mondu GmbH finden Sie [url=https://www.mondu.ai/de/datenschutzgrundverordnung-kaeufer/]hier[/url].',
45+
'name' => 'SEPA-Lastschrift (30 Tage)'
5346
],
5447
'en-GB' => [
55-
'name' => 'SEPA - Pay later by direct debit',
56-
'description' => 'Information on the processing of your personal data by Mondu GmbH can be found [url=https://www.mondu.ai/de/datenschutzgrundverordnung-kaeufer/]here[/url].',
48+
'name' => 'SEPA direct debit (30 days)'
5749
],
5850
'nl-NL' => [
59-
'name' => 'SEPA automatische incasso - nu kopen, later betalen',
60-
'description' => 'Informatie over de verwerking van uw persoonsgegevens door Mondu GmbH vindt u [url=https://www.mondu.ai/nl/gdpr-notification-for-merchants/]hier[/url].'
51+
'name' => 'SEPA automatische incasso (30 dagen)'
6152
],
6253
'fr-FR' => [
63-
'name' => 'SEPA - Payer plus tard par prélèvement automatique SEPA',
64-
'description' => "Plus d'informations sur la façon dont Mondu GmbH traite vos données personnelles peuvent être trouvées [url=https://mondu.ai/fr/gdpr-notification-for-buyers]ici[/url]."
54+
'name' => 'Prélèvement automatique SEPA (30 jours)'
6555
]
6656
],
6757
],
6858
MonduInstallmentHandler::class => [
6959
'handlerIdentifier' => MonduInstallmentHandler::class,
7060
'name' => 'Ratenkauf - Bequem in Raten per Bankeinzug zahlen',
71-
'description' => 'Hinweise zur Verarbeitung Ihrer personenbezogenen Daten durch die Mondu GmbH finden Sie [url=https://www.mondu.ai/de/datenschutzgrundverordnung-kaeufer/]hier[/url].',
7261
'afterOrderEnabled' => true,
7362
'translations' => [
7463
'de-DE' => [
75-
'name' => 'Ratenkauf - Bequem in Raten per Bankeinzug zahlen',
76-
'description' => 'Hinweise zur Verarbeitung Ihrer personenbezogenen Daten durch die Mondu GmbH finden Sie [url=https://www.mondu.ai/de/datenschutzgrundverordnung-kaeufer/]hier[/url].',
64+
'name' => 'Ratenkauf (3, 6, 12 Monaten)'
7765
],
7866
'en-GB' => [
79-
'name' => 'Split payments - Pay conveniently in instalments by direct debit',
80-
'description' => 'Information on the processing of your personal data by Mondu GmbH can be found [url=https://www.mondu.ai/de/datenschutzgrundverordnung-kaeufer/]here[/url].',
67+
'name' => 'Installments (3, 6, 12 months)'
8168
],
8269
'nl-NL' => [
83-
'name' => 'Gespreid betalen, betaal gemakkelijk in termijnen via automatische incasso',
84-
'description' => 'Informatie over de verwerking van uw persoonsgegevens door Mondu GmbH vindt u [url=https://www.mondu.ai/nl/gdpr-notification-for-merchants/]hier[/url].'
70+
'name' => 'Betaling in termijnen (3, 6, 12 maanden)'
8571
],
8672
'fr-FR' => [
87-
'name' => 'Paiement échelonné - Payer confortablement en plusieurs fois par prélèvement automatique',
88-
'description' => "Plus d'informations sur la façon dont Mondu GmbH traite vos données personnelles peuvent être trouvées [url=https://mondu.ai/fr/gdpr-notification-for-buyers]ici[/url]."
73+
'name' => 'Paiement échelonnés (3, 6, 12 mois)'
8974
]
9075
],
9176
],
9277
MonduInstallmentByInvoiceHandler::class => [
9378
'handlerIdentifier' => MonduInstallmentByInvoiceHandler::class,
9479
'name' => 'Gesplittete Zahlungen - Ratenkauf per Banküberweisung',
95-
'description' => 'Hinweise zur Verarbeitung Ihrer personenbezogenen Daten durch die Mondu GmbH finden Sie [url=https://www.mondu.ai/de/datenschutzgrundverordnung-kaeufer/]hier[/url].',
9680
'afterOrderEnabled' => true,
9781
'translations' => [
9882
'de-DE' => [
99-
'name' => 'Gesplittete Zahlungen - Ratenkauf per Banküberweisung',
100-
'description' => 'Hinweise zur Verarbeitung Ihrer personenbezogenen Daten durch die Mondu GmbH finden Sie [url=https://www.mondu.ai/de/datenschutzgrundverordnung-kaeufer/]hier[/url].',
83+
'name' => 'Ratenkauf (3, 6, 12 Monaten) UK'
10184
],
10285
'en-GB' => [
103-
'name' => 'Split payments - Pay Later in Installments by Bank Transfer',
104-
'description' => 'Information on the processing of your personal data by Mondu GmbH can be found [url=https://www.mondu.ai/de/datenschutzgrundverordnung-kaeufer/]here[/url].',
86+
'name' => 'Business instalments (3, 6, 12)'
10587
],
10688
'nl-NL' => [
107-
'name' => 'Gesplitste betalingen - Betaal later in termijnen via bankoverschrijving',
108-
'description' => 'Informatie over de verwerking van uw persoonsgegevens door Mondu GmbH vindt u [url=https://www.mondu.ai/nl/gdpr-notification-for-merchants/]hier[/url].'
89+
'name' => 'Betaling in termijnen (3, 6, 12 maanden) UK'
10990
],
11091
'fr-FR' => [
111-
'name' => 'Paiements fractionnés - Payer plus tard en plusieurs fois par virement bancaire',
112-
'description' => "Plus d'informations sur la façon dont Mondu GmbH traite vos données personnelles peuvent être trouvées [url=https://mondu.ai/fr/gdpr-notification-for-buyers]ici[/url]."
92+
'name' => 'Paiement échelonnés (3, 6, 12 mois) UK'
11393
]
11494
],
11595
],
11696
MonduPayNowHandler::class => [
11797
'handlerIdentifier' => MonduPayNowHandler::class,
118-
'name' => 'Echtzeitüberweisung – Direkt von Ihrem Bankkonto bezahlen',
119-
'description' => 'Informationen über die Verarbeitung Ihrer persönlichen Daten durch die Mondu GmbH finden Sie [url=https://www.mondu.ai/de/datenschutzgrundverordnung-kaeufer/]hier[/url].',
98+
'name' => 'Echtzeitüberweisung',
12099
'afterOrderEnabled' => true,
121100
'translations' => [
122101
'de-DE' => [
123-
'name' => 'Echtzeitüberweisung – Direkt von Ihrem Bankkonto bezahlen',
124-
'description' => 'Informationen über die Verarbeitung Ihrer persönlichen Daten durch die Mondu GmbH finden Sie [url=https://www.mondu.ai/de/datenschutzgrundverordnung-kaeufer/]hier[/url].',
102+
'name' => 'Echtzeitüberweisung'
125103
],
126104
'en-GB' => [
127-
'name' => 'Instant Pay – Pay directly from your bank account',
128-
'description' => 'Information about how Mondu GmbH processes your personal data can be found [url=https://www.mondu.ai/de/datenschutzgrundverordnung-kaeufer/]here[/url].',
105+
'name' => 'Instant Pay'
129106
],
130107
'nl-NL' => [
131-
'name' => 'Instant Pay – Betaal direct vanaf uw bankrekening',
132-
'description' => 'Instant Pay – Betaal direct vanaf uw bankrekening [url=https://www.mondu.ai/nl/gdpr-notification-for-merchants/]hier[/url].'
108+
'name' => 'Instant Pay'
133109
],
134110
'fr-FR' => [
135-
'name' => 'Virement Instantané – Payez directement depuis votre compte bancaire',
136-
'description' => "Des informations sur la façon dont Mondu GmbH traite vos données personnelles peuvent être trouvées [url=https://mondu.ai/fr/gdpr-notification-for-buyers]ici[/url]."
111+
'name' => 'Virement instantané'
137112
]
138113
],
139114
],
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Mondu\MonduPayment\Command;
6+
7+
use Shopware\Core\Framework\Context;
8+
use Shopware\Core\Framework\Event\BusinessEventCollector;
9+
use Symfony\Component\Console\Command\Command;
10+
use Symfony\Component\Console\Input\InputInterface;
11+
use Symfony\Component\Console\Output\OutputInterface;
12+
use Symfony\Component\Console\Style\SymfonyStyle;
13+
14+
class CheckFlowAwareCommand extends Command
15+
{
16+
protected static $defaultName = 'mondu:check-flow-aware';
17+
18+
private BusinessEventCollector $businessEventCollector;
19+
20+
public function __construct(BusinessEventCollector $businessEventCollector)
21+
{
22+
parent::__construct();
23+
$this->businessEventCollector = $businessEventCollector;
24+
}
25+
26+
public static function getDefaultName(): ?string
27+
{
28+
return 'mondu:check-flow-aware';
29+
}
30+
31+
protected function configure(): void
32+
{
33+
$this->setName('mondu:check-flow-aware')
34+
->setDescription('Check Flow Builder aware interfaces for Mondu events');
35+
}
36+
37+
protected function execute(InputInterface $input, OutputInterface $output): int
38+
{
39+
$io = new SymfonyStyle($input, $output);
40+
$context = Context::createDefaultContext();
41+
42+
// Collect all business events
43+
$events = $this->businessEventCollector->collect($context);
44+
45+
$io->title('Flow Builder Events Analysis');
46+
47+
// Filter Mondu events
48+
$monduEvents = [];
49+
foreach ($events as $event) {
50+
if (strpos($event->getName(), 'mondu') !== false) {
51+
$monduEvents[] = $event;
52+
}
53+
}
54+
55+
if (empty($monduEvents)) {
56+
$io->error('❌ No Mondu events found!');
57+
return Command::FAILURE;
58+
}
59+
60+
$io->success(sprintf('✅ Found %d Mondu events', count($monduEvents)));
61+
62+
foreach ($monduEvents as $event) {
63+
$io->section($event->getName());
64+
65+
$io->writeln('Class: ' . $event->getClass());
66+
67+
// Get aware interfaces - In Shopware 6.6, getAware() might need a context
68+
try {
69+
// Try with reflection to see what's stored
70+
$reflection = new \ReflectionClass($event);
71+
$property = $reflection->getProperty('aware');
72+
$property->setAccessible(true);
73+
$aware = $property->getValue($event);
74+
75+
if (empty($aware)) {
76+
$io->error('❌ No aware interfaces defined in BusinessEventDefinition!');
77+
} else {
78+
$io->writeln('Aware interfaces (from definition):');
79+
foreach ($aware as $interface) {
80+
$io->writeln(' - ' . $interface);
81+
}
82+
}
83+
} catch (\Exception $e) {
84+
$io->warning('Could not read aware property: ' . $e->getMessage());
85+
}
86+
87+
// Check actual class interfaces
88+
$class = $event->getClass();
89+
if (class_exists($class)) {
90+
$reflection = new \ReflectionClass($class);
91+
$interfaces = $reflection->getInterfaceNames();
92+
93+
$io->writeln('');
94+
$io->writeln('Actual class interfaces:');
95+
foreach ($interfaces as $interface) {
96+
$shortName = substr($interface, strrpos($interface, '\\') + 1);
97+
$io->writeln(' - ' . $shortName);
98+
}
99+
}
100+
101+
$io->newLine();
102+
}
103+
104+
// Now check what the default Checkout Order Placed event looks like
105+
$io->section('Comparison: checkout.order.placed');
106+
foreach ($events as $event) {
107+
if ($event->getName() === 'checkout.order.placed') {
108+
$io->writeln('Class: ' . $event->getClass());
109+
110+
try {
111+
$reflection = new \ReflectionClass($event);
112+
$property = $reflection->getProperty('aware');
113+
$property->setAccessible(true);
114+
$aware = $property->getValue($event);
115+
116+
$io->writeln('Aware interfaces:');
117+
foreach ($aware as $interface) {
118+
$io->writeln(' - ' . $interface);
119+
}
120+
} catch (\Exception $e) {
121+
$io->warning('Could not read aware property: ' . $e->getMessage());
122+
}
123+
break;
124+
}
125+
}
126+
127+
return Command::SUCCESS;
128+
}
129+
}
130+
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Mondu\MonduPayment\Command;
6+
7+
use Shopware\Core\Framework\Context;
8+
use Shopware\Core\Framework\Event\BusinessEventCollector;
9+
use Symfony\Component\Console\Attribute\AsCommand;
10+
use Symfony\Component\Console\Command\Command;
11+
use Symfony\Component\Console\Input\InputInterface;
12+
use Symfony\Component\Console\Output\OutputInterface;
13+
use Symfony\Component\Console\Style\SymfonyStyle;
14+
15+
#[AsCommand(
16+
name: 'mondu:check-events',
17+
description: 'Check if Mondu events are registered in Flow Builder'
18+
)]
19+
class CheckMonduEventsCommand extends Command
20+
{
21+
public function __construct(
22+
private readonly BusinessEventCollector $businessEventCollector
23+
) {
24+
parent::__construct();
25+
}
26+
27+
protected function execute(InputInterface $input, OutputInterface $output): int
28+
{
29+
$io = new SymfonyStyle($input, $output);
30+
31+
$io->title('Checking Mondu Events Registration in Flow Builder');
32+
33+
$context = Context::createDefaultContext();
34+
$events = $this->businessEventCollector->collect($context);
35+
36+
$monduEvents = [];
37+
foreach ($events->getElements() as $event) {
38+
if (str_starts_with($event->getName(), 'mondu.')) {
39+
$monduEvents[] = $event->getName();
40+
}
41+
}
42+
43+
if (empty($monduEvents)) {
44+
$io->error('No Mondu events found in Flow Builder!');
45+
$io->note('Expected events: mondu.order.confirmed, mondu.order.cancelled, etc.');
46+
return Command::FAILURE;
47+
}
48+
49+
$io->success(sprintf('Found %d Mondu event(s):', count($monduEvents)));
50+
$io->listing($monduEvents);
51+
52+
return Command::SUCCESS;
53+
}
54+
}
55+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Mondu\MonduPayment\Command;
6+
7+
use Symfony\Component\Console\Command\Command;
8+
use Symfony\Component\Console\Input\InputInterface;
9+
use Symfony\Component\Console\Output\OutputInterface;
10+
11+
class TestMonduEventsCommand extends Command
12+
{
13+
protected static $defaultName = 'mondu:test:events';
14+
protected static $defaultDescription = 'Test Mondu custom events';
15+
16+
protected function configure(): void
17+
{
18+
$this
19+
->setName('mondu:test:events')
20+
->setDescription('Test Mondu custom events');
21+
}
22+
23+
protected function execute(InputInterface $input, OutputInterface $output): int
24+
{
25+
$output->writeln('Testing Mondu Custom Events...');
26+
$output->writeln('Available events:');
27+
$output->writeln('- mondu.order.confirmed');
28+
$output->writeln('- mondu.order.cancelled');
29+
$output->writeln('- mondu.order.pending');
30+
$output->writeln('- mondu.order.approved');
31+
$output->writeln('- mondu.order.declined');
32+
$output->writeln('');
33+
$output->writeln('Events are triggered automatically when webhooks are received from Mondu.');
34+
$output->writeln('Check the Mondu logs for event details:');
35+
$output->writeln('docker exec shop-sw6 tail -f /var/www/html/var/log/mondu.log');
36+
37+
return Command::SUCCESS;
38+
}
39+
}

0 commit comments

Comments
 (0)