From 4e3f5fbdf9d47d17d9885dd76c454ca356a69609 Mon Sep 17 00:00:00 2001 From: Vitalij Mik Date: Wed, 27 Sep 2023 14:55:07 +0200 Subject: [PATCH] MOL-969: Store refund manager metadata in DB (#625) * MOL-969: Add entities * MOL-969: store refunds in db * MOL-969: can save refund items * MOL-969: fix hydrator tests * MOL-969: Fix styles * MOL-969: fix metadata * MOL-969: fix merge * MOL-969: update pr * MOL-969: create an array --------- Co-authored-by: Vitalij Mik --- composer.lock | 520 ++++++++++-------- .../Builder/RefundDataBuilder.php | 2 +- .../OrderLineItem/OrderLineItemExtension.php | 35 ++ .../DAL/Refund/RefundDefinition.php | 3 + .../RefundManager/DAL/Refund/RefundEntity.php | 28 + .../DAL/RefundItem/RefundItemCollection.php | 17 + .../DAL/RefundItem/RefundItemDefinition.php | 58 ++ .../DAL/RefundItem/RefundItemEntity.php | 257 +++++++++ .../RefundManager/RefundData/RefundData.php | 7 +- .../RefundManager/RefundManager.php | 83 ++- .../Api/Order/RefundControllerBase.php | 2 +- src/Hydrator/RefundHydrator.php | 34 +- .../Migration1644753635CreateSubscription.php | 2 - .../Migration1672671475RefundItem.php | 44 ++ src/MolliePayments.php | 17 +- .../services/refundmanager/services.xml | 9 +- src/Resources/config/services/services.xml | 10 + .../config/services/subscription/services.xml | 1 + .../Fixer/RoundingDifferenceFixer.php | 2 +- src/Service/OrderService.php | 3 +- .../Refund/CompositionMigrationService.php | 172 ++++++ .../CompositionMigrationServiceInterface.php | 13 + src/Service/Refund/Item/RefundItem.php | 19 +- src/Service/Refund/Mollie/DataCompressor.php | 37 -- src/Service/Refund/Mollie/RefundMetadata.php | 45 +- src/Service/Refund/RefundService.php | 28 +- src/Service/Refund/RefundServiceInterface.php | 2 +- tests/PHPUnit/Fakes/FakeRefundService.php | 2 +- tests/PHPUnit/Hydrator/RefundHydratorTest.php | 2 +- .../Service/Refund/Item/RefundItemTest.php | 3 +- .../Refund/Mollie/DataCompressorTest.php | 53 -- .../Refund/Mollie/RefundMetadataTest.php | 55 +- 32 files changed, 1097 insertions(+), 468 deletions(-) create mode 100644 src/Components/RefundManager/DAL/OrderLineItem/OrderLineItemExtension.php create mode 100644 src/Components/RefundManager/DAL/RefundItem/RefundItemCollection.php create mode 100644 src/Components/RefundManager/DAL/RefundItem/RefundItemDefinition.php create mode 100644 src/Components/RefundManager/DAL/RefundItem/RefundItemEntity.php create mode 100644 src/Migration/Migration1672671475RefundItem.php create mode 100644 src/Service/Refund/CompositionMigrationService.php create mode 100644 src/Service/Refund/CompositionMigrationServiceInterface.php delete mode 100644 src/Service/Refund/Mollie/DataCompressor.php delete mode 100644 tests/PHPUnit/Service/Refund/Mollie/DataCompressorTest.php diff --git a/composer.lock b/composer.lock index a1ad84c5b..65c8d7296 100644 --- a/composer.lock +++ b/composer.lock @@ -232,16 +232,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.281.8", + "version": "3.281.10", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "eb349b9f31502a05c70362f57913b9fed6b65b1f" + "reference": "049604298f769fa218549d8ff5cac1981f0a349a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/eb349b9f31502a05c70362f57913b9fed6b65b1f", - "reference": "eb349b9f31502a05c70362f57913b9fed6b65b1f", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/049604298f769fa218549d8ff5cac1981f0a349a", + "reference": "049604298f769fa218549d8ff5cac1981f0a349a", "shasum": "" }, "require": { @@ -321,9 +321,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.281.8" + "source": "https://github.com/aws/aws-sdk-php/tree/3.281.10" }, - "time": "2023-09-15T18:34:59+00:00" + "time": "2023-09-19T18:33:42+00:00" }, { "name": "boxblinkracer/phpunuhi", @@ -395,26 +395,25 @@ }, { "name": "brick/math", - "version": "0.9.3", + "version": "0.11.0", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae" + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae", - "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae", + "url": "https://api.github.com/repos/brick/math/zipball/0ad82ce168c82ba30d1c01ec86116ab52f589478", + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478", "shasum": "" }, "require": { - "ext-json": "*", - "php": "^7.1 || ^8.0" + "php": "^8.0" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", - "vimeo/psalm": "4.9.2" + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "5.0.0" }, "type": "library", "autoload": { @@ -439,19 +438,15 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.9.3" + "source": "https://github.com/brick/math/tree/0.11.0" }, "funding": [ { "url": "https://github.com/BenMorel", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/brick/math", - "type": "tidelift" } ], - "time": "2021-08-15T20:50:18+00:00" + "time": "2023-01-15T23:15:59+00:00" }, { "name": "cocur/slugify", @@ -1634,30 +1629,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.5.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^9 || ^11", + "doctrine/coding-standard": "^11", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.30 || ^5.4" + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" }, "type": "library", "autoload": { @@ -1684,7 +1679,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" }, "funding": [ { @@ -1700,7 +1695,7 @@ "type": "tidelift" } ], - "time": "2022-12-30T00:15:36+00:00" + "time": "2022-12-30T00:23:10+00:00" }, { "name": "doctrine/lexer", @@ -4027,29 +4022,29 @@ }, { "name": "laminas/laminas-code", - "version": "4.7.1", + "version": "4.12.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-code.git", - "reference": "91aabc066d5620428120800c0eafc0411e441a62" + "reference": "36cbee228b427446419dd51944bdfb6bb8ddbcd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-code/zipball/91aabc066d5620428120800c0eafc0411e441a62", - "reference": "91aabc066d5620428120800c0eafc0411e441a62", + "url": "https://api.github.com/repos/laminas/laminas-code/zipball/36cbee228b427446419dd51944bdfb6bb8ddbcd0", + "reference": "36cbee228b427446419dd51944bdfb6bb8ddbcd0", "shasum": "" }, "require": { - "php": ">=7.4, <8.2" + "php": "~8.1.0 || ~8.2.0" }, "require-dev": { - "doctrine/annotations": "^1.13.2", + "doctrine/annotations": "^2.0.0", "ext-phar": "*", "laminas/laminas-coding-standard": "^2.3.0", "laminas/laminas-stdlib": "^3.6.1", - "phpunit/phpunit": "^9.5.10", - "psalm/plugin-phpunit": "^0.17.0", - "vimeo/psalm": "^4.13.1" + "phpunit/phpunit": "^10.0.9", + "psalm/plugin-phpunit": "^0.18.4", + "vimeo/psalm": "^5.7.1" }, "suggest": { "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", @@ -4057,9 +4052,6 @@ }, "type": "library", "autoload": { - "files": [ - "polyfill/ReflectionEnumPolyfill.php" - ], "psr-4": { "Laminas\\Code\\": "src/" } @@ -4089,35 +4081,38 @@ "type": "community_bridge" } ], - "time": "2022-11-21T01:32:31+00:00" + "time": "2023-09-06T14:56:25+00:00" }, { "name": "lcobucci/clock", - "version": "2.0.0", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/lcobucci/clock.git", - "reference": "353d83fe2e6ae95745b16b3d911813df6a05bfb3" + "reference": "c7aadcd6fd97ed9e199114269c0be3f335e38876" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/clock/zipball/353d83fe2e6ae95745b16b3d911813df6a05bfb3", - "reference": "353d83fe2e6ae95745b16b3d911813df6a05bfb3", + "url": "https://api.github.com/repos/lcobucci/clock/zipball/c7aadcd6fd97ed9e199114269c0be3f335e38876", + "reference": "c7aadcd6fd97ed9e199114269c0be3f335e38876", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0" + "php": "~8.1.0 || ~8.2.0", + "stella-maris/clock": "^0.1.7" + }, + "provide": { + "psr/clock-implementation": "1.0" }, "require-dev": { - "infection/infection": "^0.17", - "lcobucci/coding-standard": "^6.0", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-deprecation-rules": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpstan/phpstan-strict-rules": "^0.12", - "phpunit/php-code-coverage": "9.1.4", - "phpunit/phpunit": "9.3.7" + "infection/infection": "^0.26", + "lcobucci/coding-standard": "^9.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-deprecation-rules": "^1.1.1", + "phpstan/phpstan-phpunit": "^1.3.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^9.5.27" }, "type": "library", "autoload": { @@ -4138,7 +4133,7 @@ "description": "Yet another clock abstraction", "support": { "issues": "https://github.com/lcobucci/clock/issues", - "source": "https://github.com/lcobucci/clock/tree/2.0.x" + "source": "https://github.com/lcobucci/clock/tree/2.3.0" }, "funding": [ { @@ -4150,7 +4145,7 @@ "type": "patreon" } ], - "time": "2020-08-27T18:56:02+00:00" + "time": "2022-12-19T14:38:11+00:00" }, { "name": "lcobucci/jwt", @@ -4640,37 +4635,38 @@ }, { "name": "league/uri", - "version": "6.7.2", + "version": "6.8.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "d3b50812dd51f3fbf176344cc2981db03d10fe06" + "reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/d3b50812dd51f3fbf176344cc2981db03d10fe06", - "reference": "d3b50812dd51f3fbf176344cc2981db03d10fe06", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/a700b4656e4c54371b799ac61e300ab25a2d1d39", + "reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39", "shasum": "" }, "require": { "ext-json": "*", "league/uri-interfaces": "^2.3", - "php": "^7.4 || ^8.0", - "psr/http-message": "^1.0" + "php": "^8.1", + "psr/http-message": "^1.0.1" }, "conflict": { "league/uri-schemes": "^1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^v3.3.2", - "nyholm/psr7": "^1.5", - "php-http/psr7-integration-tests": "^1.1", - "phpstan/phpstan": "^1.2.0", + "friendsofphp/php-cs-fixer": "^v3.9.5", + "nyholm/psr7": "^1.5.1", + "php-http/psr7-integration-tests": "^1.1.1", + "phpbench/phpbench": "^1.2.6", + "phpstan/phpstan": "^1.8.5", "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0.0", - "phpstan/phpstan-strict-rules": "^1.1.0", - "phpunit/phpunit": "^9.5.10", - "psr/http-factory": "^1.0" + "phpstan/phpstan-phpunit": "^1.1.1", + "phpstan/phpstan-strict-rules": "^1.4.3", + "phpunit/phpunit": "^9.5.24", + "psr/http-factory": "^1.0.1" }, "suggest": { "ext-fileinfo": "Needed to create Data URI from a filepath", @@ -4727,7 +4723,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri/issues", - "source": "https://github.com/thephpleague/uri/tree/6.7.2" + "source": "https://github.com/thephpleague/uri/tree/6.8.0" }, "funding": [ { @@ -4735,7 +4731,7 @@ "type": "github" } ], - "time": "2022-09-13T19:50:42+00:00" + "time": "2022-09-13T19:58:47+00:00" }, { "name": "league/uri-interfaces", @@ -6016,16 +6012,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.28", + "version": "9.2.29", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "7134a5ccaaf0f1c92a4f5501a6c9f98ac4dcc0ef" + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7134a5ccaaf0f1c92a4f5501a6c9f98ac4dcc0ef", - "reference": "7134a5ccaaf0f1c92a4f5501a6c9f98ac4dcc0ef", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", "shasum": "" }, "require": { @@ -6082,7 +6078,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.28" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" }, "funding": [ { @@ -6090,7 +6086,7 @@ "type": "github" } ], - "time": "2023-09-12T14:36:20+00:00" + "time": "2023-09-19T04:57:46+00:00" }, { "name": "phpunit/php-file-iterator", @@ -6335,16 +6331,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.12", + "version": "9.6.13", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a122c2ebd469b751d774aa0f613dc0d67697653f" + "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a122c2ebd469b751d774aa0f613dc0d67697653f", - "reference": "a122c2ebd469b751d774aa0f613dc0d67697653f", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3d767f7f9e191eab4189abe41ab37797e30b1be", + "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be", "shasum": "" }, "require": { @@ -6418,7 +6414,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.12" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.13" }, "funding": [ { @@ -6434,7 +6430,7 @@ "type": "tidelift" } ], - "time": "2023-09-12T14:39:31+00:00" + "time": "2023-09-19T05:39:22+00:00" }, { "name": "psr/cache", @@ -6485,6 +6481,54 @@ }, "time": "2016-08-06T20:24:11+00:00" }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, { "name": "psr/container", "version": "1.1.2", @@ -6933,21 +6977,20 @@ }, { "name": "ramsey/collection", - "version": "1.3.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4" + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/ad7475d1c9e70b190ecffc58f2d989416af339b4", - "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4", + "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0", - "symfony/polyfill-php81": "^1.23" + "php": "^8.1" }, "require-dev": { "captainhook/plugin-composer": "^5.3", @@ -7007,7 +7050,7 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/1.3.0" + "source": "https://github.com/ramsey/collection/tree/2.0.0" }, "funding": [ { @@ -7019,29 +7062,27 @@ "type": "tidelift" } ], - "time": "2022-12-27T19:12:24+00:00" + "time": "2022-12-31T21:50:55+00:00" }, { "name": "ramsey/uuid", - "version": "4.2.3", + "version": "4.7.4", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df" + "reference": "60a4c63ab724854332900504274f6150ff26d286" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/60a4c63ab724854332900504274f6150ff26d286", + "reference": "60a4c63ab724854332900504274f6150ff26d286", "shasum": "" }, "require": { - "brick/math": "^0.8 || ^0.9", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11", "ext-json": "*", - "php": "^7.2 || ^8.0", - "ramsey/collection": "^1.0", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php80": "^1.14" + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" }, "replace": { "rhumsaa/uuid": "self.version" @@ -7053,24 +7094,23 @@ "doctrine/annotations": "^1.8", "ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.3", - "moontoast/math": "^1.1", "paragonie/random-lib": "^2", "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", "php-parallel-lint/php-parallel-lint": "^1.1", "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-mockery": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", "phpunit/phpunit": "^8.5 || ^9", - "slevomat/coding-standard": "^7.0", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.5", "vimeo/psalm": "^4.9" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-ctype": "Enables faster processing of character classification using ctype functions.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", @@ -7078,9 +7118,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "4.x-dev" - }, "captainhook": { "force-install": true } @@ -7105,7 +7142,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.2.3" + "source": "https://github.com/ramsey/uuid/tree/4.7.4" }, "funding": [ { @@ -7117,7 +7154,7 @@ "type": "tidelift" } ], - "time": "2021-09-25T23:10:38+00:00" + "time": "2023-04-15T23:01:58+00:00" }, { "name": "react/promise", @@ -9324,6 +9361,53 @@ }, "time": "2020-01-22T14:45:26+00:00" }, + { + "name": "stella-maris/clock", + "version": "0.1.7", + "source": { + "type": "git", + "url": "https://github.com/stella-maris-solutions/clock.git", + "reference": "fa23ce16019289a18bb3446fdecd45befcdd94f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/stella-maris-solutions/clock/zipball/fa23ce16019289a18bb3446fdecd45befcdd94f8", + "reference": "fa23ce16019289a18bb3446fdecd45befcdd94f8", + "shasum": "" + }, + "require": { + "php": "^7.0|^8.0", + "psr/clock": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "StellaMaris\\Clock\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andreas Heigl", + "role": "Maintainer" + } + ], + "description": "A pre-release of the proposed PSR-20 Clock-Interface", + "homepage": "https://gitlab.com/stella-maris/clock", + "keywords": [ + "clock", + "datetime", + "point in time", + "psr20" + ], + "support": { + "source": "https://github.com/stella-maris-solutions/clock/tree/0.1.7" + }, + "time": "2022-11-25T16:15:06+00:00" + }, { "name": "superbalist/flysystem-google-storage", "version": "7.2.2", @@ -9377,28 +9461,28 @@ }, { "name": "symfony/amqp-messenger", - "version": "v5.4.28", + "version": "v6.0.19", "source": { "type": "git", "url": "https://github.com/symfony/amqp-messenger.git", - "reference": "24e5cc90da041e0e1b7bbe15b82ad7f27a508c01" + "reference": "14cd4f200a500ed91d05c3dd44322067cc522aaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/amqp-messenger/zipball/24e5cc90da041e0e1b7bbe15b82ad7f27a508c01", - "reference": "24e5cc90da041e0e1b7bbe15b82ad7f27a508c01", + "url": "https://api.github.com/repos/symfony/amqp-messenger/zipball/14cd4f200a500ed91d05c3dd44322067cc522aaf", + "reference": "14cd4f200a500ed91d05c3dd44322067cc522aaf", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/messenger": "^5.3|^6.0" + "ext-amqp": "*", + "php": ">=8.0.2", + "symfony/messenger": "^5.4|^6.0" }, "require-dev": { - "symfony/event-dispatcher": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/property-access": "^4.4|^5.0|^6.0", - "symfony/serializer": "^4.4|^5.0|^6.0" + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/property-access": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" }, "type": "symfony-messenger-bridge", "autoload": { @@ -9426,7 +9510,7 @@ "description": "Symfony AMQP extension Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/amqp-messenger/tree/v5.4.28" + "source": "https://github.com/symfony/amqp-messenger/tree/v6.0.19" }, "funding": [ { @@ -9442,7 +9526,7 @@ "type": "tidelift" } ], - "time": "2023-08-09T17:16:27+00:00" + "time": "2023-01-01T08:36:10+00:00" }, { "name": "symfony/asset", @@ -10109,32 +10193,31 @@ }, { "name": "symfony/doctrine-messenger", - "version": "v5.4.25", + "version": "v6.2.12", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-messenger.git", - "reference": "96bd1e093bfa8587205f4413193545c6685d7cd6" + "reference": "f8fb54b7325d0c3bcc2b1b1c70461eaa3dd7f0f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/96bd1e093bfa8587205f4413193545c6685d7cd6", - "reference": "96bd1e093bfa8587205f4413193545c6685d7cd6", + "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/f8fb54b7325d0c3bcc2b1b1c70461eaa3dd7f0f5", + "reference": "f8fb54b7325d0c3bcc2b1b1c70461eaa3dd7f0f5", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/messenger": "^5.1|^6.0", + "doctrine/dbal": "^2.13|^3.0", + "php": ">=8.1", + "symfony/messenger": "^5.4|^6.0", "symfony/service-contracts": "^1.1|^2|^3" }, "conflict": { - "doctrine/dbal": "<2.13", "doctrine/persistence": "<1.3" }, "require-dev": { - "doctrine/dbal": "^2.13|^3.0", "doctrine/persistence": "^1.3|^2|^3", - "symfony/property-access": "^4.4|^5.0|^6.0", - "symfony/serializer": "^4.4|^5.0|^6.0" + "symfony/property-access": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" }, "type": "symfony-messenger-bridge", "autoload": { @@ -10162,7 +10245,7 @@ "description": "Symfony Doctrine Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-messenger/tree/v5.4.25" + "source": "https://github.com/symfony/doctrine-messenger/tree/v6.2.12" }, "funding": [ { @@ -10178,7 +10261,7 @@ "type": "tidelift" } ], - "time": "2023-06-22T08:06:06+00:00" + "time": "2023-06-24T11:48:11+00:00" }, { "name": "symfony/dotenv", @@ -11026,38 +11109,31 @@ }, { "name": "symfony/intl", - "version": "v5.4.26", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "c26c40b64ecdc056810e294ea67ac5b34182cd69" + "reference": "1f8cb145c869ed089a8531c51a6a4b31ed0b3c69" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/c26c40b64ecdc056810e294ea67ac5b34182cd69", - "reference": "c26c40b64ecdc056810e294ea67ac5b34182cd69", + "url": "https://api.github.com/repos/symfony/intl/zipball/1f8cb145c869ed089a8531c51a6a4b31ed0b3c69", + "reference": "1f8cb145c869ed089a8531c51a6a4b31ed0b3c69", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1" }, "require-dev": { - "symfony/filesystem": "^4.4|^5.0|^6.0", + "symfony/filesystem": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", "symfony/var-exporter": "^5.4|^6.0" }, "type": "library", "autoload": { - "files": [ - "Resources/functions.php" - ], "psr-4": { "Symfony\\Component\\Intl\\": "" }, - "classmap": [ - "Resources/stubs" - ], "exclude-from-classmap": [ "/Tests/" ] @@ -11084,7 +11160,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a PHP replacement layer for the C intl extension that includes additional data from the ICU library", + "description": "Provides access to the localization data of the ICU library", "homepage": "https://symfony.com", "keywords": [ "i18n", @@ -11095,7 +11171,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v5.4.26" + "source": "https://github.com/symfony/intl/tree/v6.3.2" }, "funding": [ { @@ -11111,27 +11187,25 @@ "type": "tidelift" } ], - "time": "2023-07-13T09:02:54+00:00" + "time": "2023-07-20T07:43:09+00:00" }, { "name": "symfony/lock", - "version": "v5.4.25", + "version": "v6.1.11", "source": { "type": "git", "url": "https://github.com/symfony/lock.git", - "reference": "ed4055b2e03c8893ce2d0042c8f0e0707be8e179" + "reference": "cbc3366559a568ed56d9e7ed6d8e29a083eebb5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/lock/zipball/ed4055b2e03c8893ce2d0042c8f0e0707be8e179", - "reference": "ed4055b2e03c8893ce2d0042c8f0e0707be8e179", + "url": "https://api.github.com/repos/symfony/lock/zipball/cbc3366559a568ed56d9e7ed6d8e29a083eebb5b", + "reference": "cbc3366559a568ed56d9e7ed6d8e29a083eebb5b", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "psr/log": "^1|^2|^3" }, "conflict": { "doctrine/dbal": "<2.13" @@ -11174,7 +11248,7 @@ "semaphore" ], "support": { - "source": "https://github.com/symfony/lock/tree/v5.4.25" + "source": "https://github.com/symfony/lock/tree/v6.1.11" }, "funding": [ { @@ -11190,7 +11264,7 @@ "type": "tidelift" } ], - "time": "2023-06-22T08:06:06+00:00" + "time": "2023-01-01T08:36:55+00:00" }, { "name": "symfony/mailer", @@ -11678,29 +11752,27 @@ }, { "name": "symfony/password-hasher", - "version": "v5.4.27", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/password-hasher.git", - "reference": "6dd2daf41b44384752f6b59e8ad3e56ffb81e35c" + "reference": "d23ad221989e6b8278d050cabfd7b569eee84590" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/password-hasher/zipball/6dd2daf41b44384752f6b59e8ad3e56ffb81e35c", - "reference": "6dd2daf41b44384752f6b59e8ad3e56ffb81e35c", + "url": "https://api.github.com/repos/symfony/password-hasher/zipball/d23ad221989e6b8278d050cabfd7b569eee84590", + "reference": "d23ad221989e6b8278d050cabfd7b569eee84590", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php80": "^1.15" + "php": ">=8.1" }, "conflict": { - "symfony/security-core": "<5.3" + "symfony/security-core": "<5.4" }, "require-dev": { - "symfony/console": "^5.3|^6.0", - "symfony/security-core": "^5.3|^6.0" + "symfony/console": "^5.4|^6.0", + "symfony/security-core": "^5.4|^6.0" }, "type": "library", "autoload": { @@ -11732,7 +11804,7 @@ "password" ], "support": { - "source": "https://github.com/symfony/password-hasher/tree/v5.4.27" + "source": "https://github.com/symfony/password-hasher/tree/v6.3.0" }, "funding": [ { @@ -11748,7 +11820,7 @@ "type": "tidelift" } ], - "time": "2023-07-28T14:44:35+00:00" + "time": "2023-02-14T09:04:20+00:00" }, { "name": "symfony/polyfill-ctype", @@ -13013,26 +13085,26 @@ }, { "name": "symfony/redis-messenger", - "version": "v5.4.26", + "version": "v6.0.19", "source": { "type": "git", "url": "https://github.com/symfony/redis-messenger.git", - "reference": "55258642bca0d1869d147c85ee3277305549d5a3" + "reference": "75183a574bae512ae38beb0f3e623e6c4d708789" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/redis-messenger/zipball/55258642bca0d1869d147c85ee3277305549d5a3", - "reference": "55258642bca0d1869d147c85ee3277305549d5a3", + "url": "https://api.github.com/repos/symfony/redis-messenger/zipball/75183a574bae512ae38beb0f3e623e6c4d708789", + "reference": "75183a574bae512ae38beb0f3e623e6c4d708789", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/messenger": "^5.1|^6.0" + "ext-redis": "*", + "php": ">=8.0.2", + "symfony/messenger": "^5.4|^6.0" }, "require-dev": { - "symfony/property-access": "^4.4|^5.0|^6.0", - "symfony/serializer": "^4.4|^5.0|^6.0" + "symfony/property-access": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" }, "type": "symfony-messenger-bridge", "autoload": { @@ -13060,7 +13132,7 @@ "description": "Symfony Redis extension Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/redis-messenger/tree/v5.4.26" + "source": "https://github.com/symfony/redis-messenger/tree/v6.0.19" }, "funding": [ { @@ -13076,7 +13148,7 @@ "type": "tidelift" } ], - "time": "2023-07-19T20:11:33+00:00" + "time": "2023-01-01T08:36:10+00:00" }, { "name": "symfony/routing", @@ -13580,34 +13652,34 @@ }, { "name": "symfony/string", - "version": "v5.4.26", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "1181fe9270e373537475e826873b5867b863883c" + "reference": "d0a29e15c4225c128d8de89241f923345393c0cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/1181fe9270e373537475e826873b5867b863883c", - "reference": "1181fe9270e373537475e826873b5867b863883c", + "url": "https://api.github.com/repos/symfony/string/zipball/d0a29e15c4225c128d8de89241f923345393c0cf", + "reference": "d0a29e15c4225c128d8de89241f923345393c0cf", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "~1.15" + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/translation-contracts": ">=3.0" + "symfony/translation-contracts": "<2.0" }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/http-client": "^4.4|^5.0|^6.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0|^6.0" + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/intl": "^6.2", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" }, "type": "library", "autoload": { @@ -13646,7 +13718,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.26" + "source": "https://github.com/symfony/string/tree/v6.2.13" }, "funding": [ { @@ -13662,7 +13734,7 @@ "type": "tidelift" } ], - "time": "2023-06-28T12:46:07+00:00" + "time": "2023-07-05T08:41:15+00:00" }, { "name": "symfony/translation", @@ -14164,39 +14236,33 @@ }, { "name": "symfony/var-dumper", - "version": "v5.4.28", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "684b36ff415e1381d4a943c3ca2502cd2debad73" + "reference": "34e5ca671222670ae00749d1f554713021f8ef63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/684b36ff415e1381d4a943c3ca2502cd2debad73", - "reference": "684b36ff415e1381d4a943c3ca2502cd2debad73", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/34e5ca671222670ae00749d1f554713021f8ef63", + "reference": "34e5ca671222670ae00749d1f554713021f8ef63", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/console": "<4.4" + "symfony/console": "<5.4" }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^4.4|^5.0|^6.0", - "symfony/http-kernel": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/uid": "^5.1|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", "twig/twig": "^2.13|^3.0.4" }, - "suggest": { - "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump", - "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" - }, "bin": [ "Resources/bin/var-dump-server" ], @@ -14233,7 +14299,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.4.28" + "source": "https://github.com/symfony/var-dumper/tree/v6.3.2" }, "funding": [ { @@ -14249,7 +14315,7 @@ "type": "tidelift" } ], - "time": "2023-08-24T13:38:36+00:00" + "time": "2023-07-21T07:05:52+00:00" }, { "name": "symfony/var-exporter", diff --git a/src/Components/RefundManager/Builder/RefundDataBuilder.php b/src/Components/RefundManager/Builder/RefundDataBuilder.php index 253d6695f..841c6e00b 100644 --- a/src/Components/RefundManager/Builder/RefundDataBuilder.php +++ b/src/Components/RefundManager/Builder/RefundDataBuilder.php @@ -76,7 +76,7 @@ public function buildRefundData(OrderEntity $order, Context $context): RefundDat try { - $refunds = $this->refundService->getRefunds($order); + $refunds = $this->refundService->getRefunds($order, $context); } catch (PaymentNotFoundException $ex) { # if we dont have a payment, then theres also no refunds # we still need our data, only with an empty list of refunds diff --git a/src/Components/RefundManager/DAL/OrderLineItem/OrderLineItemExtension.php b/src/Components/RefundManager/DAL/OrderLineItem/OrderLineItemExtension.php new file mode 100644 index 000000000..d1aff6f9d --- /dev/null +++ b/src/Components/RefundManager/DAL/OrderLineItem/OrderLineItemExtension.php @@ -0,0 +1,35 @@ +add(new OneToManyAssociationField(self::ORDER_LINE_ITEM_PROPERTY_NAME, RefundItemDefinition::class, 'order_line_item_id')); + } +} diff --git a/src/Components/RefundManager/DAL/Refund/RefundDefinition.php b/src/Components/RefundManager/DAL/Refund/RefundDefinition.php index 659281033..019de024f 100644 --- a/src/Components/RefundManager/DAL/Refund/RefundDefinition.php +++ b/src/Components/RefundManager/DAL/Refund/RefundDefinition.php @@ -3,6 +3,7 @@ namespace Kiener\MolliePayments\Components\RefundManager\DAL\Refund; +use Kiener\MolliePayments\Components\RefundManager\DAL\RefundItem\RefundItemDefinition; use Shopware\Core\Checkout\Order\OrderDefinition; use Shopware\Core\Framework\DataAbstractionLayer\EntityDefinition; use Shopware\Core\Framework\DataAbstractionLayer\Field\FkField; @@ -10,6 +11,7 @@ use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\Required; use Shopware\Core\Framework\DataAbstractionLayer\Field\IdField; use Shopware\Core\Framework\DataAbstractionLayer\Field\LongTextField; +use Shopware\Core\Framework\DataAbstractionLayer\Field\OneToManyAssociationField; use Shopware\Core\Framework\DataAbstractionLayer\Field\ReferenceVersionField; use Shopware\Core\Framework\DataAbstractionLayer\Field\StringField; use Shopware\Core\Framework\DataAbstractionLayer\FieldCollection; @@ -59,6 +61,7 @@ protected function defineFields(): FieldCollection new LongTextField('public_description', 'publicDescription'), new LongTextField('internal_description', 'internalDescription'), + new OneToManyAssociationField('refundItems', RefundItemDefinition::class, 'refund_id') ]); } } diff --git a/src/Components/RefundManager/DAL/Refund/RefundEntity.php b/src/Components/RefundManager/DAL/Refund/RefundEntity.php index 02c0ccada..a81ddccbc 100644 --- a/src/Components/RefundManager/DAL/Refund/RefundEntity.php +++ b/src/Components/RefundManager/DAL/Refund/RefundEntity.php @@ -2,6 +2,7 @@ namespace Kiener\MolliePayments\Components\RefundManager\DAL\Refund; +use Kiener\MolliePayments\Components\RefundManager\DAL\RefundItem\RefundItemCollection; use Shopware\Core\Framework\DataAbstractionLayer\Entity; use Shopware\Core\Framework\DataAbstractionLayer\EntityIdTrait; @@ -36,6 +37,17 @@ class RefundEntity extends Entity */ protected $internalDescription; + /** + * @var RefundItemCollection + */ + protected $refundItems; + + public function __construct() + { + $this->refundItems = new RefundItemCollection(); + } + + /** * @return string */ @@ -120,4 +132,20 @@ public function setInternalDescription(?string $internalDescription): void { $this->internalDescription = $internalDescription; } + + /** + * @return RefundItemCollection + */ + public function getRefundItems(): RefundItemCollection + { + return $this->refundItems; + } + + /** + * @param RefundItemCollection $refundItems + */ + public function setRefundItems(RefundItemCollection $refundItems): void + { + $this->refundItems = $refundItems; + } } diff --git a/src/Components/RefundManager/DAL/RefundItem/RefundItemCollection.php b/src/Components/RefundManager/DAL/RefundItem/RefundItemCollection.php new file mode 100644 index 000000000..a0a896785 --- /dev/null +++ b/src/Components/RefundManager/DAL/RefundItem/RefundItemCollection.php @@ -0,0 +1,17 @@ + + */ +final class RefundItemCollection extends EntityCollection +{ + protected function getExpectedClass(): string + { + return RefundItemEntity::class; + } +} diff --git a/src/Components/RefundManager/DAL/RefundItem/RefundItemDefinition.php b/src/Components/RefundManager/DAL/RefundItem/RefundItemDefinition.php new file mode 100644 index 000000000..4ccbc7132 --- /dev/null +++ b/src/Components/RefundManager/DAL/RefundItem/RefundItemDefinition.php @@ -0,0 +1,58 @@ +addFlags(new Required(), new PrimaryKey(), new ApiAware()), + (new StringField('type', 'type'))->addFlags(new Required(), new ApiAware()), + (new FkField('refund_id', 'refundId', RefundDefinition::class))->addFlags(new ApiAware()), + (new ManyToOneAssociationField('refund', 'refund_id', RefundDefinition::class))->addFlags(new ApiAware()), + (new IntField('quantity', 'quantity'))->addFlags(new Required(), new ApiAware()), + (new StringField('label', 'label'))->addFlags(new ApiAware()), + (new FloatField('amount', 'amount'))->addFlags(new Required(), new ApiAware()), + (new StringField('mollie_line_id', 'mollieLineId'))->addFlags(new Required(), new ApiAware()), + (new FkField('order_line_item_id', 'orderLineItemId', OrderLineItemDefinition::class))->addFlags(new ApiAware()), + new ReferenceVersionField(OrderLineItemDefinition::class, 'order_line_item_version_id'), + (new ManyToOneAssociationField('orderLineItem', 'order_line_item_id', OrderLineItemDefinition::class))->addFlags(new ApiAware()), + ]); + } +} diff --git a/src/Components/RefundManager/DAL/RefundItem/RefundItemEntity.php b/src/Components/RefundManager/DAL/RefundItem/RefundItemEntity.php new file mode 100644 index 000000000..50f8fb98c --- /dev/null +++ b/src/Components/RefundManager/DAL/RefundItem/RefundItemEntity.php @@ -0,0 +1,257 @@ +type; + } + + /** + * @param string $type + */ + public function setType(string $type): void + { + $this->type = $type; + } + + /** + * @return string + */ + public function getRefundId(): string + { + return $this->refundId; + } + + /** + * @param string $refundId + */ + public function setRefundId(string $refundId): void + { + $this->refundId = $refundId; + } + + /** + * @return string + */ + public function getMollieLineId(): string + { + return $this->mollieLineId; + } + + /** + * @param string $mollieLineId + */ + public function setMollieLineId(string $mollieLineId): void + { + $this->mollieLineId = $mollieLineId; + } + + /** + * @return int + */ + public function getQuantity(): int + { + return $this->quantity; + } + + /** + * @param int $quantity + */ + public function setQuantity(int $quantity): void + { + $this->quantity = $quantity; + } + + /** + * @return float + */ + public function getAmount(): float + { + return $this->amount; + } + + /** + * @param float $amount + */ + public function setAmount(float $amount): void + { + $this->amount = $amount; + } + + /** + * @return string + */ + public function getOrderLineItemId(): ?string + { + return $this->orderLineItemId; + } + + /** + * @param string $orderLineItemId + */ + public function setOrderLineItemId(string $orderLineItemId): void + { + $this->orderLineItemId = $orderLineItemId; + } + + /** + * @return null|OrderLineItemEntity + */ + public function getOrderLineItem(): ?OrderLineItemEntity + { + return $this->orderLineItem; + } + + /** + * @param OrderLineItemEntity $orderLineItem + */ + public function setOrderLineItem(OrderLineItemEntity $orderLineItem): void + { + $this->orderLineItem = $orderLineItem; + } + + /** + * @return null|RefundEntity + */ + public function getRefund(): ?RefundEntity + { + return $this->refund; + } + + /** + * @param null|RefundEntity $refund + */ + public function setRefund(?RefundEntity $refund): void + { + $this->refund = $refund; + } + + /** + * @return string + */ + public function getLabel(): string + { + return $this->label; + } + + /** + * @param string $label + */ + public function setLabel(string $label): void + { + $this->label = $label; + } + + /** + * @return null|string + */ + public function getOrderLineItemVersionId(): ?string + { + return $this->orderLineItemVersionId; + } + + /** + * @param null|string $orderLineItemVersionId + */ + public function setOrderLineItemVersionId(?string $orderLineItemVersionId): void + { + $this->orderLineItemVersionId = $orderLineItemVersionId; + } + + /** + * @param string $type + * @param string $mollieLineId + * @param string $label + * @param int $quantity + * @param float $amount + * @param null|string $oderLineItemId + * @param null|string $oderLineItemVersionId + * @param null|string $refundId + * @return array + */ + public static function createEntryArray(string $type, string $mollieLineId, string $label, int $quantity, float $amount, ?string $oderLineItemId, ?string $oderLineItemVersionId, ?string $refundId): array + { + $row = [ + 'type' => $type, + 'mollieLineId' => $mollieLineId, + 'label' => $label, + 'quantity' => $quantity, + 'amount' => $amount, + 'oderLineItemId' => $oderLineItemId, + 'oderLineItemVersionId' => $oderLineItemVersionId, + ]; + + /** + * refundId is not given when we create a new entry because the id is created by shopware dal + */ + if ($refundId !== null) { + $row['refundId'] = $refundId; + } + + return $row; + } +} diff --git a/src/Components/RefundManager/RefundData/RefundData.php b/src/Components/RefundManager/RefundData/RefundData.php index b96c93cd3..2b95550ed 100644 --- a/src/Components/RefundManager/RefundData/RefundData.php +++ b/src/Components/RefundManager/RefundData/RefundData.php @@ -2,6 +2,7 @@ namespace Kiener\MolliePayments\Components\RefundManager\RefundData; +use Kiener\MolliePayments\Components\RefundManager\DAL\RefundItem\RefundItemEntity; use Kiener\MolliePayments\Components\RefundManager\RefundData\OrderItem\AbstractItem; use Mollie\Api\Resources\Refund; @@ -135,10 +136,10 @@ public function toArray() /** @var array $refundsArray */ $refundsArray = $this->refunds; foreach ($refundsArray as $refundIndex => $refund) { - if (isset($refund['metadata']['composition']) && is_array($refund['metadata']['composition'])) { - foreach ($refund['metadata']['composition'] as $compositionIndex => $composition) { + if (isset($refund['metadata']) && property_exists($refund['metadata'], 'composition') && is_array($refund['metadata']->composition)) { + foreach ($refund['metadata']->composition as $compositionIndex => $composition) { if ((bool)$composition['swReference'] === false) { - $refundsArray[$refundIndex]['metadata']['composition'][$compositionIndex]['label'] = self::ROUNDING_ITEM_LABEL; + $refundsArray[$refundIndex]['metadata']->composition[$compositionIndex]['label'] = self::ROUNDING_ITEM_LABEL; } } } diff --git a/src/Components/RefundManager/RefundManager.php b/src/Components/RefundManager/RefundManager.php index 1e5ab2651..f3df010e9 100644 --- a/src/Components/RefundManager/RefundManager.php +++ b/src/Components/RefundManager/RefundManager.php @@ -6,6 +6,7 @@ use Kiener\MolliePayments\Compatibility\Bundles\FlowBuilder\FlowBuilderEventFactory; use Kiener\MolliePayments\Compatibility\Bundles\FlowBuilder\FlowBuilderFactoryInterface; use Kiener\MolliePayments\Components\RefundManager\Builder\RefundDataBuilder; +use Kiener\MolliePayments\Components\RefundManager\DAL\RefundItem\RefundItemEntity; use Kiener\MolliePayments\Components\RefundManager\DAL\Repository\RefundRepositoryInterface; use Kiener\MolliePayments\Components\RefundManager\Integrators\StockManagerInterface; use Kiener\MolliePayments\Components\RefundManager\RefundData\RefundData; @@ -13,9 +14,12 @@ use Kiener\MolliePayments\Components\RefundManager\Request\RefundRequestItem; use Kiener\MolliePayments\Components\RefundManager\Request\RefundRequestItemRoundingDiff; use Kiener\MolliePayments\Exception\CouldNotCreateMollieRefundException; +use Kiener\MolliePayments\Service\MollieApi\Fixer\RoundingDifferenceFixer; use Kiener\MolliePayments\Service\MollieApi\Order; use Kiener\MolliePayments\Service\OrderServiceInterface; use Kiener\MolliePayments\Service\Refund\Item\RefundItem; +use Kiener\MolliePayments\Service\Refund\Item\RefundItemType; +use Kiener\MolliePayments\Service\Refund\Mollie\DataCompressor; use Kiener\MolliePayments\Service\Refund\RefundServiceInterface; use Kiener\MolliePayments\Struct\MollieApi\OrderLineMetaDataStruct; use Kiener\MolliePayments\Struct\Order\OrderAttributes; @@ -127,6 +131,7 @@ public function refund(OrderEntity $order, RefundRequest $request, Context $cont /** @var null|\Mollie\Api\Resources\Order $mollieOrder */ $mollieOrder = null; + $refundType = ''; if ($orderAttributes->isTypeSubscription()) { # pure subscription orders do not @@ -165,6 +170,7 @@ public function refund(OrderEntity $order, RefundRequest $request, Context $cont if ($orderAttributes->isTypeSubscription()) { + $refundType = RefundItemType::PARTIAL; # we only have a transaction in the case of a subscription $refund = $this->refundService->refundPartial( $order, @@ -175,6 +181,7 @@ public function refund(OrderEntity $order, RefundRequest $request, Context $cont $context ); } else { + $refundType = RefundItemType::FULL; $refund = $this->refundService->refundFull( $order, $request->getDescription(), @@ -186,6 +193,7 @@ public function refund(OrderEntity $order, RefundRequest $request, Context $cont } elseif ($request->isFullRefundWithItems($order)) { $this->appendRoundingItemFromMollieOrder($request, $mollieOrder); $serviceItems = $this->convertToRefundItems($request, $order, $mollieOrder); + $refundType = RefundItemType::FULL; $refund = $this->refundService->refundFull( $order, $request->getDescription(), @@ -194,6 +202,7 @@ public function refund(OrderEntity $order, RefundRequest $request, Context $cont $context ); } elseif ($request->isPartialAmountOnly()) { + $refundType = RefundItemType::PARTIAL; $refund = $this->refundService->refundPartial( $order, $request->getDescription(), @@ -203,6 +212,7 @@ public function refund(OrderEntity $order, RefundRequest $request, Context $cont $context ); } elseif ($request->isPartialAmountWithItems($order)) { + $refundType = RefundItemType::PARTIAL; $refund = $this->refundService->refundPartial( $order, $request->getDescription(), @@ -213,8 +223,7 @@ public function refund(OrderEntity $order, RefundRequest $request, Context $cont ); } - - if (!$refund instanceof Refund) { + if (! $refund instanceof Refund) { # a problem happened, lets finish with an exception throw new CouldNotCreateMollieRefundException('', (string)$order->getOrderNumber()); } @@ -222,20 +231,22 @@ public function refund(OrderEntity $order, RefundRequest $request, Context $cont $refundAmount = (float)$refund->amount->value; + + $refundData = [ + 'orderId' => $order->getId(), + 'orderVersionId' => $order->getVersionId(), + 'mollieRefundId' => $refund->id, + 'publicDescription' => $request->getDescription(), + 'internalDescription' => $request->getInternalDescription(), + + ]; + $refundItems = $this->convertToRepositoryArray($serviceItems, $refundType); + if (count($refundItems) > 0) { + $refundData['refundItems'] = $refundItems; + } # SAVE LOCAL REFUND # --------------------------------------------------------------------------------------------- - $this->refundRepository->create( - [ - [ - 'orderId' => $order->getId(), - 'orderVersionId' => $order->getVersionId(), - 'mollieRefundId' => $refund->id, - 'publicDescription' => $request->getDescription(), - 'internalDescription' => $request->getInternalDescription(), - ] - ], - $context - ); + $this->refundRepository->create([$refundData], $context); # DISPATCH FLOW BUILDER @@ -379,8 +390,9 @@ private function convertToRefundItems(RefundRequest $request, OrderEntity $order foreach ($request->getItems() as $requestItem) { $mollieLineID = ''; - $shopwareReferenceID = ''; - + $shopwareReferenceID = RoundingDifferenceFixer::DEFAULT_TITLE; + $orderLineItemId = null; + $orderLineItemVersionId = null; $orderItem = $this->getOrderItem($order, $requestItem->getLineId()); # if we have a real line item, then extract @@ -388,11 +400,11 @@ private function convertToRefundItems(RefundRequest $request, OrderEntity $order if ($orderItem instanceof OrderLineItemEntity) { $orderItemAttributes = new OrderLineItemEntityAttributes($orderItem); $mollieLineID = $orderItemAttributes->getMollieOrderLineID(); - + $orderLineItemId = $orderItem->getId(); + $orderLineItemVersionId = $orderItem->getVersionId(); + $shopwareReferenceID = (string)$orderItem->getReferencedId(); if (isset($orderItem->getPayload()['productNumber'])) { $shopwareReferenceID = (string)$orderItem->getPayload()['productNumber']; - } else { - $shopwareReferenceID = (string)$orderItem->getReferencedId(); } } else { # yeah i know complexity...but for now lets keep it compact :) @@ -431,14 +443,43 @@ private function convertToRefundItems(RefundRequest $request, OrderEntity $order # for our refund service with all # required information $serviceItems[] = new RefundItem( - $requestItem->getLineId(), $mollieLineID, (string)$shopwareReferenceID, $requestItem->getQuantity(), - $requestItem->getAmount() + $requestItem->getAmount(), + $orderLineItemId, + $orderLineItemVersionId ); } return $serviceItems; } + + /** + * @param RefundItem[] $serviceItems + * @param string $type + * @return array + */ + private function convertToRepositoryArray(array $serviceItems, string $type): array + { + $data = []; + foreach ($serviceItems as $item) { + if ($item->getQuantity() <= 0) { + continue; + } + $row = RefundItemEntity::createEntryArray( + $type, + $item->getMollieLineID(), + $item->getShopwareReference(), + $item->getQuantity(), + $item->getAmount(), + $item->getShopwareLineID(), + $item->getShopwareLineVersionId(), + null + ); + + $data[] = $row; + } + return $data; + } } diff --git a/src/Controller/Api/Order/RefundControllerBase.php b/src/Controller/Api/Order/RefundControllerBase.php index db9ff91b5..d8a69c6fd 100644 --- a/src/Controller/Api/Order/RefundControllerBase.php +++ b/src/Controller/Api/Order/RefundControllerBase.php @@ -267,7 +267,7 @@ private function listRefundsAction(string $orderId, Context $context): JsonRespo try { $order = $this->orderService->getOrder($orderId, $context); - $refunds = $this->refundService->getRefunds($order); + $refunds = $this->refundService->getRefunds($order, $context); return $this->json($refunds); } catch (\Throwable $e) { diff --git a/src/Hydrator/RefundHydrator.php b/src/Hydrator/RefundHydrator.php index 20ce941ad..d5f3ae6f4 100644 --- a/src/Hydrator/RefundHydrator.php +++ b/src/Hydrator/RefundHydrator.php @@ -3,8 +3,10 @@ namespace Kiener\MolliePayments\Hydrator; use Kiener\MolliePayments\Components\RefundManager\DAL\Order\OrderExtension; +use Kiener\MolliePayments\Components\RefundManager\DAL\OrderLineItem\OrderLineItemExtension; use Kiener\MolliePayments\Components\RefundManager\DAL\Refund\RefundCollection; use Kiener\MolliePayments\Components\RefundManager\DAL\Refund\RefundEntity; +use Kiener\MolliePayments\Components\RefundManager\DAL\RefundItem\RefundItemEntity; use Mollie\Api\Resources\Refund; use Shopware\Core\Checkout\Order\OrderEntity; @@ -33,14 +35,17 @@ public function hydrate(Refund $refund, OrderEntity $order): array ]; } - $metaData = []; + $metaData = new \stdClass(); - if (property_exists($refund, 'metadata')) { - # @phpstan-ignore-next-line - $metaData = (string)$refund->metadata; - $metaData = json_decode($metaData, true); + if (property_exists($refund, 'metadata') && $refund->metadata !== null) { + /** @var \stdClass|string $metaData */ + $metaData = $refund->metadata; + if (is_string($metaData)) { + $metaData = json_decode($metaData); + } } + $internalDescription = null; /** @var RefundCollection $shopwareRefunds */ @@ -54,9 +59,28 @@ public function hydrate(Refund $refund, OrderEntity $order): array $shopwareRefund = $shopwareRefunds->first(); if ($shopwareRefund !== null) { $internalDescription = $shopwareRefund->getInternalDescription(); + + $refundLineItems = $shopwareRefund->getRefundItems()->getElements(); + + $metaData->composition = []; + /** @var RefundItemEntity $refundLineItem */ + foreach ($refundLineItems as $refundLineItem) { + $metaData->type = $refundLineItem->getType(); + $metaData->composition[]=[ + 'swLineId' => (string)$refundLineItem->getOrderLineItemId(), + 'swLineVersionId' => (string)$refundLineItem->getOrderLineItemVersionId(), + 'mollieLineId' => $refundLineItem->getMollieLineId(), + 'swReference' => $refundLineItem->getLabel(), + 'quantity' => $refundLineItem->getQuantity(), + 'amount' => $refundLineItem->getAmount() + ]; + } } } + + + return [ 'id' => $refund->id, 'orderId' => $refund->orderId, diff --git a/src/Migration/Migration1644753635CreateSubscription.php b/src/Migration/Migration1644753635CreateSubscription.php index 9d7b3acce..ecb748eb9 100755 --- a/src/Migration/Migration1644753635CreateSubscription.php +++ b/src/Migration/Migration1644753635CreateSubscription.php @@ -4,9 +4,7 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Exception; -use Shopware\Core\Defaults; use Shopware\Core\Framework\Migration\MigrationStep; -use Shopware\Core\Framework\Uuid\Uuid; class Migration1644753635CreateSubscription extends MigrationStep { diff --git a/src/Migration/Migration1672671475RefundItem.php b/src/Migration/Migration1672671475RefundItem.php new file mode 100644 index 000000000..f8a7385ea --- /dev/null +++ b/src/Migration/Migration1672671475RefundItem.php @@ -0,0 +1,44 @@ +executeStatement($sql); + } + + public function updateDestructive(Connection $connection): void + { + // implement update destructive + } +} diff --git a/src/MolliePayments.php b/src/MolliePayments.php index 6af32bd77..35e8d0959 100644 --- a/src/MolliePayments.php +++ b/src/MolliePayments.php @@ -88,14 +88,13 @@ public function configureRoutes(RoutingConfigurator $routes, string $environment public function install(InstallContext $context): void { parent::install($context); - - /** @var ContainerInterface $container */ - $container = $this->container; - + if ($this->container === null) { + throw new Exception('Container is not initialized'); + } # that's the only part we use the Shopware repository directly, # and not our custom one, because our repositories are not yet registered in this function /** @var EntityRepository $shopwareRepoCustomFields */ - $shopwareRepoCustomFields = $container->get('custom_field_set.repository'); + $shopwareRepoCustomFields = $this->container->get('custom_field_set.repository'); if ($shopwareRepoCustomFields !== null) { $mollieRepoCustomFields = new CustomFieldSetRepository($shopwareRepoCustomFields); @@ -170,11 +169,11 @@ public function deactivate(DeactivateContext $context): void */ private function preparePlugin(Context $context): void { - /** @var ContainerInterface $container */ - $container = $this->container; - + if ($this->container === null) { + throw new Exception('Container is not initialized'); + } /** @var PluginInstaller $pluginInstaller */ - $pluginInstaller = $container->get(PluginInstaller::class); + $pluginInstaller = $this->container->get(PluginInstaller::class); $pluginInstaller->install($context); } diff --git a/src/Resources/config/services/refundmanager/services.xml b/src/Resources/config/services/refundmanager/services.xml index 72ea420ff..3e6ae3a34 100644 --- a/src/Resources/config/services/refundmanager/services.xml +++ b/src/Resources/config/services/refundmanager/services.xml @@ -8,9 +8,16 @@ - + + + + + + + + diff --git a/src/Resources/config/services/services.xml b/src/Resources/config/services/services.xml index 206ff60d2..7b021e49a 100644 --- a/src/Resources/config/services/services.xml +++ b/src/Resources/config/services/services.xml @@ -67,8 +67,15 @@ + + + + + + + @@ -178,5 +185,8 @@ + + + diff --git a/src/Resources/config/services/subscription/services.xml b/src/Resources/config/services/subscription/services.xml index 4c1b0ef9a..3319e5aab 100755 --- a/src/Resources/config/services/subscription/services.xml +++ b/src/Resources/config/services/subscription/services.xml @@ -37,6 +37,7 @@ + diff --git a/src/Service/MollieApi/Fixer/RoundingDifferenceFixer.php b/src/Service/MollieApi/Fixer/RoundingDifferenceFixer.php index 1203963a0..3f70ce6f8 100644 --- a/src/Service/MollieApi/Fixer/RoundingDifferenceFixer.php +++ b/src/Service/MollieApi/Fixer/RoundingDifferenceFixer.php @@ -9,7 +9,7 @@ class RoundingDifferenceFixer { - private const DEFAULT_TITLE = 'Automatic Rounding Difference'; + public const DEFAULT_TITLE = 'Automatic Rounding Difference'; private const DEFAULT_SKU = ''; diff --git a/src/Service/OrderService.php b/src/Service/OrderService.php index 02a6941dd..46def6f4a 100644 --- a/src/Service/OrderService.php +++ b/src/Service/OrderService.php @@ -3,6 +3,7 @@ namespace Kiener\MolliePayments\Service; use Kiener\MolliePayments\Components\RefundManager\DAL\Order\OrderExtension; +use Kiener\MolliePayments\Components\RefundManager\DAL\OrderLineItem\OrderLineItemExtension; use Kiener\MolliePayments\Exception\CouldNotExtractMollieOrderIdException; use Kiener\MolliePayments\Exception\CouldNotExtractMollieOrderLineIdException; use Kiener\MolliePayments\Exception\OrderNumberNotFoundException; @@ -103,7 +104,7 @@ public function getOrder(string $orderId, Context $context): OrderEntity $criteria->addAssociation('transactions.paymentMethod'); $criteria->addAssociation('transactions.paymentMethod.appPaymentMethod.app'); $criteria->addAssociation('transactions.stateMachineState'); - $criteria->addAssociation(OrderExtension::REFUND_PROPERTY_NAME); # for refund manager + $criteria->addAssociation(OrderExtension::REFUND_PROPERTY_NAME.'.refundItems'); # for refund manager $order = $this->orderRepository->search($criteria, $context)->first(); diff --git a/src/Service/Refund/CompositionMigrationService.php b/src/Service/Refund/CompositionMigrationService.php new file mode 100644 index 000000000..fc83579eb --- /dev/null +++ b/src/Service/Refund/CompositionMigrationService.php @@ -0,0 +1,172 @@ +refundItemRepository = $refundItemRepository; + } + + public function updateRefundItems(Refund $refund, OrderEntity $order, Context $context): OrderEntity + { + /** @var \stdClass|string $oldMetadata */ + $oldMetadata = $refund->metadata; + if (! is_string($oldMetadata)) { + return $order; + } + + $oldMetadata = json_decode($oldMetadata); + if (! property_exists($oldMetadata, 'composition') && ! is_array($oldMetadata->composition)) { + return $order; + } + + $oldCompositions = $oldMetadata->composition; + + /** @var ?RefundCollection $shopwareRefunds */ + $shopwareRefunds = $order->getExtension(OrderExtension::REFUND_PROPERTY_NAME); + + if ($shopwareRefunds === null) { + return $order; + } + + + $shopwareRefunds = $shopwareRefunds->filterByProperty('mollieRefundId', $refund->id); + + /** @var ?RefundEntity $shopwareRefund */ + $shopwareRefund = $shopwareRefunds->first(); + + if ($shopwareRefund === null) { + return $order; + } + + $refundLineItems = $shopwareRefund->getRefundItems()->getElements(); + + /** + * Exit criteria, if we have refund line items, then we exit here + */ + if (count($refundLineItems) > 0) { + return $order; + } + + /** @var ?OrderLineItemCollection $orderLineItems */ + $orderLineItems = $order->getLineItems(); + if ($orderLineItems === null) { + return $order; + } + + $dataToSave = []; + foreach ($oldCompositions as $composition) { + $label = $composition->swReference; + if (strlen($label) === 0) { + $label = RoundingDifferenceFixer::DEFAULT_TITLE; + } + + $orderLineItemId = null; + $orderLineItemVersionId = null; + $orderLineItem = $this->filterByMollieId($orderLineItems, $composition->mollieLineId); + + if ($orderLineItem instanceof OrderLineItemEntity) { + $orderLineItemId = $orderLineItem->getId(); + $orderLineItemVersionId = $orderLineItem->getVersionId(); + } + + $row = RefundItemEntity::createEntryArray( + $oldMetadata->type, + $composition->mollieLineId, + $label, + $composition->quantity, + $composition->amount, + $orderLineItemId, + $orderLineItemVersionId, + $shopwareRefund->getId() + ); + + $dataToSave[] = $row; + } + + $entityWrittenContainerEvent = $this->refundItemRepository->create($dataToSave, $context); + + /** + * get the new inserted data from the written container event and create a new refund items collection and assign it to the refund. + * php is using here copy by reference so the order will have the new line items inside the refund and we do not need to reload the order entity again + */ + $refundItems = $this->createEntitiesByEvent($entityWrittenContainerEvent); + $shopwareRefund->setRefundItems($refundItems); + return $order; + } + + private function createEntitiesByEvent(EntityWrittenContainerEvent $event): RefundItemCollection + { + $collection = new RefundItemCollection(); + $events = $event->getEvents(); + if ($events === null) { + return $collection; + } + /** @var EntityWrittenEvent $writtenEvent */ + $writtenEvent = $events->first(); + $results = $writtenEvent->getWriteResults(); + + foreach ($results as $result) { + $entity = new RefundItemEntity(); + $entity->setId($result->getProperty('id')); + $entity->setUniqueIdentifier($result->getProperty('id')); + $entity->setQuantity($result->getProperty('quantity')); + $entity->setLabel($result->getProperty('label')); + $entity->setAmount($result->getProperty('amount')); + $entity->setRefundId($result->getProperty('refundId')); + $entity->setMollieLineId($result->getProperty('mollieLineId')); + if ($result->getProperty('orderLineItemId') !== null && $result->getProperty('orderLineItemVersionId') !== null) { + $entity->setOrderLineItemId($result->getProperty('orderLineItemId')); + $entity->setOrderLineItemVersionId($result->getProperty('orderLineItemVersionId')); + } + + $entity->setType($result->getProperty('type')); + $entity->setCreatedAt($result->getProperty('createdAt')); + $collection->add($entity); + } + return $collection; + } + + private function filterByMollieId(OrderLineItemCollection $lineItems, string $mollieLineId): ?OrderLineItemEntity + { + $foundItem = null; + /** @var OrderLineItemEntity $lineItem */ + foreach ($lineItems as $lineItem) { + $customFields = $lineItem->getCustomFields(); + if ($customFields === null) { + continue; + } + if (! isset($customFields['mollie_payments']['order_line_id'])) { + continue; + } + if ($customFields['mollie_payments']['order_line_id'] === $mollieLineId) { + $foundItem = $lineItem; + break; + } + } + return $foundItem; + } +} diff --git a/src/Service/Refund/CompositionMigrationServiceInterface.php b/src/Service/Refund/CompositionMigrationServiceInterface.php new file mode 100644 index 000000000..9c690e36c --- /dev/null +++ b/src/Service/Refund/CompositionMigrationServiceInterface.php @@ -0,0 +1,13 @@ +shopwareLineID = $shopwareLineID; $this->mollieLineID = $mollieLineID; $this->shopwareReference = $shopwareReference; $this->quantity = $quantity; $this->amount = round($amount, 2); + $this->shopwareLineVersionId = $shopwareLineVersionId; } /** * @return string */ - public function getShopwareLineID(): string + public function getShopwareLineID(): ?string { return $this->shopwareLineID; } @@ -86,4 +91,12 @@ public function getMollieLineID(): string { return $this->mollieLineID; } + + /** + * @return null|string + */ + public function getShopwareLineVersionId(): ?string + { + return $this->shopwareLineVersionId; + } } diff --git a/src/Service/Refund/Mollie/DataCompressor.php b/src/Service/Refund/Mollie/DataCompressor.php deleted file mode 100644 index f082ce86a..000000000 --- a/src/Service/Refund/Mollie/DataCompressor.php +++ /dev/null @@ -1,37 +0,0 @@ -= will be compressed - */ - private const LENGTH_THRESHOLD = 32; - - /** - * this is the length of the part in the - * beginning and end of the string to be compressed. - * this value * 2 is the final length - */ - private const LENGTH_PARTS = 4; - - - /** - * @param string $value - * @return string - */ - public function compress(string $value): string - { - if (strlen($value) < self::LENGTH_THRESHOLD) { - return $value; - } - - $firstPart = substr($value, 0, self::LENGTH_PARTS); - $lastPart = substr($value, -self::LENGTH_PARTS); - - return $firstPart . $lastPart; - } -} diff --git a/src/Service/Refund/Mollie/RefundMetadata.php b/src/Service/Refund/Mollie/RefundMetadata.php index 546ecf33b..857ce1a10 100644 --- a/src/Service/Refund/Mollie/RefundMetadata.php +++ b/src/Service/Refund/Mollie/RefundMetadata.php @@ -6,10 +6,6 @@ class RefundMetadata { - /** - * @var DataCompressor - */ - private $dataCompression; /** * @var string @@ -31,28 +27,27 @@ public function __construct(string $type, array $items) { $this->type = $type; $this->items = $items; - - $this->dataCompression = new DataCompressor(); } /** - * @param array $metadata + * @param \stdClass $metadata * @return RefundMetadata */ - public static function fromArray(array $metadata): RefundMetadata + public static function fromArray(\stdClass $metadata): RefundMetadata { - $type = (string)$metadata['type']; - $composition = (isset($metadata['composition'])) ? (array)$metadata['composition'] : []; + $type = (string)$metadata->type; + $composition = property_exists($metadata, 'composition') ? $metadata->composition : []; $items = []; foreach ($composition as $compItem) { $items[] = new RefundItem( - $compItem['swLineId'], $compItem['mollieLineId'], - $compItem['swReference'], + (string)$compItem['swReference'], $compItem['quantity'], - $compItem['amount'] + $compItem['amount'], + $compItem['swLineId'], + $compItem['swLineVersionId'] ); } @@ -74,28 +69,4 @@ public function getComposition(): array { return $this->items; } - - /** - * @return string - */ - public function toString(): string - { - $data = [ - 'type' => $this->type, - ]; - - foreach ($this->items as $item) { - $swLineId = $this->dataCompression->compress($item->getShopwareLineID()); - - $data['composition'][] = [ - 'swLineId' => $swLineId, - 'mollieLineId' => $item->getMollieLineID(), - 'swReference' => $item->getShopwareReference(), - 'quantity' => $item->getQuantity(), - 'amount' => $item->getAmount(), - ]; - } - - return (string)json_encode($data); - } } diff --git a/src/Service/Refund/RefundService.php b/src/Service/Refund/RefundService.php index 8deb04cd0..c13f9f4ce 100644 --- a/src/Service/Refund/RefundService.php +++ b/src/Service/Refund/RefundService.php @@ -21,6 +21,8 @@ use Mollie\Api\Resources\Refund; use Shopware\Core\Checkout\Order\OrderEntity; use Shopware\Core\Framework\Context; +use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; +use Shopware\Core\Framework\Uuid\Uuid; use Shopware\Core\System\Currency\CurrencyEntity; class RefundService implements RefundServiceInterface @@ -45,6 +47,11 @@ class RefundService implements RefundServiceInterface */ private $gwMollie; + /** + * @var CompositionMigrationServiceInterface + */ + private $compositionRepairService; + /** * @param Order $mollie @@ -52,12 +59,13 @@ class RefundService implements RefundServiceInterface * @param RefundHydrator $refundHydrator * @param MollieGatewayInterface $gwMollie */ - public function __construct(Order $mollie, OrderService $orders, RefundHydrator $refundHydrator, MollieGatewayInterface $gwMollie) + public function __construct(Order $mollie, OrderService $orders, RefundHydrator $refundHydrator, MollieGatewayInterface $gwMollie, CompositionMigrationServiceInterface $compositionRepairService) { $this->mollie = $mollie; $this->orders = $orders; $this->refundHydrator = $refundHydrator; $this->gwMollie = $gwMollie; + $this->compositionRepairService = $compositionRepairService; } @@ -76,11 +84,8 @@ public function refundFull(OrderEntity $order, string $description, string $inte $mollieOrder = $this->mollie->getMollieOrder($mollieOrderId, $order->getSalesChannelId()); - $metadata = new RefundMetadata(RefundItemType::FULL, $refundItems); - $params = [ 'description' => $description, - 'metadata' => $metadata->toString(), ]; @@ -125,8 +130,6 @@ public function refundFull(OrderEntity $order, string $description, string $inte */ public function refundPartial(OrderEntity $order, string $description, string $internalDescription, float $amount, array $lineItems, Context $context): Refund { - $metadata = new RefundMetadata(RefundItemType::PARTIAL, $lineItems); - $payment = $this->getPayment($order); $refund = $payment->refund([ @@ -134,8 +137,7 @@ public function refundPartial(OrderEntity $order, string $description, string $i 'value' => number_format($amount, 2, '.', ''), 'currency' => ($order->getCurrency() instanceof CurrencyEntity) ? $order->getCurrency()->getIsoCode() : '', ], - 'description' => $description, - 'metadata' => $metadata->toString(), + 'description' => $description ]); if (!$refund instanceof Refund) { @@ -192,7 +194,7 @@ public function cancel(OrderEntity $order, string $refundId): bool * @throws CouldNotExtractMollieOrderIdException * @return array */ - public function getRefunds(OrderEntity $order): array + public function getRefunds(OrderEntity $order, Context $context): array { $orderAttributes = new OrderAttributes($order); @@ -210,6 +212,14 @@ public function getRefunds(OrderEntity $order): array if ($refund->status === 'canceled') { continue; } + if (property_exists($refund, 'metadata')) { + /** @var \stdClass|string $metadata */ + $metadata = $refund->metadata; + if (is_string($metadata)) { + $order = $this->compositionRepairService->updateRefundItems($refund, $order, $context); + } + } + $refundsArray[] = $this->refundHydrator->hydrate($refund, $order); } diff --git a/src/Service/Refund/RefundServiceInterface.php b/src/Service/Refund/RefundServiceInterface.php index c028001f8..b107f7d95 100644 --- a/src/Service/Refund/RefundServiceInterface.php +++ b/src/Service/Refund/RefundServiceInterface.php @@ -43,7 +43,7 @@ public function cancel(OrderEntity $order, string $refundId): bool; * @param OrderEntity $order * @return Refund[] */ - public function getRefunds(OrderEntity $order): array; + public function getRefunds(OrderEntity $order, Context $context): array; /** * @param OrderEntity $order diff --git a/tests/PHPUnit/Fakes/FakeRefundService.php b/tests/PHPUnit/Fakes/FakeRefundService.php index db6bd886e..fce503478 100644 --- a/tests/PHPUnit/Fakes/FakeRefundService.php +++ b/tests/PHPUnit/Fakes/FakeRefundService.php @@ -108,7 +108,7 @@ public function cancel(OrderEntity $order, string $refundId): bool * @param OrderEntity $order * @return array */ - public function getRefunds(OrderEntity $order): array + public function getRefunds(OrderEntity $order, Context $context): array { // TODO: Implement getRefunds() method. } diff --git a/tests/PHPUnit/Hydrator/RefundHydratorTest.php b/tests/PHPUnit/Hydrator/RefundHydratorTest.php index 6588d1f4e..a9ab8e6ce 100644 --- a/tests/PHPUnit/Hydrator/RefundHydratorTest.php +++ b/tests/PHPUnit/Hydrator/RefundHydratorTest.php @@ -116,7 +116,7 @@ private function getExpectedData(?float $amount, ?float $settlementAmount, strin 'isProcessing' => $status == RefundStatus::STATUS_PROCESSING, 'isQueued' => $status == RefundStatus::STATUS_QUEUED, 'isTransferred' => $status == RefundStatus::STATUS_REFUNDED, - 'metadata' => null, + 'metadata' => new \stdClass(), ]; } diff --git a/tests/PHPUnit/Service/Refund/Item/RefundItemTest.php b/tests/PHPUnit/Service/Refund/Item/RefundItemTest.php index 602fe7f66..f133adc43 100644 --- a/tests/PHPUnit/Service/Refund/Item/RefundItemTest.php +++ b/tests/PHPUnit/Service/Refund/Item/RefundItemTest.php @@ -19,11 +19,12 @@ class RefundItemTest extends TestCase public function testAmountRounded() { $item = new RefundItem( - '', '', '', 1, 14.9899999, + '', + '' ); $this->assertEquals(14.99, $item->getAmount()); diff --git a/tests/PHPUnit/Service/Refund/Mollie/DataCompressorTest.php b/tests/PHPUnit/Service/Refund/Mollie/DataCompressorTest.php deleted file mode 100644 index 1f4e41506..000000000 --- a/tests/PHPUnit/Service/Refund/Mollie/DataCompressorTest.php +++ /dev/null @@ -1,53 +0,0 @@ -comporessor = new DataCompressor(); - } - - /** - * This test verifies that a valid ID with length 32 is - * correctly compressed and returned. - * - * @return void - */ - public function testCompressID() - { - $value = $this->comporessor->compress('2a88d9b59d474c7e869d8071649be43c'); - - $this->assertEquals(8, strlen($value)); - $this->assertEquals('2a88e43c', $value); - } - - - /** - * This test verifies that invalid IDs with length < 32 are - * not compressed at all. - * - * @return void - */ - public function testInvalidIDsAreNotCompressed() - { - # string with length 31 - $value = $this->comporessor->compress('2a88d9b59d474c7e869d8071649be43'); - - $this->assertEquals(31, strlen($value)); - $this->assertEquals('2a88d9b59d474c7e869d8071649be43', $value); - } -} diff --git a/tests/PHPUnit/Service/Refund/Mollie/RefundMetadataTest.php b/tests/PHPUnit/Service/Refund/Mollie/RefundMetadataTest.php index d2604d612..79abe7183 100644 --- a/tests/PHPUnit/Service/Refund/Mollie/RefundMetadataTest.php +++ b/tests/PHPUnit/Service/Refund/Mollie/RefundMetadataTest.php @@ -44,65 +44,14 @@ public function testType() public function testCompositionItems() { $items = []; - $items[] = new RefundItem('sw1', 'mol1', 'art-123', 2, 9.99); - $items[] = new RefundItem('sw1', 'mol1', 'art-123', 2, 9.99); + $items[] = new RefundItem( 'mol1', 'art-123', 2, 9.99,'sw1','swVersion1'); + $items[] = new RefundItem('mol1', 'art-123', 2, 9.99,'sw1','swVersion1'); $metadata = new RefundMetadata('abc', $items); $this->assertCount(2, $metadata->getComposition()); } - /** - * This test verifies that its possible to assign composition items - * and that they are stored. - * - * @return void - */ - public function testToString() - { - $items = []; - $items[] = new RefundItem('sw1', 'mol1', 'art-123', 2, 9.99); - - $metadata = new RefundMetadata('FULL', $items); - - $expected = [ - 'type' => 'FULL', - 'composition' => [ - [ - 'swLineId' => 'sw1', - 'mollieLineId' => 'mol1', - 'swReference' => 'art-123', - 'quantity' => 2, - 'amount' => 9.99, - ] - ] - ]; - - $expected = json_encode($expected); - - $this->assertEquals($expected, $metadata->toString()); - } - - - /** - * This test verifies that our long IDs are correctly compressed - * and returned in our JSON output instead of the long IDs. - * - * @return void - */ - public function testCompression() - { - $items = []; - $items[] = new RefundItem('2a88d9b59d474c7e869d8071649be43c', 'mol1', 'c7bca22753c84d08b6178a50052b4146', 2, 9.99); - $metadata = new RefundMetadata('FULL', $items); - $outputJson = json_decode($metadata->toString(), true); - - $lineId = $outputJson['composition'][0]['swLineId']; - $swReference = $outputJson['composition'][0]['swReference']; - - $this->assertEquals(8, strlen($lineId)); - $this->assertEquals('2a88e43c', $lineId); - } }