diff --git a/composer.lock b/composer.lock index 40343ca..1e88740 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1f1e6e29b31f6171b5cbf35bd44b668f", + "content-hash": "87704edab92c52e0357537f2ba85ebc5", "packages": [ { "name": "composer/ca-bundle", - "version": "1.2.4", + "version": "1.2.6", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "10bb96592168a0f8e8f6dcde3532d9fa50b0b527" + "reference": "47fe531de31fca4a1b997f87308e7d7804348f7e" }, "dist": { "type": "zip", - "url": "https://github.com/gitapi/repos/composer/ca-bundle/zipball/10bb96592168a0f8e8f6dcde3532d9fa50b0b527", - "reference": "10bb96592168a0f8e8f6dcde3532d9fa50b0b527", + "url": "https://github.com/gitapi/repos/composer/ca-bundle/zipball/47fe531de31fca4a1b997f87308e7d7804348f7e", + "reference": "47fe531de31fca4a1b997f87308e7d7804348f7e", "shasum": "" }, "require": { @@ -28,7 +28,7 @@ "require-dev": { "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8", "psr/log": "^1.0", - "symfony/process": "^2.5 || ^3.0 || ^4.0" + "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0" }, "type": "library", "extra": { @@ -60,20 +60,20 @@ "ssl", "tls" ], - "time": "2019-08-30T08:44:50+00:00" + "time": "2020-01-13T10:02:55+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "6.4.1", + "version": "6.5.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "0895c932405407fd3a7368b6910c09a24d26db11" + "reference": "43ece0e75098b7ecd8d13918293029e555a50f82" }, "dist": { "type": "zip", - "url": "https://github.com/gitapi/repos/guzzle/guzzle/zipball/0895c932405407fd3a7368b6910c09a24d26db11", - "reference": "0895c932405407fd3a7368b6910c09a24d26db11", + "url": "https://github.com/gitapi/repos/guzzle/guzzle/zipball/43ece0e75098b7ecd8d13918293029e555a50f82", + "reference": "43ece0e75098b7ecd8d13918293029e555a50f82", "shasum": "" }, "require": { @@ -88,12 +88,13 @@ "psr/log": "^1.1" }, "suggest": { + "ext-intl": "Required for Internationalized Domain Name (IDN) support", "psr/log": "Required for using the Log middleware" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.3-dev" + "dev-master": "6.5-dev" } }, "autoload": { @@ -126,7 +127,7 @@ "rest", "web service" ], - "time": "2019-10-23T15:58:00+00:00" + "time": "2019-12-23T11:57:10+00:00" }, { "name": "guzzlehttp/promises", @@ -252,16 +253,16 @@ }, { "name": "mollie/mollie-api-php", - "version": "v2.12.0", + "version": "v2.17.0", "source": { "type": "git", "url": "https://github.com/mollie/mollie-api-php.git", - "reference": "a8540896e069fca409cf18351b33ec10f58622c6" + "reference": "ee22d0301aee55a41ef2e7d201ef29f86550d1f7" }, "dist": { "type": "zip", - "url": "https://github.com/gitapi/repos/mollie/mollie-api-php/zipball/a8540896e069fca409cf18351b33ec10f58622c6", - "reference": "a8540896e069fca409cf18351b33ec10f58622c6", + "url": "https://github.com/gitapi/repos/mollie/mollie-api-php/zipball/ee22d0301aee55a41ef2e7d201ef29f86550d1f7", + "reference": "ee22d0301aee55a41ef2e7d201ef29f86550d1f7", "shasum": "" }, "require": { @@ -334,7 +335,7 @@ "sofortbanking", "subscriptions" ], - "time": "2019-09-26T12:36:04+00:00" + "time": "2020-02-25T12:19:37+00:00" }, { "name": "psr/http-message", @@ -429,17 +430,6 @@ { "name": "roave/security-advisories", "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "f8c8349a4b12a26edfa8b21d07d3dbeb6dcedcfa" - }, - "dist": { - "type": "zip", - "url": "https://github.com/gitapi/repos/Roave/SecurityAdvisories/zipball/f8c8349a4b12a26edfa8b21d07d3dbeb6dcedcfa", - "reference": "f8c8349a4b12a26edfa8b21d07d3dbeb6dcedcfa", - "shasum": "" - }, "conflict": { "3f/pygmentize": "<1.2", "adodb/adodb-php": "<5.20.12", @@ -449,16 +439,21 @@ "api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6", "asymmetricrypt/asymmetricrypt": ">=0,<9.9.99", "aws/aws-sdk-php": ">=3,<3.2.1", + "bagisto/bagisto": "<0.1.5", + "bolt/bolt": "<3.6.10", "brightlocal/phpwhois": "<=4.2.5", + "buddypress/buddypress": "<5.1.2", "bugsnag/bugsnag-laravel": ">=2,<2.0.2", "cakephp/cakephp": ">=1.3,<1.3.18|>=2,<2.4.99|>=2.5,<2.5.99|>=2.6,<2.6.12|>=2.7,<2.7.6|>=3,<3.5.18|>=3.6,<3.6.15|>=3.7,<3.7.7", "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", "cartalyst/sentry": "<=2.1.6", + "centreon/centreon": "<18.10.8|>=19,<19.4.5", + "cesnet/simplesamlphp-module-proxystatistics": "<3.1", "codeigniter/framework": "<=3.0.6", "composer/composer": "<=1-alpha.11", "contao-components/mediaelement": ">=2.14.2,<2.21.1", "contao/core": ">=2,<3.5.39", - "contao/core-bundle": ">=4,<4.4.39|>=4.5,<4.7.5", + "contao/core-bundle": ">=4,<4.4.46|>=4.5,<4.8.6", "contao/listing-bundle": ">=4,<4.4.8", "datadog/dd-trace": ">=0.30,<0.30.2", "david-garcia/phpwhois": "<=4.3.1", @@ -471,13 +466,20 @@ "doctrine/mongodb-odm": ">=1,<1.0.2", "doctrine/mongodb-odm-bundle": ">=2,<3.0.1", "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1", + "dolibarr/dolibarr": "<=10.0.6", "dompdf/dompdf": ">=0.6,<0.6.2", - "drupal/core": ">=7,<7.67|>=8,<8.6.16|>=8.7,<8.7.1|>8.7.3,<8.7.5", - "drupal/drupal": ">=7,<7.67|>=8,<8.6.16|>=8.7,<8.7.1|>8.7.3,<8.7.5", + "drupal/core": ">=7,<7.69|>=8,<8.7.11|>=8.8,<8.8.1", + "drupal/drupal": ">=7,<7.69|>=8,<8.7.11|>=8.8,<8.8.1", + "endroid/qr-code-bundle": "<3.4.2", + "enshrined/svg-sanitize": "<0.13.1", "erusev/parsedown": "<1.7.2", - "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.4", - "ezsystems/ezpublish-kernel": ">=5.3,<5.3.12.1|>=5.4,<5.4.13.1|>=6,<6.7.9.1|>=6.8,<6.13.5.1|>=7,<7.2.4.1|>=7.3,<7.3.2.1", - "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.6|>=5.4,<5.4.12.3|>=2011,<2017.12.4.3|>=2018.6,<2018.6.1.4|>=2018.9,<2018.9.1.3", + "ezsystems/ezfind-ls": ">=5.3,<5.3.6.1|>=5.4,<5.4.11.1|>=2017.12,<2017.12.0.1", + "ezsystems/ezplatform": ">=1.7,<1.7.9.1|>=1.13,<1.13.5.1|>=2.5,<2.5.4", + "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6", + "ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2", + "ezsystems/ezplatform-user": ">=1,<1.0.1", + "ezsystems/ezpublish-kernel": ">=5.3,<5.3.12.1|>=5.4,<5.4.14.1|>=6,<6.7.9.1|>=6.8,<6.13.6.2|>=7,<7.2.4.1|>=7.3,<7.3.2.1|>=7.5,<7.5.6.2", + "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.6|>=5.4,<5.4.14.1|>=2011,<2017.12.7.2|>=2018.6,<2018.6.1.4|>=2018.9,<2018.9.1.3|>=2019.3,<2019.3.4.2", "ezsystems/repository-forms": ">=2.3,<2.3.2.1", "ezyang/htmlpurifier": "<4.1.1", "firebase/php-jwt": "<2", @@ -486,6 +488,7 @@ "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2", "friendsofsymfony/user-bundle": ">=1.2,<1.3.5", "fuel/core": "<1.8.1", + "getgrav/grav": "<1.7-beta.8", "gree/jose": "<=2.2", "gregwar/rst": "<1.0.3", "guzzlehttp/guzzle": ">=4-rc.2,<4.2.4|>=5,<5.3.1|>=6,<6.2.1", @@ -503,12 +506,15 @@ "laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30", "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", "league/commonmark": "<0.18.3", + "librenms/librenms": "<1.53", + "magento/community-edition": ">=2,<2.2.10|>=2.3,<2.3.3", "magento/magento1ce": "<1.9.4.3", "magento/magento1ee": ">=1,<1.14.4.3", - "magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.3", + "magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.2-p.2", "monolog/monolog": ">=1.8,<1.12", "namshi/jose": "<2.2", "onelogin/php-saml": "<2.10.4", + "oneup/uploader-bundle": "<1.9.3|>=2,<2.1.5", "openid/php-openid": "<2.3", "oro/crm": ">=1.7,<1.7.4", "oro/platform": ">=1.7,<1.7.4", @@ -517,50 +523,68 @@ "paragonie/random_compat": "<2", "paypal/merchant-sdk-php": "<3.12", "pear/archive_tar": "<1.4.4", + "phpfastcache/phpfastcache": ">=5,<5.0.13", "phpmailer/phpmailer": ">=5,<5.2.27|>=6,<6.0.6", - "phpoffice/phpexcel": "<=1.8.1", - "phpoffice/phpspreadsheet": "<=1.5", + "phpmyadmin/phpmyadmin": "<4.9.2", + "phpoffice/phpexcel": "<1.8.2", + "phpoffice/phpspreadsheet": "<1.8", "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3", "phpwhois/phpwhois": "<=4.2.5", "phpxmlrpc/extras": "<0.6.1", + "pimcore/pimcore": "<6.3", + "prestashop/autoupgrade": ">=4,<4.10.1", + "prestashop/gamification": "<2.3.2", + "prestashop/ps_facetedsearch": "<3.4.1", + "privatebin/privatebin": "<1.2.2|>=1.3,<1.3.2", "propel/propel": ">=2-alpha.1,<=2-alpha.7", "propel/propel1": ">=1,<=1.7.1", "pusher/pusher-php-server": "<2.2.1", - "robrichards/xmlseclibs": ">=1,<3.0.2", + "robrichards/xmlseclibs": "<3.0.4", "sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9", + "scheb/two-factor-bundle": ">=0,<3.26|>=4,<4.11", "sensiolabs/connect": "<4.2.3", "serluck/phpwhois": "<=4.2.6", "shopware/shopware": "<5.3.7", - "silverstripe/cms": ">=3,<=3.0.11|>=3.1,<3.1.11", + "silverstripe/admin": ">=1.0.3,<1.0.4|>=1.1,<1.1.1", + "silverstripe/assets": ">=1,<1.3.5|>=1.4,<1.4.4", + "silverstripe/cms": "<4.3.6|>=4.4,<4.4.4", + "silverstripe/comments": ">=1.3,<1.9.99|>=2,<2.9.99|>=3,<3.1.1", "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3", - "silverstripe/framework": ">=3,<3.6.7|>=3.7,<3.7.3|>=4,<4.4", + "silverstripe/framework": "<4.4.5|>=4.5,<4.5.2", "silverstripe/graphql": ">=2,<2.0.5|>=3,<3.1.2", "silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1", "silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4", + "silverstripe/subsites": ">=2,<2.1.1", + "silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1", "silverstripe/userforms": "<3", "simple-updates/phpwhois": "<=1", "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4", - "simplesamlphp/simplesamlphp": "<1.17.3", + "simplesamlphp/simplesamlphp": "<1.18.4", "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", + "simplito/elliptic-php": "<1.0.6", "slim/slim": "<2.6", "smarty/smarty": "<3.1.33", "socalnick/scn-social-auth": "<1.15.2", "spoonity/tcpdf": "<6.2.22", "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1", "stormpath/sdk": ">=0,<9.9.99", - "studio-42/elfinder": "<2.1.48", + "studio-42/elfinder": "<2.1.49", "swiftmailer/swiftmailer": ">=4,<5.4.5", "sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2", "sylius/grid": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1", "sylius/grid-bundle": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1", - "sylius/sylius": ">=1,<1.1.18|>=1.2,<1.2.17|>=1.3,<1.3.12|>=1.4,<1.4.4", - "symfony/cache": ">=3.1,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", + "sylius/resource-bundle": "<1.3.13|>=1.4,<1.4.6|>=1.5,<1.5.1|>=1.6,<1.6.3", + "sylius/sylius": "<1.3.16|>=1.4,<1.4.12|>=1.5,<1.5.9|>=1.6,<1.6.5", + "symbiote/silverstripe-multivaluefield": ">=3,<3.0.99", + "symbiote/silverstripe-versionedfiles": "<=2.0.3", + "symfony/cache": ">=3.1,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8", "symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", - "symfony/http-foundation": ">=2,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", - "symfony/http-kernel": ">=2,<2.3.29|>=2.4,<2.5.12|>=2.6,<2.6.8", + "symfony/http-foundation": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8", + "symfony/http-kernel": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8", "symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/mime": ">=4.3,<4.3.8", "symfony/phpunit-bridge": ">=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", "symfony/polyfill": ">=1,<1.10", "symfony/polyfill-php55": ">=1,<1.10", @@ -571,11 +595,12 @@ "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<2.8.37|>=3,<3.3.17|>=3.4,<3.4.7|>=4,<4.0.7", "symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", "symfony/security-guard": ">=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", - "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", + "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8", "symfony/serializer": ">=2,<2.0.11", - "symfony/symfony": ">=2,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", + "symfony/symfony": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8", "symfony/translation": ">=2,<2.0.17", "symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3", + "symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8", "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7", "tecnickcom/tcpdf": "<6.2.22", @@ -585,14 +610,17 @@ "titon/framework": ">=0,<9.9.99", "truckersmp/phpwhois": "<=4.3.1", "twig/twig": "<1.38|>=2,<2.7", - "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.32|>=8,<8.7.27|>=9,<9.5.8", - "typo3/cms-core": ">=8,<8.7.27|>=9,<9.5.8", + "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.32|>=8,<8.7.30|>=9,<9.5.12|>=10,<10.2.1", + "typo3/cms-core": ">=8,<8.7.30|>=9,<9.5.12|>=10,<10.2.1", "typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.10|>=3.1,<3.1.7|>=3.2,<3.2.7|>=3.3,<3.3.5", "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4", "typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1", "ua-parser/uap-php": "<3.8", + "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2", + "verot/class.upload.php": "<=1.0.3|>=2,<=2.0.4", "wallabag/tcpdf": "<6.2.22", "willdurand/js-translation-bundle": "<2.1.1", + "yii2mod/yii2-cms": "<1.9.2", "yiisoft/yii": ">=1.1.14,<1.1.15", "yiisoft/yii2": "<2.0.15", "yiisoft/yii2-bootstrap": "<2.0.4", @@ -601,6 +629,7 @@ "yiisoft/yii2-gii": "<2.0.4", "yiisoft/yii2-jui": "<2.0.4", "yiisoft/yii2-redis": "<2.0.8", + "yourls/yourls": "<1.7.4", "zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3", "zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2", "zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2", @@ -637,10 +666,15 @@ "name": "Marco Pivetta", "email": "ocramius@gmail.com", "role": "maintainer" + }, + { + "name": "Ilya Tribusean", + "email": "slash3b@gmail.com", + "role": "maintainer" } ], "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", - "time": "2019-10-29T22:11:03+00:00" + "time": "2020-03-03T17:52:54+00:00" } ], "packages-dev": [], diff --git a/info.xml b/info.xml index 046f379..6ba23dc 100644 --- a/info.xml +++ b/info.xml @@ -29,6 +29,10 @@ 2019-12-18 + + 107.sql + 2020-03-02 + 131_globalinclude.php 144_notify.php @@ -90,6 +94,15 @@ + + Artikel mit rationalen Stückzahlen + Artikel mit rationalen Stückzahlen werden dann unterstützt, jedoch als ein Artikel behandelt. KEIN Teilversand hierfür möglich! + supportQ + + + + + TransaktionsID des Zahlungseingangs: Welche ID soll an die WAWI übetragen werden? @@ -113,6 +126,7 @@ + error_canceled @@ -120,9 +134,8 @@ - + + error_expired @@ -130,16 +143,16 @@ + error_open - + + error_failed @@ -147,39 +160,43 @@ - + + lbl_cardHolder + lbl_cardNumber + lbl_expiryDate + lbl_varificationCode - - + + + cvchint_1 + cvchint_2 @@ -187,9 +204,8 @@ - + + @@ -226,6 +242,7 @@ 0 JTLMollieCreditCard.php JTLMollieCreditCard + tpl/mollieComponents.tpl tpl/bestellabschluss.tpl Kreditkarte @@ -553,6 +570,46 @@ Bezahlen Sie bequem mit Klarna Slice It. + + mollie Przelewy24 + + 17 + 0 + mollie.com + OTHER + 1 + 0 + 1 + 0 + JTLMolliePrzelewy24.php + JTLMolliePrzelewy24 + tpl/bestellabschluss.tpl + + Przelewy24 + mollie + Bezahlen Sie bequem mit Przelewy24. + + + + mollie MyBank + + 17 + 0 + mollie.com + OTHER + 1 + 0 + 1 + 0 + JTLMollieMyBank.php + JTLMollieMyBank + tpl/bestellabschluss.tpl + + MyBank + mollie + Bezahlen Sie bequem mit MyBank. + + \ No newline at end of file diff --git a/version/106/adminmenu/orders.php b/version/106/adminmenu/orders.php index 96a1207..e34ac14 100644 --- a/version/106/adminmenu/orders.php +++ b/version/106/adminmenu/orders.php @@ -117,7 +117,7 @@ } } - $logs = Shop::DB()->executeQueryPrepared("SELECT * FROM tzahlungslog WHERE cLogData LIKE :kBestellung OR cLogData LIKE :cBestellNr OR cLogData LIKE :MollieID ORDER BY dDatum DESC, cLog DESC", [ + $logs = Shop::DB()->executeQueryPrepared("SELECT * FROM tzahlungslog WHERE cLogData LIKE :kBestellung OR cLogData LIKE :cBestellNr OR cLogData LIKE :MollieID ORDER BY dDatum DESC", [ ':kBestellung' => '%#' . ($payment->kBestellung ?: '##') . '%', ':cBestellNr' => '%§' . ($payment->cOrderNumber ?: '§§') . '%', ':MollieID' => '%$' . ($payment->kID ?: '$$') . '%', diff --git a/version/106/frontend/131_globalinclude.php b/version/106/frontend/131_globalinclude.php index ce69519..514cbea 100644 --- a/version/106/frontend/131_globalinclude.php +++ b/version/106/frontend/131_globalinclude.php @@ -24,48 +24,20 @@ $logData = '$' . $oZahlungSession->cNotifyID; if (!(int)$oZahlungSession->kBestellung && $oZahlungSession->cNotifyID) { - Mollie::JTLMollie()->doLog("Hook 131: Bestellung noch nicht finalisiert ({$oZahlungSession->cNotifyID})", $logData, LOGLEVEL_DEBUG); // Bestellung noch nicht finalisiert $mOrder = JTLMollie::API()->orders->get($oZahlungSession->cNotifyID, ['embed' => 'payments']); if ($mOrder && $mOrder->id === $oZahlungSession->cNotifyID) { - $lock = new \ws_mollie\ExclusiveLock('mollie_' . $mOrder->id, PFAD_ROOT . PFAD_COMPILEDIR); - $logged = false; - $maxWait = 300; - while (!$lock->lock() && $maxWait > 0) { - if (!$logged) { - Mollie::JTLMollie()->doLog("Hook 131: Order currently locked ({$oZahlungSession->cNotifyID})", $logData, LOGLEVEL_DEBUG); - $logged = microtime(true); - } - usleep(100000); - $maxWait--; - } - - if ($logged) { - Mollie::JTLMollie()->doLog("Hook 131: Order unlocked (after " . round(microtime(true) - $logged, 2) . "s - maxWait left: {$maxWait})", $logData, LOGLEVEL_DEBUG); - } else { - Mollie::JTLMollie()->doLog("Hook 131: Order locked - maxWait left: {$maxWait})", $logData, LOGLEVEL_DEBUG); - } - - $oZahlungSession = JTLMollie::getZahlungSession($_REQUEST['mollie']); - if ((int)$oZahlungSession->kBestellung) { - Mollie::JTLMollie()->doLog("Hook 131: Order finalized already ({$oZahlungSession->kBestellung}) => redirect", $logData, LOGLEVEL_DEBUG); - return Mollie::getOrderCompletedRedirect($oZahlungSession->kBestellung, true); - } - - Mollie::JTLMollie()->doLog("Hook 131: Order {$mOrder->id} - {$mOrder->status}
" . print_r($mOrder, 1) . "
", $logData, LOGLEVEL_DEBUG); if (!in_array($mOrder->status, [OrderStatus::STATUS_EXPIRED, OrderStatus::STATUS_CANCELED])) { $payment = Mollie::getLastPayment($mOrder); if (in_array($payment->status, [PaymentStatus::STATUS_AUTHORIZED, PaymentStatus::STATUS_PAID, PaymentStatus::STATUS_PENDING])) { if (session_id() !== $oZahlungSession->cSID) { - Mollie::JTLMollie()->doLog("Hook 131: Switch to PaymentSession
" . print_r([session_id(), $oZahlungSession], 1) . "
", $logData, LOGLEVEL_DEBUG); session_destroy(); session_id($oZahlungSession->cSID); $session = Session::getInstance(true, true); } else { - Mollie::JTLMollie()->doLog("Hook 131: Already in PaymentSession
" . print_r([session_id(), $oZahlungSession], 1) . "
", $logData, LOGLEVEL_DEBUG); $session = Session::getInstance(false, false); } @@ -75,11 +47,8 @@ $order = fakeBestellung(); $order = finalisiereBestellung(); $session->cleanUp(); - $logData .= '#' . $order->kBestellung . '§' . $order->cBestellNr; - Mollie::JTLMollie()->doLog("Hook 131: Bestellung finalisiert
" . print_r([$order->kBestellung, $order->cBestellNr], 1) . "
", $logData, LOGLEVEL_DEBUG); if ($order->kBestellung > 0) { - Mollie::JTLMollie()->doLog("Hook 131: Finalisierung erfolgreich, kBestellung: {$order->kBestellung} / {$order->cBestellNr}", $logData, LOGLEVEL_DEBUG); $oZahlungSession->nBezahlt = 1; $oZahlungSession->dZeitBezahlt = 'now()'; $oZahlungSession->kBestellung = (int)$order->kBestellung; @@ -87,8 +56,6 @@ Shop::DB()->update('tzahlungsession', 'cZahlungsID', $oZahlungSession->cZahlungsID, $oZahlungSession); Mollie::handleOrder($mOrder, $order->kBestellung); return Mollie::getOrderCompletedRedirect($order->kBestellung, true); - } else { - Mollie::JTLMollie()->doLog("Hook 131: Fionalisierung fehlgeschlagen
" . print_r($order, 1) . "
", $logData, LOGLEVEL_ERROR); } } else { Mollie::JTLMollie()->doLog("Hook 131: Invalid PaymentStatus: {$payment->status} for {$payment->id} ", $logData, LOGLEVEL_ERROR); @@ -106,8 +73,6 @@ header('Location: ' . Shop::getURL() . '/bestellvorgang.php?editZahlungsart=1'); exit(); } - } else { - Mollie::JTLMollie()->doLog("Hook 131: already finalized => redirect / kBestellung:{$oZahlungSession->kBestellung} && cNotifyID:{$oZahlungSession->cNotifyID}", $logData, LOGLEVEL_NOTICE); } return Mollie::getOrderCompletedRedirect((int)$oZahlungSession->kBestellung, true); } diff --git a/version/106/paymentmethod/JTLMollie.php b/version/106/paymentmethod/JTLMollie.php index 6d69cdc..ec80516 100644 --- a/version/106/paymentmethod/JTLMollie.php +++ b/version/106/paymentmethod/JTLMollie.php @@ -106,7 +106,7 @@ public function addIncomingPayment($order, $payment) public function doLog($msg, $data = null, $level = LOGLEVEL_NOTICE) { //ZahlungsLog::add($this->moduleID, $msg, $data, $level); - ZahlungsLog::add($this->moduleID, "[" . microtime(true) . " - " . $_SERVER['PHP_SELF'] . "] " . $msg, $data, $level); + ZahlungsLog::add($this->moduleID, "[" . $_SERVER['PHP_SELF'] . "] " . $msg, $data, $level); return $this; } @@ -505,22 +505,12 @@ public function handleNotification($order, $hash, $args) */ public function finalizeOrder($order, $hash, $args) { - $result = false; try { if ($oZahlungSession = self::getZahlungSession(md5($hash))) { if ((int)$oZahlungSession->kBestellung <= 0) { - - $logData = '$' . $args['id']; - $GLOBALS['mollie_notify_lock'] = new \ws_mollie\ExclusiveLock('mollie_' . $args['id'], PFAD_ROOT . PFAD_COMPILEDIR); - if ($GLOBALS['mollie_notify_lock']->lock()) { - $this->doLog("JTLMollie::finalizeOrder::locked ({$args['id']})", $logData, LOGLEVEL_DEBUG); - } else { - $this->doLog("JTLMollie::finalizeOrder::locked failed ({$args['id']})", $logData, LOGLEVEL_ERROR); - } - $oOrder = self::API()->orders->get($args['id'], ['embed' => 'payments']); - + $logData = '$' . $oOrder->id; $result = in_array($oOrder->status, [OrderStatus::STATUS_PAID, OrderStatus::STATUS_AUTHORIZED, OrderStatus::STATUS_PENDING, OrderStatus::STATUS_COMPLETED]); $this->doLog('JTLMollie::finalizeOrder (' . ($result ? 'true' : 'false') . ')
' . print_r([$hash, $args, $oOrder], 1) . '
', $logData, LOGLEVEL_DEBUG); //Payment::updateFromPayment($oMolliePayment, $order->kBestellung); diff --git a/version/107/adminmenu/info.php b/version/107/adminmenu/info.php new file mode 100644 index 0000000..292064e --- /dev/null +++ b/version/107/adminmenu/info.php @@ -0,0 +1,64 @@ +assign('defaultTabbertab', Helper::getAdminmenu('Info')); + Helper::selfupdate(); + } + + $svgQuery = http_build_query([ + 'p' => Helper::oPlugin()->cPluginID, + 'v' => Helper::oPlugin()->nVersion, + 's' => defined('APPLICATION_VERSION') ? APPLICATION_VERSION : JTL_VERSION, + 'b' => defined('JTL_MINOR_VERSION') ? JTL_MINOR_VERSION : '0', + 'd' => Helper::getDomain(), + 'm' => base64_encode(Helper::getMasterMail(true)), + 'php' => PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION . PHP_EXTRA_VERSION, + ]); + + echo ""; + echo "
" . + "
" . + " " . + " Lizenz Informationen" . + ' ' . + '
' . + "
" . + " " . + " Update Informationen" . + ' ' . + '
' . + "
" . + " " . + " Plugin informationen" . + ' ' . + '
' . + '
'; + + try { + $latestRelease = Helper::getLatestRelease(array_key_exists('update', $_REQUEST)); + if ((int)Helper::oPlugin()->nVersion < (int)$latestRelease->version) { + Shop::Smarty()->assign('update', $latestRelease); + } + + } catch (\Exception $e) { + } + + Shop::Smarty()->display(Helper::oPlugin()->cAdminmenuPfad . '/tpl/info.tpl'); + + if (file_exists(__DIR__ . '/_addon.php')) { + try { + include __DIR__ . '/_addon.php'; + } catch (Exception $e) { + } + } + +} catch (Exception $e) { + echo "
Fehler: {$e->getMessage()}
"; + Helper::logExc($e); +} \ No newline at end of file diff --git a/version/107/adminmenu/orders.php b/version/107/adminmenu/orders.php new file mode 100644 index 0000000..9a584d7 --- /dev/null +++ b/version/107/adminmenu/orders.php @@ -0,0 +1,240 @@ +executeQueryPrepared('SELECT * FROM xplugin_ws_mollie_payments WHERE kBestellung > 0 AND dCreatedAt >= :From AND dCreatedAt <= :To ORDER BY dCreatedAt', [ + ':From' => $from->format('Y-m-d'), + ':To' => $to->format('Y-m-d'), + ], 2); + + + $api = JTLMollie::API(); + + header('Content-Type: application/csv'); + header('Content-Disposition: attachment; filename=mollie-' . $from->format('Ymd') . '-' . $to->format('Ymd') . '.csv'); + header('Pragma: no-cache'); + + $out = fopen('php://output', 'w'); + + + fputcsv($out, [ + 'kBestellung', + 'OrderID', + 'Status (mollie)', + 'BestellNr', + 'Status (JTL)', + 'Mode', + 'OriginalOrderNumber', + 'Currency', + 'Amount', + 'Method', + 'PaymentID', + 'Created' + ]); + + + foreach ($orders as $order) { + $tbestellung = Shop::DB()->executeQueryPrepared('SELECT cBestellNr, cStatus FROM tbestellung WHERE kBestellung = :kBestellung', [':kBestellung' => $order->kBestellung], 1); + + $tmp = [ + 'kBestellung' => $order->kBestellung, + 'cOrderId' => $order->kID, + 'cStatus' => $order->cStatus, + 'cBestellNr' => $tbestellung ? $tbestellung->cBestellNr : $order->cOrderNumber, + 'nStatus' => $tbestellung ? $tbestellung->cStatus : 0, + 'cMode' => $order->cMode, + 'cOriginalOrderNumber' => '', + 'cCurrency' => $order->cCurrency, + 'fAmount' => $order->fAmount, + 'cMethod' => $order->cMethod, + 'cPaymentId' => '', + 'dCreated' => $order->dCreatedAt, + ]; + + try { + $oOrder = $api->orders->get($order->kID, ['embed' => 'payments']); + $tmp['cStatus'] = $oOrder->status; + $tmp['cOriginalOrderNumber'] = isset($oOrder->metadata->originalOrderNumber) ? $oOrder->metadata->originalOrderNumber : ''; + foreach ($oOrder->payments() as $payment) { + if ($payment->status === \Mollie\Api\Types\PaymentStatus::STATUS_PAID) { + $tmp['cPaymentId'] = $payment->id; + } + } + } catch (Exception $e) { + } + fputcsv($out, $tmp); + + $export[] = $tmp; + } + + fclose($out); + exit(); + + } catch (Exception $e) { + $ordersMsgs[] = (object)['type' => 'danger', 'text' => 'Fehler:' . $e->getMessage()]; + } + break; + + case 'refund': + if (!array_key_exists('id', $_REQUEST)) { + $ordersMsgs[] = (object)['type' => 'danger', 'text' => 'Keine ID angeben!']; + break; + } + $payment = Payment::getPaymentMollie($_REQUEST['id']); + if (!$payment) { + $ordersMsgs[] = (object)['type' => 'danger', 'text' => 'Order nicht gefunden!']; + break; + } + + $order = JTLMollie::API()->orders->get($_REQUEST['id']); + if ($order->status == OrderStatus::STATUS_CANCELED) { + $ordersMsgs[] = (object)['type' => 'danger', 'text' => 'Bestellung bereits storniert']; + break; + } + $refund = JTLMollie::API()->orderRefunds->createFor($order, ['lines' => []]); + Mollie::JTLMollie()->doLog("Order refunded:
" . print_r($refund, 1) . "
", '$' . $payment->kID . '#' . $payment->kBestellung . '§' . $payment->cOrderNumber, LOGLEVEL_NOTICE); + + goto order; + break; + + case 'cancel': + if (!array_key_exists('id', $_REQUEST)) { + $ordersMsgs[] = (object)['type' => 'danger', 'text' => 'Keine ID angeben!']; + break; + } + $payment = Payment::getPaymentMollie($_REQUEST['id']); + if (!$payment) { + $ordersMsgs[] = (object)['type' => 'danger', 'text' => 'Order nicht gefunden!']; + break; + } + $order = JTLMollie::API()->orders->get($_REQUEST['id']); + if ($order->status == OrderStatus::STATUS_CANCELED) { + $ordersMsgs[] = (object)['type' => 'danger', 'text' => 'Bestellung bereits storniert']; + break; + } + $cancel = JTLMollie::API()->orders->cancel($order->id); + Mollie::JTLMollie()->doLog("Order canceled:
" . print_r($cancel, 1) . "
", '$' . $payment->kID . '#' . $payment->kBestellung . '§' . $payment->cOrderNumber, LOGLEVEL_NOTICE); + goto order; + break; + + case 'capture': + if (!array_key_exists('id', $_REQUEST)) { + $ordersMsgs[] = (object)['type' => 'danger', 'text' => 'Keine ID angeben!']; + break; + } + $payment = Payment::getPaymentMollie($_REQUEST['id']); + if (!$payment) { + $ordersMsgs[] = (object)['type' => 'danger', 'text' => 'Order nicht gefunden!']; + break; + } + $order = JTLMollie::API()->orders->get($_REQUEST['id']); + if ($order->status !== OrderStatus::STATUS_AUTHORIZED && $order->status !== OrderStatus::STATUS_SHIPPING) { + $ordersMsgs[] = (object)['type' => 'danger', 'text' => 'Nur autorisierte Zahlungen können erfasst werden!']; + break; + } + + $oBestellung = new Bestellung($payment->kBestellung, true); + if (!$oBestellung->kBestellung) { + $ordersMsgs[] = (object)['type' => 'danger', 'text' => 'Bestellung konnte nicht geladen werden!']; + break; + } + + $logData = '#' . $payment->kBestellung . '$' . $payment->kID . "§" . $oBestellung->cBestellNr; + + $options = ['lines' => []]; + if ($oBestellung->cTracking) { + $tracking = new stdClass(); + $tracking->carrier = $oBestellung->cVersandartName; + $tracking->url = $oBestellung->cTrackingURL; + $tracking->code = $oBestellung->cTracking; + $options['tracking'] = $tracking; + } + + // CAPTURE ALL + $shipment = JTLMollie::API()->shipments->createFor($order, $options); + $ordersMsgs[] = (object)['type' => 'success', 'text' => 'Zahlung wurde erfolgreich erfasst!']; + Mollie::JTLMollie()->doLog('Shipment created
' . print_r(['options' => $options, 'shipment' => $shipment], 1) . '
', $logData); + goto order; + + case 'order': + order: + if (!array_key_exists('id', $_REQUEST)) { + $ordersMsgs[] = (object)['type' => 'danger', 'text' => 'Keine ID angeben!']; + break; + } + + $order = JTLMollie::API()->orders->get($_REQUEST['id'], ['embed' => 'payments,refunds']); + $payment = Payment::getPaymentMollie($_REQUEST['id']); + if ($payment) { + $oBestellung = new Bestellung($payment->kBestellung, false); + //\ws_mollie\Model\Payment::updateFromPayment($order, $oBestellung->kBestellung); + if ($oBestellung->kBestellung && $oBestellung->cBestellNr !== $payment->cOrderNumber) { + Shop::DB()->executeQueryPrepared("UPDATE xplugin_ws_mollie_payments SET cOrderNumber = :cBestellNr WHERE kID = :kID", [ + ':cBestellNr' => $oBestellung->cBestellNr, + ':kID' => $payment->kID, + ], 3); + } + } + $logs = Shop::DB()->executeQueryPrepared("SELECT * FROM tzahlungslog WHERE cLogData LIKE :kBestellung OR cLogData LIKE :cBestellNr OR cLogData LIKE :MollieID ORDER BY dDatum DESC, cLog DESC", [ + ':kBestellung' => '%#' . ($payment->kBestellung ?: '##') . '%', + ':cBestellNr' => '%§' . ($payment->cOrderNumber ?: '§§') . '%', + ':MollieID' => '%$' . ($payment->kID ?: '$$') . '%', + ], 2); + + Shop::Smarty()->assign('payment', $payment) + ->assign('oBestellung', $oBestellung) + ->assign('order', $order) + ->assign('logs', $logs) + ->assign('ordersMsgs', $ordersMsgs); + Shop::Smarty()->display($oPlugin->cAdminmenuPfad . '/tpl/order.tpl'); + return; + } + } + + + Mollie::fixZahlungsarten(); + + + $payments = Shop::DB()->executeQueryPrepared("SELECT * FROM xplugin_ws_mollie_payments WHERE kBestellung IS NOT NULL AND cStatus != 'created' ORDER BY dCreatedAt DESC LIMIT 1000;", [], 2); + foreach ($payments as $i => $payment) { + $payments[$i]->oBestellung = new Bestellung($payment->kBestellung, false); + } + + Shop::Smarty()->assign('payments', $payments) + ->assign('ordersMsgs', $ordersMsgs) + ->assign('admRoot', str_replace('http:', '', $oPlugin->cAdminmenuPfadURL)) + ->assign('hasAPIKey', trim(Helper::getSetting("api_key")) !== ''); + + Shop::Smarty()->display($oPlugin->cAdminmenuPfad . '/tpl/orders.tpl'); +} catch (Exception $e) { + echo "
" . + "{$e->getMessage()}
" . + "
{$e->getFile()}:{$e->getLine()}
{$e->getTraceAsString()}
" . + "
"; + Helper::logExc($e); +} diff --git a/version/107/adminmenu/paymentmethods.php b/version/107/adminmenu/paymentmethods.php new file mode 100644 index 0000000..1782978 --- /dev/null +++ b/version/107/adminmenu/paymentmethods.php @@ -0,0 +1,60 @@ +setApiKey(Helper::getSetting("api_key")); + + $profile = $mollie->profiles->get('me'); + /* $methods = $mollie->methods->all([ + //'locale' => 'de_DE', + 'include' => 'pricing', + ]);*/ + + $za = filter_input(INPUT_GET, 'za', FILTER_VALIDATE_BOOLEAN); + $active = filter_input(INPUT_GET, 'active', FILTER_VALIDATE_BOOLEAN); + $amount = filter_input(INPUT_GET, 'amount', FILTER_VALIDATE_FLOAT) ?: null; + $locale = filter_input(INPUT_GET, 'locale', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^[a-zA-Z]{2}_[a-zA-Z]{2}$/']]) ?: null; + $currency = filter_input(INPUT_GET, 'currency', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^[a-zA-Z]{3}$/']]) ?: 'EUR'; + + if ($za) { + Shop::Smarty()->assign('defaultTabbertab', Helper::getAdminmenu("Zahlungsarten")); + } + + $params = ['include' => 'pricing,issuers']; + if ($amount && $currency && $locale) { + $params['amount'] = ['value' => number_format($amount, 2, '.', ''), 'currency' => $currency]; + $params['locale'] = $locale; + if ($active) { + $params['includeWallets'] = 'applepay'; + $params['resource'] = 'orders'; + } + } + + if ($active) { + $allMethods = $mollie->methods->allActive($params); + } else { + $allMethods = $mollie->methods->allAvailable($params); + } + + Shop::Smarty()->assign('profile', $profile) + ->assign('currencies', Mollie::getCurrencies()) + ->assign('locales', Mollie::getLocales()) + ->assign('allMethods', $allMethods); + Shop::Smarty()->display($oPlugin->cAdminmenuPfad . '/tpl/paymentmethods.tpl'); +} catch (Exception $e) { + echo "
{$e->getMessage()}
"; + Helper::logExc($e); +} diff --git a/version/107/adminmenu/tpl/info.tpl b/version/107/adminmenu/tpl/info.tpl new file mode 100644 index 0000000..77a48dc --- /dev/null +++ b/version/107/adminmenu/tpl/info.tpl @@ -0,0 +1,96 @@ +
+
+
+ + + +
+
+ + + +
+ + {if isset($update)} +
+ +
+

Update auf Version {$update->version} verfügbar!

+
+
+
+
Version:
+
{$update->version}
+
+
+
Erschienen:
+
{$update->create_date}
+
+
+
Changelog:
+
+ +
+
+ +
+
+ +
+
+
+ {else} +
+ + + +
+ {/if} + +
+
+
+ + + +
+
+ + + +
+ +
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+{if file_exists("{$smarty['current_dir']}/_addon.tpl")} + {include file="{$smarty['current_dir']}/_addon.tpl"} +{/if} \ No newline at end of file diff --git a/version/107/adminmenu/tpl/mollie-account-erstellen.png b/version/107/adminmenu/tpl/mollie-account-erstellen.png new file mode 100644 index 0000000..fc18192 Binary files /dev/null and b/version/107/adminmenu/tpl/mollie-account-erstellen.png differ diff --git a/version/107/adminmenu/tpl/order.tpl b/version/107/adminmenu/tpl/order.tpl new file mode 100644 index 0000000..5b3d172 --- /dev/null +++ b/version/107/adminmenu/tpl/order.tpl @@ -0,0 +1,286 @@ + +

+ « + Bestellung: {$oBestellung->cBestellNr} - + {if $oBestellung->cStatus|intval == 1} + OFFEN + {elseif $oBestellung->cStatus|intval == 2} + IN BEARBEITUNG + {elseif $oBestellung->cStatus|intval == 3} + BEZAHLT + {elseif $oBestellung->cStatus|intval == 4} + VERSANDT + {elseif $oBestellung->cStatus|intval == 5} + TEILVERSANDT + {elseif $oBestellung->cStatus|intval == -1} + STORNO + {else} + n/a + {/if} +

+ +{if count($ordersMsgs)} + {foreach from=$ordersMsgs item=alert} +
{$alert->text}
+ {/foreach} +
+{/if} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Mollie ID:{$payment->kID}Mode:{$order->mode}Status: + {$order->status} + {if $order->amountRefunded && $order->amountRefunded->value == $order->amount->value} + (total refund) + {elseif $order->amountRefunded && $order->amountRefunded->value > 0} + (partly refund) + {/if} +
Betrag:{$order->amount->value|number_format:2:',':''} {$order->amount->currency}Captured:{if $order->amountCaptured}{$order->amountCaptured->value|number_format:2:',':''} {$order->amountCaptured->currency}{else}-{/if}Refunded:{if $order->amountRefunded}{$order->amountRefunded->value|number_format:2:',':''} {$order->amountRefunded->currency}{else}-{/if} +
Method:{$order->method}Locale:{$order->locale}Erstellt:{"d. M Y H:i:s"|date:($order->createdAt|strtotime)}
Kunde: + {if $order->billingAddress->organizationName}{$order->billingAddress->organizationName}{else}{$order->billingAddress->title} {$order->billingAddress->givenName} {$order->billingAddress->familyName}{/if} + Zahlungslink: + {$payment->cCheckoutURL} +
+{if $order->payments()->count > 0} +

Zahlungen

+ + + + + + + + + + + + + + {foreach from=$order->payments() item=payment} + + + + + + + + + + + {/foreach} +
IDStatusMethodeAmountSettlementRefundedRemainingDetails
{$payment->id}{$payment->status}{$payment->method}{$payment->amount->value} {$payment->amount->currency} + {if $payment->settlementAmount} + {$payment->settlementAmount->value} {$payment->settlementAmount->currency} + {else}-{/if} + + {if $payment->amountRefunded} + {$payment->amountRefunded->value} {$payment->amountRefunded->currency} + {else}-{/if} + + {if $payment->amountRemaining} + {$payment->amountRemaining->value} {$payment->amountRemaining->currency} + {else}-{/if} + +
    + {foreach from=$payment->details item=value key=key} +
  • {$key}: {if $value|is_scalar}{$value}{else}{$value|json_encode}{/if}
  • + {/foreach} +
+
+{/if} + + +

Positionen:

+ +
+ {if ($order->status === 'authorized' || $order->status === 'shipping') && $oBestellung->cStatus|intval >= 3} + + Zahlung erfassen1 + + {/if} + {if !$order->amountRefunded || ($order->amount->value > $order->amountRefunded->value && $order->amountCaptured->value > 0)} + Rückerstatten2 + + {/if} + {if $order->isCancelable} + Stornieren3 + + {/if} +
+ + + + + + + + + + + + + + + + + + {assign var="vat" value=0} + {assign var="netto" value=0} + {assign var="brutto" value=0} + {foreach from=$order->lines item=line} + + {assign var="vat" value=$vat+$line->vatAmount->value} + {assign var="netto" value=$netto+$line->totalAmount->value-$line->vatAmount->value} + {assign var="brutto" value=$brutto+$line->totalAmount->value} + + + + + + + + + + + + + {/foreach} + + + + + + + + + + +
StatusSKUNameTypAnzahlMwStSteuerNettoBrutto 
+ {if $line->status == 'created'} + erstellt + {elseif $line->status == 'pending'} + austehend + {elseif $line->status == 'paid'} + bezahlt + {elseif $line->status == 'authorized'} + autorisiert + {elseif $line->status == 'shipping'} + versendet + {elseif $line->status == 'completed'} + abgeschlossen + {elseif $line->status == 'expired'} + abgelaufen + {elseif $line->status == 'canceled'} + storniert + {else} + Unbekannt: {$line->status} + {/if} + {$line->sku}{$line->name|utf8_decode}{$line->type}{$line->quantity}{$line->vatRate|floatval}%{$line->vatAmount->value|number_format:2:',':''} {$line->vatAmount->currency}{($line->totalAmount->value - $line->vatAmount->value)|number_format:2:',':''} {$line->vatAmount->currency}{$line->totalAmount->value|number_format:2:',':''} {$line->totalAmount->currency} + {*if $line->quantity > $line->quantityShipped} + + + + {/if} + {if $line->quantity > $line->quantityRefunded} + + + + {/if} + {if $line->isCancelable} + + + + {/if*} + {*$line|var_dump*} +
{$vat|number_format:2:',':''} {$order->amount->currency}{$netto|number_format:2:',':''} {$order->amount->currency}{$brutto|number_format:2:',':''} {$order->amount->currency} 
+ +
+ 1 = Bestellung wird bei Mollie als versandt markiert. WAWI wird nicht informiert.
+ 2 = Bezahlter Betrag wird dem Kunden rckerstattet. WAWI wird nicht informiert.
+ 3 = Bestellung wird bei Mollie storniert. WAWI wird nicht informiert.
+
+ +

Log

+ + + {foreach from=$logs item=log} + + + + + + + {/foreach} +
+ {if $log->nLevel == 1} + Fehler + {elseif $log->nLevel == 2} + Hinweis + {elseif $log->nLevel == 3} + Debug + {else} + unknown {$log->nLevel} + {/if} + {$log->cModulId} +
+ {$log->cLog} +
+
{$log->dDatum}
+ + diff --git a/version/107/adminmenu/tpl/orders.tpl b/version/107/adminmenu/tpl/orders.tpl new file mode 100644 index 0000000..4ec7af3 --- /dev/null +++ b/version/107/adminmenu/tpl/orders.tpl @@ -0,0 +1,135 @@ + +{if count($ordersMsgs)} + {foreach from=$ordersMsgs item=alert} +
{$alert->text}
+ {/foreach} +
+{/if} + +{if $hasAPIKey == false} + + Jetzt kostenlos Mollie Account eröffnen! + +{else} + + + + + + + + + + + + + + + + {foreach from=$payments item=payment} + + + + + + + + + + + + {/foreach} + +
BestellNr.IDMollie StatusJTL StatusBetragWährungLocaleMethodeErstellt
+ {$payment->cOrderNumber} + {if $payment->cMode == 'test'} + TEST + {/if} + + {$payment->kID} + + {if $payment->cStatus == 'created'} + erstellt + {elseif $payment->cStatus == 'pending'} + austehend + {elseif $payment->cStatus == 'paid'} + bezahlt + {elseif $payment->cStatus == 'authorized'} + autorisiert + {elseif $payment->cStatus == 'shipping'} + versendet + {elseif $payment->cStatus == 'completed'} + abgeschlossen + {elseif $payment->cStatus == 'expired'} + abgelaufen + {elseif $payment->cStatus == 'canceled'} + storniert + {else} + Unbekannt: {$payment->cStatus} + {/if} + {if $payment->fAmountRefunded && $payment->fAmountRefunded == $payment->fAmount} + (total refund) + {elseif $payment->fAmountRefunded && $payment->fAmountRefunded > 0} + (partly refund) + {/if} + + + {if $payment->oBestellung->cStatus|intval == 1} + OFFEN + {elseif $payment->oBestellung->cStatus|intval == 2} + IN BEARBEITUNG + {elseif $payment->oBestellung->cStatus|intval == 3} + BEZAHLT + {elseif $payment->oBestellung->cStatus|intval == 4} + VERSANDT + {elseif $payment->oBestellung->cStatus|intval == 5} + TEILVERSANDT + {elseif $payment->oBestellung->cStatus|intval == -1} + STORNO + {else} + n/a + {/if} + {$payment->fAmount|number_format:2:',':''}{$payment->cCurrency}{$payment->cLocale}{$payment->cMethod}{"d. M Y H:i"|date:($payment->dCreatedAt|strtotime)}
+ {if $payments|count > 900} +
Hier werden nur die letzten 1000 Ergebnisse angezeigt.
+ {/if} + + +
+
+

Export:

+
+ +
+ + + + + +
+
+ +{/if} + diff --git a/version/107/adminmenu/tpl/paymentmethods.tpl b/version/107/adminmenu/tpl/paymentmethods.tpl new file mode 100644 index 0000000..4c37e02 --- /dev/null +++ b/version/107/adminmenu/tpl/paymentmethods.tpl @@ -0,0 +1,97 @@ +

Account Status

+ + + + + + + {if $profile->review} + + + {/if} + +
Mode:{$profile->mode}Status:{$profile->status}Review:{$profile->review->status}
+ +
+ +
+
+ + +
+ + + +
+
+ + +
+
+ + +
+
+ + + reset +
+
+
+ + +{if $allMethods && $allMethods|count} + + + + + + + + + + + + {foreach from=$allMethods item=method} + + + + + + + + {/foreach} + +
BildIDNamePreiseInfos
{$method->description|utf8_decode}{$method->id}{$method->description|utf8_decode} +
    + {foreach from=$method->pricing item=price} +
  • {$price->description|utf8_decode}: {$price->fixed->value} {$price->fixed->currency} + {if $price->variable > 0.0} + + {$price->variable}% + {/if} +
  • + {/foreach} +
+
+ Min: {if $method->minimumAmount}{$method->minimumAmount->value} {$method->minimumAmount->currency}{else}n/a{/if} +
+ Max: {if $method->maximumAmount}{$method->maximumAmount->value} {$method->maximumAmount->currency}{else}n/a{/if} +
+{else} +
Es konnten keine Methoden abgerufen werden.
+{/if} \ No newline at end of file diff --git a/version/106/class/ExclusiveLock.php b/version/107/class/ExclusiveLock.php similarity index 100% rename from version/106/class/ExclusiveLock.php rename to version/107/class/ExclusiveLock.php diff --git a/version/107/class/Helper.php b/version/107/class/Helper.php new file mode 100644 index 0000000..8f4772c --- /dev/null +++ b/version/107/class/Helper.php @@ -0,0 +1,311 @@ +short_url != '' ? $release->short_url : $release->full_url; + $filename = basename($release->full_url); + $tmpDir = PFAD_ROOT . PFAD_COMPILEDIR; + $pluginsDir = PFAD_ROOT . PFAD_PLUGIN; + + // 1. PRE-CHECKS + if (file_exists($pluginsDir . self::oPlugin()->cVerzeichnis . '/.git') && is_dir($pluginsDir . self::oPlugin()->cVerzeichnis . '/.git')) { + throw new Exception('Pluginordner enthält ein GIT Repository, kein Update möglich!'); + } + + if (!function_exists("curl_exec")) { + throw new Exception("cURL ist nicht verfügbar!!"); + } + if (!is_writable($tmpDir)) { + throw new Exception("Temporäres Verzeichnis_'{$tmpDir}' ist nicht beschreibbar!"); + } + if (!is_writable($pluginsDir . self::oPlugin()->cVerzeichnis)) { + throw new Exception("Plugin Verzeichnis_'" . $pluginsDir . self::oPlugin()->cVerzeichnis . "' ist nicht beschreibbar!"); + } + if (file_exists($tmpDir . $filename)) { + if (!unlink($tmpDir . $filename)) { + throw new Exception("Temporäre Datei '" . $tmpDir . $filename . "' konnte nicht gelöscht werden!"); + } + } + + // 2. DOWNLOAD + $fp = fopen($tmpDir . $filename, 'w+'); + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_TIMEOUT, 50); + curl_setopt($ch, CURLOPT_FILE, $fp); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_exec($ch); + $info = curl_getinfo($ch); + curl_close($ch); + fclose($fp); + if ($info['http_code'] !== 200) { + throw new Exception("Unerwarteter Status Code '" . $info['http_code'] . "'!"); + } + if ($info['download_content_length'] <= 0) { + throw new Exception("Unerwartete Downloadgröße '" . $info['download_content_length'] . "'!"); + } + + // 3. UNZIP + require_once PFAD_ROOT . PFAD_PCLZIP . 'pclzip.lib.php'; + $zip = new PclZip($tmpDir . $filename); + $content = $zip->listContent(); + + if (!is_array($content) || !isset($content[0]['filename']) || strpos($content[0]['filename'], '.') !== false) { + throw new Exception("Das Zip-Archiv ist leider ungültig!"); + } else { + $unzipPath = PFAD_ROOT . PFAD_PLUGIN; + $res = $zip->extract(PCLZIP_OPT_PATH, $unzipPath, PCLZIP_OPT_REPLACE_NEWER); + if ($res !== 0) { + header('Location: ' . Shop::getURL() . DIRECTORY_SEPARATOR . PFAD_ADMIN . 'pluginverwaltung.php', true); + } else { + throw new Exception('Entpacken fehlgeschlagen: ' . $zip->errorCode()); + } + } + } + + /** + * @param bool $force + * @return mixed + * @throws Exception + */ + public static function getLatestRelease($force = false) + { + $lastCheck = (int)self::getSetting(__NAMESPACE__ . '_upd'); + $lastRelease = file_exists(PFAD_ROOT . PFAD_COMPILEDIR . __NAMESPACE__ . '_upd') ? file_get_contents(PFAD_ROOT . PFAD_COMPILEDIR . __NAMESPACE__ . '_upd') : false; + if ($force || !$lastCheck || !$lastRelease || ($lastCheck + 12 * 60 * 60) < time()) { + $curl = curl_init('https://api.dash.bar/release/' . __NAMESPACE__); + @curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5); + @curl_setopt($curl, CURLOPT_TIMEOUT, 5); + @curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + @curl_setopt($curl, CURLOPT_HEADER, 0); + @curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + @curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); + + $data = curl_exec($curl); + $statusCode = (int)curl_getinfo($curl, CURLINFO_HTTP_CODE); + @curl_close($curl); + if ($statusCode !== 200) { + throw new Exception(__NAMESPACE__ . ': Could not fetch release info: ' . $statusCode); + } + $json = json_decode($data); + if (json_last_error() || $json->status != 'ok') { + throw new Exception(__NAMESPACE__ . ': Could not decode release info: ' . $data); + } + self::setSetting(__NAMESPACE__ . '_upd', time()); + file_put_contents(PFAD_ROOT . PFAD_COMPILEDIR . __NAMESPACE__ . '_upd', json_encode($json->data)); + return $json->data; + } else { + return json_decode($lastRelease); + } + } + + /** + * Register PSR-4 autoloader + * Licence-Check + * @return bool + */ + public static function init() + { + ini_set('xdebug.default_enable', defined('WS_XDEBUG_ENABLED')); + return self::autoload(); + } + + /** + * Sets a Plugin Setting and saves it to the DB + * + * @param $name + * @param $value + * @return int + */ + public static function setSetting($name, $value) + { + $setting = new stdClass; + $setting->kPlugin = self::oPlugin()->kPlugin; + $setting->cName = $name; + $setting->cWert = $value; + + if (array_key_exists($name, self::oPlugin()->oPluginEinstellungAssoc_arr)) { + $return = Shop::DB()->updateRow('tplugineinstellungen', ['kPlugin', 'cName'], [$setting->kPlugin, $setting->cName], $setting); + } else { + $return = Shop::DB()->insertRow('tplugineinstellungen', $setting); + } + self::oPlugin()->oPluginEinstellungAssoc_arr[$name] = $value; + self::oPlugin(true); // invalidate cache + return $return; + } + + /** + * Get Plugin Object + * + * @param bool $force disable Cache + * @return Plugin|null + */ + public static function oPlugin($force = false) + { + if ($force === true) { + self::$oPlugin = new Plugin(self::oPlugin(false)->kPlugin, true); + } else if (null === self::$oPlugin) { + self::$oPlugin = Plugin::getPluginById(__NAMESPACE__); + } + return self::$oPlugin; + } + + /** + * get a Plugin setting + * + * @param $name + * @return null|mixed + */ + public static function getSetting($name) + { + if (array_key_exists($name, self::oPlugin()->oPluginEinstellungAssoc_arr ?: [])) { + return self::oPlugin()->oPluginEinstellungAssoc_arr[$name]; + } + return null; + } + + /** + * Get Domain frpm URL_SHOP without www. + * + * @param string $url + * @return string + */ + public static function getDomain($url = URL_SHOP) + { + $matches = array(); + @preg_match("/^((http(s)?):\/\/)?(www\.)?([a-zA-Z0-9-\.]+)(\/.*)?$/i", $url, $matches); + return strtolower(isset($matches[5]) ? $matches[5] : $url); + } + + /** + * @param bool $e + * @return mixed + */ + public static function getMasterMail($e = false) + { + $settings = Shop::getSettings(array(CONF_EMAILS)); + $mail = trim($settings['emails']['email_master_absender']); + if ($e === true && $mail != '') { + $mail = base64_encode($mail); + $eMail = ""; + foreach (str_split($mail, 1) as $c) { + $eMail .= chr(ord($c) ^ 0x00100110); + } + return base64_encode($eMail); + } + return $mail; + } + + /** + * @param Exception $exc + * @param bool $trace + * @return void + */ + public static function logExc(Exception $exc, $trace = true) + { + Jtllog::writeLog(__NAMESPACE__ . ': ' . $exc->getMessage() . ($trace ? ' - ' . $exc->getTraceAsString() : '')); + } + + /** + * Checks if admin session is loaded + * + * @return bool + */ + public static function isAdminBackend() + { + return session_name() === 'eSIdAdm'; + } + + /** + * Returns kAdminmenu ID for given Title, used for Tabswitching + * + * @param $name string CustomLink Title + * @return int + */ + public static function getAdminmenu($name) + { + $kPluginAdminMenu = 0; + foreach (self::oPlugin()->oPluginAdminMenu_arr as $adminmenu) { + if (strtolower($adminmenu->cName) == strtolower($name)) { + $kPluginAdminMenu = $adminmenu->kPluginAdminMenu; + break; + } + } + return $kPluginAdminMenu; + } + + } + } + +} diff --git a/version/107/class/Model/AbstractModel.php b/version/107/class/Model/AbstractModel.php new file mode 100644 index 0000000..5638700 --- /dev/null +++ b/version/107/class/Model/AbstractModel.php @@ -0,0 +1,7 @@ +id; + $data = [ + ':kID' => $oMolliePayment->id, + ':kBestellung' => (int)$kBestellung ?: null, + ':kBestellung1' => (int)$kBestellung ?: null, + ':cMode' => $oMolliePayment->mode, + ':cStatus' => $oMolliePayment->status, + ':cStatus1' => $oMolliePayment->status, + ':cHash' => $hash, + ':fAmount' => $oMolliePayment->amount->value, + ':cOrderNumber' => $oMolliePayment->orderNumber, + ':cOrderNumber1' => $oMolliePayment->orderNumber, + ':cCurrency' => $oMolliePayment->amount->currency, + ':cMethod' => $oMolliePayment->method, + ':cMethod1' => $oMolliePayment->method, + ':cLocale' => $oMolliePayment->locale, + ':bCancelable' => $oMolliePayment->isCancelable, + ':bCancelable1' => $oMolliePayment->isCancelable, + ':cWebhookURL' => $oMolliePayment->webhookUrl, + ':cRedirectURL' => $oMolliePayment->redirectUrl, + ':cCheckoutURL' => $oMolliePayment->getCheckoutUrl(), + ':cCheckoutURL1' => $oMolliePayment->getCheckoutUrl(), + ':fAmountCaptured' => $oMolliePayment->amountCaptured ? $oMolliePayment->amountCaptured->value : null, + ':fAmountCaptured1' => $oMolliePayment->amountCaptured ? $oMolliePayment->amountCaptured->value : null, + ':fAmountRefunded' => $oMolliePayment->amountRefunded ? $oMolliePayment->amountRefunded->value : null, + ':fAmountRefunded1' => $oMolliePayment->amountRefunded ? $oMolliePayment->amountRefunded->value : null, + ':dCreatedAt' => $oMolliePayment->createdAt ? date('Y-m-d H:i:s', strtotime($oMolliePayment->createdAt)) : null, + ]; + Mollie::JTLMollie()->doLog('Payment::updateFromPayment
' . print_r([$kBestellung, $oMolliePayment], 1) . '
', $logData); + return Shop::DB()->executeQueryPrepared( + 'INSERT INTO ' . self::TABLE . ' (kID, kBestellung, cMode, cStatus, cHash, fAmount, cOrderNumber, cCurrency, cMethod, cLocale, bCancelable, cWebhookURL, cRedirectURL, cCheckoutURL, fAmountCaptured, fAmountRefunded, dCreatedAt) ' + . 'VALUES (:kID, :kBestellung, :cMode, :cStatus, :cHash, :fAmount, :cOrderNumber, :cCurrency, :cMethod, :cLocale, :bCancelable, :cWebhookURL, :cRedirectURL, IF(:cCheckoutURL IS NULL, cCheckoutURL, :cCheckoutURL1), :fAmountCaptured, :fAmountRefunded, :dCreatedAt) ' + . 'ON DUPLICATE KEY UPDATE kBestellung = :kBestellung1, cOrderNumber = :cOrderNumber1, cStatus = :cStatus1, cMethod = :cMethod1, bCancelable = :bCancelable1, fAmountCaptured = :fAmountCaptured1, fAmountRefunded = :fAmountRefunded1', + $data, + 3 + ); + } + + public static function getPayment($kBestellung) + { + $payment = Shop::DB()->executeQueryPrepared('SELECT * FROM ' . self::TABLE . ' WHERE kBestellung = :kBestellung', [':kBestellung' => $kBestellung], 1); + if ($payment && $payment->kBestellung) { + $payment->oBestellung = new Bestellung($payment->kBestellung, false); + } + return $payment; + } + + public static function getPaymentMollie($kID) + { + $payment = Shop::DB()->executeQueryPrepared('SELECT * FROM ' . self::TABLE . ' WHERE kID = :kID', [':kID' => $kID], 1); + if ($payment && $payment->kBestellung) { + $payment->oBestellung = new Bestellung($payment->kBestellung, false); + } + return $payment; + } + + /** + * @param $cHash + * @return array|int|object + */ + public static function getPaymentHash($cHash) + { + $payment = Shop::DB()->executeQueryPrepared('SELECT * FROM ' . self::TABLE . ' WHERE cHash = :cHash', [':cHash' => $cHash], 1); + if ($payment && $payment->kBestellung) { + $payment->oBestellung = new Bestellung($payment->kBestellung, false); + } + return $payment; + } +} diff --git a/version/107/class/Mollie.php b/version/107/class/Mollie.php new file mode 100644 index 0000000..6d0fd4c --- /dev/null +++ b/version/107/class/Mollie.php @@ -0,0 +1,548 @@ +getValue(CONF_KAUFABWICKLUNG, 'bestellabschluss_abschlussseite'); + + $bestellid = Shop::DB()->select("tbestellid ", 'kBestellung', (int)$kBestellung); + $url = Shop::getURL() . '/bestellabschluss.php?i=' . $bestellid->cId; + + + if ($mode == 'S' || !$bestellid) { // Statusseite + $bestellstatus = Shop::DB()->select('tbestellstatus', 'kBestellung', (int)$kBestellung); + $url = Shop::getURL() . '/status.php?uid=' . $bestellstatus->cUID; + } + + if ($redirect) { + if (!headers_sent()) { + header('Location: ' . $url); + } + echo "redirect ..."; + exit(); + } + return $url; + } + + /** + * @param Order $order + * @param $kBestellung + * @param bool $newStatus + * @return array + * @throws Exception + */ + public static function getShipmentOptions(Order $order, $kBestellung, $newStatus = false) + { + if (!$order || !$kBestellung) { + throw new Exception('Mollie::getShipmentOptions: order and kBestellung are required!'); + } + + $oBestellung = new Bestellung($kBestellung, true); + if ($newStatus === false) { + $newStatus = $oBestellung->cStatus; + } + $options = []; + + // Tracking Data + if ($oBestellung->cTracking) { + $tracking = new stdClass(); + $tracking->carrier = $oBestellung->cVersandartName; + $tracking->url = $oBestellung->cTrackingURL; + $tracking->code = $oBestellung->cTracking; + $options['tracking'] = $tracking; + } + + $logData = '#' . $oBestellung->kBestellung . '§' . $oBestellung->cBestellNr . '$' . $order->id; + + switch ((int)$newStatus) { + case BESTELLUNG_STATUS_VERSANDT: + Mollie::JTLMollie()->doLog('181_sync: Bestellung versandt', $logData, LOGLEVEL_DEBUG); + $options['lines'] = []; + break; + case BESTELLUNG_STATUS_TEILVERSANDT: + $lines = []; + foreach ($order->lines as $i => $line) { + if ($line->totalAmount->value > 0.0) + if (($quantity = Mollie::getBestellPosSent($line->sku, $oBestellung)) !== false && ($quantity - $line->quantityShipped) > 0) { + $x = min($quantity - $line->quantityShipped, $line->shippableQuantity); + if ($x > 0) { + $lines[] = (object)[ + 'id' => $line->id, + 'quantity' => $x, + 'amount' => (object)[ + 'currency' => $line->totalAmount->currency, + 'value' => number_format($x * $line->unitPrice->value, 2), + ], + ]; + } + } + } + Mollie::JTLMollie()->doLog('181_sync: Bestellung teilversandt', $logData, LOGLEVEL_DEBUG); + if (count($lines)) { + $options['lines'] = $lines; + } + break; + case BESTELLUNG_STATUS_STORNO: + Mollie::JTLMollie()->doLog('181_sync: Bestellung storniert', $logData, LOGLEVEL_DEBUG); + $options = null; + break; + case BESTELLUNG_STATUS_BEZAHLT: + case BESTELLUNG_STATUS_IN_BEARBEITUNG: + case BESTELLUNG_STATUS_OFFEN: + // NOTHING TO DO! + break; + default: + Mollie::JTLMollie()->doLog('181_sync: Bestellungstatus unbekannt: ' . $newStatus . '/' . $oBestellung->cStatus, $logData, LOGLEVEL_DEBUG); + } + + return $options; + } + + /** + * @return JTLMollie + * @throws Exception + */ + public static function JTLMollie() + { + if (self::$_jtlmollie === null) { + $pza = Shop::DB()->select('tpluginzahlungsartklasse', 'cClassName', 'JTLMollie'); + if (!$pza) { + throw new Exception("Mollie Zahlungsart nicht in DB gefunden!"); + } + require_once __DIR__ . '/../paymentmethod/JTLMollie.php'; + self::$_jtlmollie = new JTLMollie($pza->cModulId); + } + return self::$_jtlmollie; + } + + /** + * Returns amount of sent items for SKU + * @param $sku + * @param Bestellung $oBestellung + * @return float|int + * @throws Exception + */ + public static function getBestellPosSent($sku, Bestellung $oBestellung) + { + if ($sku === null) { + return 1; + } + /** @var WarenkorbPos $oPosition */ + foreach ($oBestellung->Positionen as $oPosition) { + if ($oPosition->cArtNr === $sku) { + $sent = 0; + /** @var Lieferschein $oLieferschein */ + foreach ($oBestellung->oLieferschein_arr as $oLieferschein) { + /** @var Lieferscheinpos $oLieferscheinPos */ + foreach ($oLieferschein->oLieferscheinPos_arr as $oLieferscheinPos) { + if ($oLieferscheinPos->getBestellPos() == $oPosition->kBestellpos) { + $sent += $oLieferscheinPos->getAnzahl(); + } + } + } + return $sent; + } + } + return false; + } + + /** + * + */ + public static function fixZahlungsarten() + { + $kPlugin = Helper::oPlugin()->kPlugin; + $test1 = 'kPlugin_%_mollie%'; + $test2 = 'kPlugin_' . $kPlugin . '_mollie%'; + $conflicted_arr = Shop::DB()->executeQueryPrepared("SELECT kZahlungsart, cName, cModulId FROM `tzahlungsart` WHERE cModulId LIKE :test1 AND cModulId NOT LIKE :test2", [ + ':test1' => $test1, + ':test2' => $test2, + ], 2); + if ($conflicted_arr && count($conflicted_arr)) { + foreach ($conflicted_arr as $conflicted) { + Shop::DB()->executeQueryPrepared('UPDATE tzahlungsart SET cModulId = :cModulId WHERE kZahlungsart = :kZahlungsart', [ + ':cModulId' => preg_replace('/^kPlugin_\d+_/', 'kPlugin_' . $kPlugin . '_', $conflicted->cModulId), + ':kZahlungsart' => $conflicted->kZahlungsart, + ], 3); + } + } + } + + /** + * @param Order $order + * @param null $kBestellung + * @return bool + * @throws Exception + */ + public static function handleOrder(Order $order, $kBestellung) + { + $logData = '$' . $order->id . '#' . $kBestellung . "§" . $order->orderNumber; + + $oBestellung = new Bestellung($kBestellung); + if ($oBestellung->kBestellung) { + + Shop::DB()->executeQueryPrepared("INSERT INTO tbestellattribut (kBestellung, cName, cValue) VALUES (:kBestellung, 'mollie_oid', :mollieId1) ON DUPLICATE KEY UPDATE cValue = :mollieId2;", [ + ':kBestellung' => $kBestellung, + ':mollieId1' => $order->id, + ':mollieId2' => $order->id, + ], 3); + + Shop::DB()->executeQueryPrepared("INSERT INTO tbestellattribut (kBestellung, cName, cValue) VALUES (:kBestellung, 'mollie_cBestellNr', :orderId1) ON DUPLICATE KEY UPDATE cValue = :orderId2;", [ + ':kBestellung' => $kBestellung, + ':orderId1' => $oBestellung->cBestellNr, + ':orderId2' => $oBestellung->cBestellNr, + ], 3); + + if(isset($order->metadata->originalOrderNumber)){ + Shop::DB()->executeQueryPrepared("INSERT INTO tbestellattribut (kBestellung, cName, cValue) VALUES (:kBestellung, 'mollie_cFakeBestellNr', :orderId1) ON DUPLICATE KEY UPDATE cValue = :orderId2;", [ + ':kBestellung' => $kBestellung, + ':orderId1' => $order->metadata->originalOrderNumber, + ':orderId2' => $order->metadata->originalOrderNumber, + ], 3); + } + + $mPayment = null; + if ($payments = $order->payments()) { + /** @var \Mollie\Api\Resources\Payment $payment */ + foreach ($payments as $payment) { + if (in_array($payment->status, [PaymentStatus::STATUS_AUTHORIZED, PaymentStatus::STATUS_PAID])) { + $mPayment = $payment; + } + } + } + if ($mPayment) { + Shop::DB()->executeQueryPrepared("INSERT INTO tbestellattribut (kBestellung, cName, cValue) VALUES (:kBestellung, 'mollie_tid', :mollieId1) ON DUPLICATE KEY UPDATE cValue = :mollieId2;", [ + ':kBestellung' => $kBestellung, + ':mollieId1' => $mPayment->id, + ':mollieId2' => $mPayment->id, + ], 3); + } + + try { + // Try to change the orderNumber + if ($order->orderNumber !== $oBestellung->cBestellNr) { + JTLMollie::API()->performHttpCall("PATCH", sprintf('orders/%s', $order->id), json_encode(['orderNumber' => $oBestellung->cBestellNr])); + } + } catch (Exception $e) { + self::JTLMollie()->doLog('Mollie::handleOrder: ' . $e->getMessage(), $logData); + } + + $_payment = self::getLastPayment($order); + + if ($_payment && $_payment->description !== $oBestellung->cBestellNr) { + JTLMollie::API()->performHttpCall('PATCH', sprintf('payments/%s', $_payment->id), json_encode(['description' => $oBestellung->cBestellNr])); + } + + + $order->orderNumber = $oBestellung->cBestellNr; + Payment::updateFromPayment($order, $kBestellung); + + $oIncomingPayment = Shop::DB()->executeQueryPrepared("SELECT * FROM tzahlungseingang WHERE kBestellung = :kBestellung", [':kBestellung' => $oBestellung->kBestellung], 1); + if (!$oIncomingPayment) { + $oIncomingPayment = new stdClass(); + } + + // 2. Check PaymentStatus + switch ($order->status) { + case OrderStatus::STATUS_PAID: + case OrderStatus::STATUS_COMPLETED: + case OrderStatus::STATUS_AUTHORIZED: + + $cHinweis = $order->id; + if ($mPayment) { + $cHinweis .= ' / ' . $mPayment->id; + } + if (Helper::getSetting('wawiPaymentID') === 'ord') { + $cHinweis = $order->id; + } elseif ($mPayment && Helper::getSetting('wawiPaymentID') === 'tr') { + $cHinweis = $mPayment->id; + } + + $oIncomingPayment->fBetrag = $order->amount->value; + $oIncomingPayment->cISO = $order->amount->currency; + $oIncomingPayment->cHinweis = $cHinweis; + Mollie::JTLMollie()->addIncomingPayment($oBestellung, $oIncomingPayment); + Mollie::JTLMollie()->setOrderStatusToPaid($oBestellung); + Mollie::JTLMollie()->doLog('Mollie::handleOrder/PaymentStatus: ' . $order->status . ' => Zahlungseingang (' . $order->amount->value . ')', $logData, LOGLEVEL_DEBUG); + break; + case OrderStatus::STATUS_SHIPPING: + case OrderStatus::STATUS_PENDING: + Mollie::JTLMollie()->setOrderStatusToPaid($oBestellung); + Mollie::JTLMollie()->doLog('Mollie::handleOrder/PaymentStatus: ' . $order->status . ' => Bestellung bezahlt, KEIN Zahlungseingang', $logData, LOGLEVEL_NOTICE); + break; + case OrderStatus::STATUS_CANCELED: + case OrderStatus::STATUS_EXPIRED: + Mollie::JTLMollie()->doLog('Mollie::handleOrder/PaymentStatus: ' . $order->status, $logData, LOGLEVEL_ERROR); + break; + } + return true; + } + return false; + } + + /** + * @param Order $order + * @return \Mollie\Api\Resources\Payment|null + */ + public static function getLastPayment(Order $order) + { + $payment = null; + if ($order->payments()) { + /** @var \Mollie\Api\Resources\Payment $p */ + foreach ($order->payments() as $p) { + if (!$payment) { + $payment = $p; + continue; + } + if (strtotime($p->createdAt) > strtotime($payment->createdAt)) { + $payment = $p; + } + } + } + return $payment; + } + + public static function getLocales() + { + $locales = ['en_US', + 'nl_NL', + 'nl_BE', + 'fr_FR', + 'fr_BE', + 'de_DE', + 'de_AT', + 'de_CH', + 'es_ES', + 'ca_ES', + 'pt_PT', + 'it_IT', + 'nb_NO', + 'sv_SE', + 'fi_FI', + 'da_DK', + 'is_IS', + 'hu_HU', + 'pl_PL', + 'lv_LV', + 'lt_LT',]; + + $laender = []; + $shopLaender = Shop::DB()->executeQuery("SELECT cLaender FROM tversandart", 2); + foreach ($shopLaender as $sL) { + $laender = array_merge(explode(' ', $sL->cLaender)); + } + $laender = array_unique($laender); + + $result = []; + $shopSprachen = Shop::DB()->executeQuery("SELECT * FROM tsprache", 2); + foreach ($shopSprachen as $sS) { + foreach ($laender as $land) { + $result[] = JTLMollie::getLocale($sS->cISO, $land); + } + } + return array_unique($result); + } + + public static function getCurrencies() + { + $currencies = ['AED' => 'AED - United Arab Emirates dirham', + 'AFN' => 'AFN - Afghan afghani', + 'ALL' => 'ALL - Albanian lek', + 'AMD' => 'AMD - Armenian dram', + 'ANG' => 'ANG - Netherlands Antillean guilder', + 'AOA' => 'AOA - Angolan kwanza', + 'ARS' => 'ARS - Argentine peso', + 'AUD' => 'AUD - Australian dollar', + 'AWG' => 'AWG - Aruban florin', + 'AZN' => 'AZN - Azerbaijani manat', + 'BAM' => 'BAM - Bosnia and Herzegovina convertible mark', + 'BBD' => 'BBD - Barbados dollar', + 'BDT' => 'BDT - Bangladeshi taka', + 'BGN' => 'BGN - Bulgarian lev', + 'BHD' => 'BHD - Bahraini dinar', + 'BIF' => 'BIF - Burundian franc', + 'BMD' => 'BMD - Bermudian dollar', + 'BND' => 'BND - Brunei dollar', + 'BOB' => 'BOB - Boliviano', + 'BRL' => 'BRL - Brazilian real', + 'BSD' => 'BSD - Bahamian dollar', + 'BTN' => 'BTN - Bhutanese ngultrum', + 'BWP' => 'BWP - Botswana pula', + 'BYN' => 'BYN - Belarusian ruble', + 'BZD' => 'BZD - Belize dollar', + 'CAD' => 'CAD - Canadian dollar', + 'CDF' => 'CDF - Congolese franc', + 'CHF' => 'CHF - Swiss franc', + 'CLP' => 'CLP - Chilean peso', + 'CNY' => 'CNY - Renminbi (Chinese) yuan', + 'COP' => 'COP - Colombian peso', + 'COU' => 'COU - Unidad de Valor Real (UVR)', + 'CRC' => 'CRC - Costa Rican colon', + 'CUC' => 'CUC - Cuban convertible peso', + 'CUP' => 'CUP - Cuban peso', + 'CVE' => 'CVE - Cape Verde escudo', + 'CZK' => 'CZK - Czech koruna', + 'DJF' => 'DJF - Djiboutian franc', + 'DKK' => 'DKK - Danish krone', + 'DOP' => 'DOP - Dominican peso', + 'DZD' => 'DZD - Algerian dinar', + 'EGP' => 'EGP - Egyptian pound', + 'ERN' => 'ERN - Eritrean nakfa', + 'ETB' => 'ETB - Ethiopian birr', + 'EUR' => 'EUR - Euro', + 'FJD' => 'FJD - Fiji dollar', + 'FKP' => 'FKP - Falkland Islands pound', + 'GBP' => 'GBP - Pound sterling', + 'GEL' => 'GEL - Georgian lari', + 'GHS' => 'GHS - Ghanaian cedi', + 'GIP' => 'GIP - Gibraltar pound', + 'GMD' => 'GMD - Gambian dalasi', + 'GNF' => 'GNF - Guinean franc', + 'GTQ' => 'GTQ - Guatemalan quetzal', + 'GYD' => 'GYD - Guyanese dollar', + 'HKD' => 'HKD - Hong Kong dollar', + 'HNL' => 'HNL - Honduran lempira', + 'HRK' => 'HRK - Croatian kuna', + 'HTG' => 'HTG - Haitian gourde', + 'HUF' => 'HUF - Hungarian forint', + 'IDR' => 'IDR - Indonesian rupiah', + 'ILS' => 'ILS - Israeli new shekel', + 'INR' => 'INR - Indian rupee', + 'IQD' => 'IQD - Iraqi dinar', + 'IRR' => 'IRR - Iranian rial', + 'ISK' => 'ISK - Icelandic króna', + 'JMD' => 'JMD - Jamaican dollar', + 'JOD' => 'JOD - Jordanian dinar', + 'JPY' => 'JPY - Japanese yen', + 'KES' => 'KES - Kenyan shilling', + 'KGS' => 'KGS - Kyrgyzstani som', + 'KHR' => 'KHR - Cambodian riel', + 'KMF' => 'KMF - Comoro franc', + 'KPW' => 'KPW - North Korean won', + 'KRW' => 'KRW - South Korean won', + 'KWD' => 'KWD - Kuwaiti dinar', + 'KYD' => 'KYD - Cayman Islands dollar', + 'KZT' => 'KZT - Kazakhstani tenge', + 'LAK' => 'LAK - Lao kip', + 'LBP' => 'LBP - Lebanese pound', + 'LKR' => 'LKR - Sri Lankan rupee', + 'LRD' => 'LRD - Liberian dollar', + 'LSL' => 'LSL - Lesotho loti', + 'LYD' => 'LYD - Libyan dinar', + 'MAD' => 'MAD - Moroccan dirham', + 'MDL' => 'MDL - Moldovan leu', + 'MGA' => 'MGA - Malagasy ariary', + 'MKD' => 'MKD - Macedonian denar', + 'MMK' => 'MMK - Myanmar kyat', + 'MNT' => 'MNT - Mongolian tögrög', + 'MOP' => 'MOP - Macanese pataca', + 'MRU' => 'MRU - Mauritanian ouguiya', + 'MUR' => 'MUR - Mauritian rupee', + 'MVR' => 'MVR - Maldivian rufiyaa', + 'MWK' => 'MWK - Malawian kwacha', + 'MXN' => 'MXN - Mexican peso', + 'MXV' => 'MXV - Mexican Unidad de Inversion (UDI)', + 'MYR' => 'MYR - Malaysian ringgit', + 'MZN' => 'MZN - Mozambican metical', + 'NAD' => 'NAD - Namibian dollar', + 'NGN' => 'NGN - Nigerian naira', + 'NIO' => 'NIO - Nicaraguan córdoba', + 'NOK' => 'NOK - Norwegian krone', + 'NPR' => 'NPR - Nepalese rupee', + 'NZD' => 'NZD - New Zealand dollar', + 'OMR' => 'OMR - Omani rial', + 'PAB' => 'PAB - Panamanian balboa', + 'PEN' => 'PEN - Peruvian sol', + 'PGK' => 'PGK - Papua New Guinean kina', + 'PHP' => 'PHP - Philippine peso', + 'PKR' => 'PKR - Pakistani rupee', + 'PLN' => 'PLN - Polish z?oty', + 'PYG' => 'PYG - Paraguayan guaraní', + 'QAR' => 'QAR - Qatari riyal', + 'RON' => 'RON - Romanian leu', + 'RSD' => 'RSD - Serbian dinar', + 'RUB' => 'RUB - Russian ruble', + 'RWF' => 'RWF - Rwandan franc', + 'SAR' => 'SAR - Saudi riyal', + 'SBD' => 'SBD - Solomon Islands dollar', + 'SCR' => 'SCR - Seychelles rupee', + 'SDG' => 'SDG - Sudanese pound', + 'SEK' => 'SEK - Swedish krona/kronor', + 'SGD' => 'SGD - Singapore dollar', + 'SHP' => 'SHP - Saint Helena pound', + 'SLL' => 'SLL - Sierra Leonean leone', + 'SOS' => 'SOS - Somali shilling', + 'SRD' => 'SRD - Surinamese dollar', + 'SSP' => 'SSP - South Sudanese pound', + 'STN' => 'STN - São Tomé and Príncipe dobra', + 'SVC' => 'SVC - Salvadoran colón', + 'SYP' => 'SYP - Syrian pound', + 'SZL' => 'SZL - Swazi lilangeni', + 'THB' => 'THB - Thai baht', + 'TJS' => 'TJS - Tajikistani somoni', + 'TMT' => 'TMT - Turkmenistan manat', + 'TND' => 'TND - Tunisian dinar', + 'TOP' => 'TOP - Tongan pa?anga', + 'TRY' => 'TRY - Turkish lira', + 'TTD' => 'TTD - Trinidad and Tobago dollar', + 'TWD' => 'TWD - New Taiwan dollar', + 'TZS' => 'TZS - Tanzanian shilling', + 'UAH' => 'UAH - Ukrainian hryvnia', + 'UGX' => 'UGX - Ugandan shilling', + 'USD' => 'USD - United States dollar', + 'UYI' => 'UYI - Uruguay Peso en Unidades Indexadas', + 'UYU' => 'UYU - Uruguayan peso', + 'UYW' => 'UYW - Unidad previsional', + 'UZS' => 'UZS - Uzbekistan som', + 'VES' => 'VES - Venezuelan bolívar soberano', + 'VND' => 'VND - Vietnamese ??ng', + 'VUV' => 'VUV - Vanuatu vatu', + 'WST' => 'WST - Samoan tala', + 'YER' => 'YER - Yemeni rial', + 'ZAR' => 'ZAR - South African rand', + 'ZMW' => 'ZMW - Zambian kwacha', + 'ZWL' => 'ZWL - Zimbabwean dollar']; + + $shopCurrencies = Shop::DB()->executeQuery("SELECT * FROM twaehrung", 2); + + $result = []; + + foreach ($shopCurrencies as $sC) { + if (array_key_exists($sC->cISO, $currencies)) { + $result[$sC->cISO] = $currencies[$sC->cISO]; + } + } + + return $result; + } +} diff --git a/version/107/frontend/131_globalinclude.php b/version/107/frontend/131_globalinclude.php new file mode 100644 index 0000000..916a7f9 --- /dev/null +++ b/version/107/frontend/131_globalinclude.php @@ -0,0 +1,120 @@ +cNotifyID; + + if (!(int)$oZahlungSession->kBestellung && $oZahlungSession->cNotifyID) { + Mollie::JTLMollie()->doLog("Hook 131: Bestellung noch nicht finalisiert ({$oZahlungSession->cNotifyID})", $logData, LOGLEVEL_DEBUG); + // Bestellung noch nicht finalisiert + $mOrder = JTLMollie::API()->orders->get($oZahlungSession->cNotifyID, ['embed' => 'payments']); + if ($mOrder && $mOrder->id === $oZahlungSession->cNotifyID) { + + $lock = new \ws_mollie\ExclusiveLock('mollie_' . $mOrder->id, PFAD_ROOT . PFAD_COMPILEDIR); + $logged = false; + $maxWait = 300; + while (!$lock->lock() && $maxWait > 0) { + if (!$logged) { + Mollie::JTLMollie()->doLog("Hook 131: Order currently locked ({$oZahlungSession->cNotifyID})", $logData, LOGLEVEL_DEBUG); + $logged = microtime(true); + } + usleep(100000); + $maxWait--; + } + + if ($logged) { + Mollie::JTLMollie()->doLog("Hook 131: Order unlocked (after " . round(microtime(true) - $logged, 2) . "s - maxWait left: {$maxWait})", $logData, LOGLEVEL_DEBUG); + } else { + Mollie::JTLMollie()->doLog("Hook 131: Order locked - maxWait left: {$maxWait})", $logData, LOGLEVEL_DEBUG); + } + + $oZahlungSession = JTLMollie::getZahlungSession($_REQUEST['mollie']); + if ((int)$oZahlungSession->kBestellung) { + Mollie::JTLMollie()->doLog("Hook 131: Order finalized already ({$oZahlungSession->kBestellung}) => redirect", $logData, LOGLEVEL_DEBUG); + return Mollie::getOrderCompletedRedirect($oZahlungSession->kBestellung, true); + } + + Mollie::JTLMollie()->doLog("Hook 131: Order {$mOrder->id} - {$mOrder->status}
" . print_r($mOrder, 1) . "
", $logData, LOGLEVEL_DEBUG); + if (!in_array($mOrder->status, [OrderStatus::STATUS_EXPIRED, OrderStatus::STATUS_CANCELED])) { + + $payment = Mollie::getLastPayment($mOrder); + if (in_array($payment->status, [PaymentStatus::STATUS_AUTHORIZED, PaymentStatus::STATUS_PAID, PaymentStatus::STATUS_PENDING])) { + + if (session_id() !== $oZahlungSession->cSID) { + Mollie::JTLMollie()->doLog("Hook 131: Switch to PaymentSession
" . print_r([session_id(), $oZahlungSession], 1) . "
", $logData, LOGLEVEL_DEBUG); + session_destroy(); + session_id($oZahlungSession->cSID); + $session = Session::getInstance(true, true); + } else { + Mollie::JTLMollie()->doLog("Hook 131: Already in PaymentSession
" . print_r([session_id(), $oZahlungSession], 1) . "
", $logData, LOGLEVEL_DEBUG); + $session = Session::getInstance(false, false); + } + + require_once PFAD_ROOT . 'includes/bestellabschluss_inc.php'; + require_once PFAD_ROOT . 'includes/mailTools.php'; + + $order = fakeBestellung(); + $order = finalisiereBestellung(); + $session->cleanUp(); + $logData .= '#' . $order->kBestellung . 'ß' . $order->cBestellNr; + Mollie::JTLMollie()->doLog("Hook 131: Bestellung finalisiert
" . print_r([$order->kBestellung, $order->cBestellNr], 1) . "
", $logData, LOGLEVEL_DEBUG); + + if ($order->kBestellung > 0) { + Mollie::JTLMollie()->doLog("Hook 131: Finalisierung erfolgreich, kBestellung: {$order->kBestellung} / {$order->cBestellNr}", $logData, LOGLEVEL_DEBUG); + $oZahlungSession->nBezahlt = 1; + $oZahlungSession->dZeitBezahlt = 'now()'; + $oZahlungSession->kBestellung = (int)$order->kBestellung; + $oZahlungSession->dNotify = strtotime($oZahlungSession->dNotify > 0) ? $oZahlungSession->dNotify : date("Y-m-d H:i:s"); + Shop::DB()->update('tzahlungsession', 'cZahlungsID', $oZahlungSession->cZahlungsID, $oZahlungSession); + Mollie::handleOrder($mOrder, $order->kBestellung); + return Mollie::getOrderCompletedRedirect($order->kBestellung, true); + } else { + Mollie::JTLMollie()->doLog("Hook 131: Fionalisierung fehlgeschlagen
" . print_r($order, 1) . "
", $logData, LOGLEVEL_ERROR); + } + } else { + Mollie::JTLMollie()->doLog("Hook 131: Invalid PaymentStatus: {$payment->status} for {$payment->id} ", $logData, LOGLEVEL_ERROR); + header('Location: ' . Shop::getURL() . '/bestellvorgang.php?editZahlungsart=1&mollieStatus=' . $payment->status); + exit(); + } + + } else { + Mollie::JTLMollie()->doLog("Hook 131: Invalid OrderStatus: {$mOrder->status} for {$mOrder->id} ", $logData, LOGLEVEL_ERROR); + header('Location: ' . Shop::getURL() . '/bestellvorgang.php?editZahlungsart=1&mollieStatus=' . $mOrder->status); + exit(); + } + } else { + Mollie::JTLMollie()->doLog("Hook 131: Could not get Order for {$oZahlungSession->cNotifyID}", $logData, LOGLEVEL_ERROR); + header('Location: ' . Shop::getURL() . '/bestellvorgang.php?editZahlungsart=1'); + exit(); + } + } else { + Mollie::JTLMollie()->doLog("Hook 131: already finalized => redirect / kBestellung:{$oZahlungSession->kBestellung} && cNotifyID:{$oZahlungSession->cNotifyID}", $logData, LOGLEVEL_NOTICE); + } + return Mollie::getOrderCompletedRedirect((int)$oZahlungSession->kBestellung, true); + } + } + ob_end_flush(); +} catch (Exception $e) { + Helper::logExc($e); +} + + diff --git a/version/107/frontend/140_smarty.php b/version/107/frontend/140_smarty.php new file mode 100644 index 0000000..0213117 --- /dev/null +++ b/version/107/frontend/140_smarty.php @@ -0,0 +1,71 @@ +oPluginSprachvariableAssoc_arr['error_' . $status]; + pq('#fieldset-payment')->prepend('
' . $text . '
'); + } + + $applePayId = "kPlugin_".Helper::oPlugin()->kPlugin."_mollieapplepay"; +pq('body')->append(<< +// +HTML +); + + switch (Helper::getSetting('load_styles')) { + case 'Y': + $selector = '#fieldset-payment [id*="_mollie"]'; + $border = ""; + break; + case 'A': + $selector = '#fieldset-payment'; + $border = "border-bottom: 1px solid #ccc;"; + break; + case 'N': + default: + return; + } + + $lh = "30px"; + if (Helper::getSetting('paymentmethod_sync') === 'size2x') { + $lh = "40px"; + } + + pq('head')->append( + << + /* MOLLIE CHECKOUT STYLES*/ + #fieldset-payment .form-group > div:hover, #checkout-shipping-payment .form-group > div:hover { + background-color: #eee; + color: black; + } + + {$selector} label > span { + line-height: {$lh}; + } + {$selector} label { + {$border} + } + {$selector} label img { + float: right; + } + +HTML + ); +} catch (Exception $e) { + Helper::logExc($e); +} diff --git a/version/107/frontend/144_notify.php b/version/107/frontend/144_notify.php new file mode 100644 index 0000000..d6c1c22 --- /dev/null +++ b/version/107/frontend/144_notify.php @@ -0,0 +1,63 @@ + Update Payment, stop skript + * - ELSE weiter mit der notify.php + */ + + +use ws_mollie\Helper; +use ws_mollie\Mollie; + +try { + + require_once __DIR__ . '/../class/Helper.php'; + + Helper::init(); + + require_once __DIR__ . '/../paymentmethod/JTLMollie.php'; + + $orderId = array_key_exists('id', $_REQUEST) ? $_REQUEST['id'] : false; + if (!$orderId) { + // NOT A MOLLIE NOTIFICATION! + return; + } + $sh = array_key_exists('sh', $_REQUEST) ? $_REQUEST['sh'] : false; + if (!$sh) { + // NO SESSION HASH GIVEN! + return; + } + + $logData = '$' . $orderId; + + if ($oZahlungSession = JTLMollie::getZahlungSession(md5(trim($sh, '_')))) { + + if(trim($oZahlungSession->cNotifyID) === ''){ + $oZahlungSession->cNotifyID = $orderId; + Shop::DB()->update('tzahlungsession', 'cZahlungsID', $oZahlungSession->cZahlungsID, $oZahlungSession); + } + + if ((int)$oZahlungSession->kBestellung <= 0) { + // Bestellung noch nicht abgeschlossen, weiter mit standard + Mollie::JTLMollie()->doLog("Hook 144: orderId open, finalize with shop standard: {$orderId} / {$oZahlungSession->cZahlungsID}", $logData, LOGLEVEL_NOTICE); + return; + } + + if (trim($oZahlungSession->cNotifyID) === trim($orderId)) { + $logData = '$' . $oZahlungSession->cNotifyID; + Mollie::JTLMollie()->doLog("Hook 144: order finalized already => handleNotification", $logData, LOGLEVEL_NOTICE); + // Bestellung bereits finalisiert => evtl. Statusänderung + $oOrder = JTLMollie::API()->orders->get($orderId, ['embed' => 'payments']); + Mollie::handleOrder($oOrder, (int)$oZahlungSession->kBestellung); + exit(); + } else { + Mollie::JTLMollie()->doLog("Hook 144: orderId invalid: {$orderId} / {$oZahlungSession->cNotifyID}", $logData, LOGLEVEL_ERROR); + } + } else { + Mollie::JTLMollie()->doLog("Hook 144: couldn't load ZahlungSession => {$sh}", $logData, LOGLEVEL_DEBUG); + } + +} catch (Exception $e) { + Helper::logExc($e); +} diff --git a/version/107/frontend/181_sync.php b/version/107/frontend/181_sync.php new file mode 100644 index 0000000..86c610c --- /dev/null +++ b/version/107/frontend/181_sync.php @@ -0,0 +1,43 @@ +kBestellung && $payment = Payment::getPayment($oBestellung->kBestellung)) { + $logData = '#' . $payment->kBestellung . '$' . $payment->kID . "§" . $oBestellung->cBestellNr; + Mollie::JTLMollie()->doLog("WAWI Abgleich: HOOK_BESTELLUNGEN_XML_BESTELLSTATUS
" . print_r($args_arr, 1) . "
", $logData, LOGLEVEL_DEBUG); + try { + $order = JTLMollie::API()->orders->get($payment->kID); + //$order->orderNumber = $oBestellung->cBestellNr; + Mollie::handleOrder($order, $oBestellung->kBestellung); + if ($order->isCreated() || $order->isPaid() || $order->isAuthorized() || $order->isShipping() || $order->isPending()) { + $options = Mollie::getShipmentOptions($order, $oBestellung->kBestellung, $status); + if ($options && array_key_exists('lines', $options) && is_array($options['lines'])) { + require_once __DIR__ . '/../paymentmethod/JTLMollie.php'; + $shipment = JTLMollie::API()->shipments->createFor($order, $options); + Mollie::JTLMollie()->doLog('Shipment created
' . print_r(['options' => $options, 'shipment' => $shipment], 1) . '
', $logData, LOGLEVEL_NOTICE); + } elseif ((int)$status !== BESTELLUNG_STATUS_BEZAHLT) { + Mollie::JTLMollie()->doLog('181_sync: options don\'t contain lines
' . print_r([$order, $options], 1) . '
', $logData, LOGLEVEL_ERROR); + } + } + } catch (Exception $e) { + Mollie::JTLMollie()->doLog('Fehler: ' . $e->getMessage() . '
' . print_r($e->getTrace(), 1) . '
', $logData, LOGLEVEL_ERROR); + } + } + + //} +} catch (Exception $e) { + Helper::logExc($e); +} diff --git a/version/107/frontend/img/trust_eng.png b/version/107/frontend/img/trust_eng.png new file mode 100644 index 0000000..3d01773 Binary files /dev/null and b/version/107/frontend/img/trust_eng.png differ diff --git a/version/107/frontend/img/trust_fre.png b/version/107/frontend/img/trust_fre.png new file mode 100644 index 0000000..ed1a2f6 Binary files /dev/null and b/version/107/frontend/img/trust_fre.png differ diff --git a/version/107/frontend/img/trust_ger.png b/version/107/frontend/img/trust_ger.png new file mode 100644 index 0000000..e42821b Binary files /dev/null and b/version/107/frontend/img/trust_ger.png differ diff --git a/version/107/paymentmethod/JTLMollie.php b/version/107/paymentmethod/JTLMollie.php new file mode 100644 index 0000000..0e033bb --- /dev/null +++ b/version/107/paymentmethod/JTLMollie.php @@ -0,0 +1,756 @@ + (int)$order->kBestellung, + 'cZahlungsanbieter' => empty($order->cZahlungsartName) ? $this->name : $order->cZahlungsartName, + 'fBetrag' => 0, + 'fZahlungsgebuehr' => 0, + 'cISO' => array_key_exists('Waehrung', $_SESSION) ? $_SESSION['Waehrung']->cISO : $payment->cISO, + 'cEmpfaenger' => '', + 'cZahler' => '', + 'dZeit' => 'now()', + 'cHinweis' => '', + 'cAbgeholt' => 'N' + ], (array)$payment); + + $logData = '#' . $order->kBestellung; + + if (isset($model->kZahlungseingang) && $model->kZahlungseingang > 0) { + Mollie::JTLMollie()->doLog('JTLMollie::addIncomingPayment (update)
' . print_r([$model, $payment], 1) . '
', $logData); + Shop::DB()->update('tzahlungseingang', 'kZahlungseingang', $model->kZahlungseingang, $model); + } else { + Mollie::JTLMollie()->doLog('JTLMollie::addIncomingPayment (create)
' . print_r([$model, $payment], 1) . '
', $logData); + Shop::DB()->insert('tzahlungseingang', $model); + } + + return $this; + } + + /** + * @param string $msg + * @param null $data + * @param int $level + * @return $this + */ + public function doLog($msg, $data = null, $level = LOGLEVEL_NOTICE) + { + ZahlungsLog::add($this->moduleID, "[" . microtime(true) . " - " . $_SERVER['PHP_SELF'] . "] " . $msg, $data, $level); + return $this; + } + + /** + * @param Bestellung $order + * @return PaymentMethod|void + */ + public function setOrderStatusToPaid($order) + { + // If paid already, do nothing + if ((int)$order->cStatus >= BESTELLUNG_STATUS_BEZAHLT) { + return $this; + } + parent::setOrderStatusToPaid($order); + } + + /** + * Prepares everything so that the Customer can start the Payment Process. + * Tells Template Engine. + * + * @param Bestellung $order + * @return bool|string + */ + public function preparePaymentProcess($order) + { + $logData = '#' . $order->kBestellung . "§" . $order->cBestellNr; + + $payable = (float)$order->fGesamtsumme > 0; + + if ($payable) { + $this->updateMollieCustomer($_SESSION['Kunde']); + } + + try { + + if ($order->kBestellung) { + if ($payable) { + $payment = Payment::getPayment($order->kBestellung); + $oMolliePayment = self::API()->orders->get($payment->kID, ['embed' => 'payments']); + Mollie::handleOrder($oMolliePayment, $order->kBestellung); + if ($payment && in_array($payment->cStatus, [OrderStatus::STATUS_CREATED]) && $payment->cCheckoutURL) { + $logData .= '$' . $payment->kID; + if (!$this->duringCheckout) { + Session::getInstance()->cleanUp(); + } + header('Location: ' . $payment->cCheckoutURL); + echo "redirect to payment ..."; + exit(); + } + } else { + return Mollie::getOrderCompletedRedirect($order->kBestellung, true); + } + } + } catch (Exception $e) { + $this->doLog("Get Payment Error: " . $e->getMessage() . ". Create new ORDER...", $logData, LOGLEVEL_ERROR); + } + + + try { + + if (!$payable) { + $bestellung = finalisiereBestellung(); + if ($bestellung && (int)$bestellung->kBestellung > 0) { + return Mollie::getOrderCompletedRedirect($bestellung->kBestellung, true); + } + header('Location: ' . Shop::getURL() . '/bestellvorgang.php?editZahlungsart=1&mollieStatus=failed'); + echo "redirect..."; + exit(); + } + + if (!array_key_exists('oMolliePayment', $_SESSION) || !($_SESSION['oMolliePayment'] instanceof \Mollie\Api\Resources\Order)) { + $hash = $this->generateHash($order); + //$_SESSION['cMollieHash'] = $hash; + $orderData = $this->getOrderData($order, $hash); + $oMolliePayment = self::API()->orders->create($orderData); + $this->updateHash($hash, $oMolliePayment->id); + $_SESSION['oMolliePayment'] = $oMolliePayment; + } else { + $oMolliePayment = $_SESSION['oMolliePayment']; + } + $logData .= '$' . $oMolliePayment->id; + $this->doLog('Mollie Create Payment Redirect: ' . $oMolliePayment->getCheckoutUrl() . "
" . print_r($oMolliePayment, 1) . "
", $logData, LOGLEVEL_DEBUG); + Payment::updateFromPayment($oMolliePayment, $order->kBestellung, md5(trim($hash, '_'))); + Shop::Smarty()->assign('oMolliePayment', $oMolliePayment); + + if (!$this->duringCheckout) { + Session::getInstance()->cleanUp(); + } + + if (!$oMolliePayment->getCheckoutUrl() && ($oMolliePayment->isAuthorized() || $oMolliePayment->isPaid())) { + header('Location: ' . $oMolliePayment->redirectUrl); + echo "redirect to order ..."; + } else { + header('Location: ' . $oMolliePayment->getCheckoutUrl()); + echo "redirect to payment ..."; + } + unset($_SESSION['oMolliePayment']); + exit(); + } catch (ApiException $e) { + $this->doLog("Create Payment Error: " . $e->getMessage() . '
' . print_r($orderData, 1) . '
', $logData, LOGLEVEL_ERROR); + //header('Location: ' . Shop::getURL() . '/bestellvorgang.php?editZahlungsart=1&mollieStatus=failed'); + echo "redirect..."; + exit(); + } + } + + /** + * @param $oKunde Kunde + */ + public function updateMollieCustomer($oKunde) + { + if (!$oKunde->kKunde || (int)$oKunde->nRegistriert <= 0) { + return; + } + try { + $customerId = Shop::DB()->select('xplugin_ws_mollie_kunde', 'kKunde', (int)$oKunde->kKunde); + $api = JTLMollie::API(); + /** @var Customer $customer */ + $customer = new stdClass(); + if ($customerId && isset($customerId->customerId)) { + try { + $customer = $api->customers->get($customerId->customerId); + } catch (Exception $e) { + Helper::logExc($e); + } + } + + $customer->name = utf8_encode(trim($oKunde->cVorname . ' ' . $oKunde->cNachname)); + $customer->email = utf8_encode($oKunde->cMail); + $customer->locale = self::getLocale($_SESSION['cISOSprache'], $_SESSION['Kunde']->cLand); + $customer->metadata = [ + 'kKunde' => $oKunde->kKunde, + 'kKundengruppe' => $oKunde->kKundengruppe, + 'cKundenNr' => $oKunde->cKundenNr, + ]; + + if ($customer instanceof Customer) { + $customer->update(); + } else { + if ($customer = $api->customers->create((array)$customer)) { + Shop::DB()->insert('xplugin_ws_mollie_kunde', (object)[ + 'kKunde' => $oKunde->kKunde, + 'customerId' => $customer->id, + ]); + } + } + + } catch (Exception $e) { + Helper::logExc($e); + } + } + + /** + * @return MollieApiClient + * @throws ApiException + * @throws IncompatiblePlatform + */ + public static function API() + { + Helper::init(); + if (self::$_mollie === null) { + self::$_mollie = new MollieApiClient(new Client([ + \GuzzleHttp\RequestOptions::VERIFY => \Composer\CaBundle\CaBundle::getBundledCaBundlePath(), + \GuzzleHttp\RequestOptions::TIMEOUT => 60, + ])); + self::$_mollie->setApiKey(Helper::getSetting('api_key')); + self::$_mollie->addVersionString("JTL-Shop/" . JTL_VERSION . '.' . JTL_MINOR_VERSION); + self::$_mollie->addVersionString("ws_mollie/" . Helper::oPlugin()->nVersion); + } + return self::$_mollie; + } + + public static function getLocale($cISOSprache, $country = null) + { + switch ($cISOSprache) { + case "ger": + if ($country === "AT") { + return "de_AT"; + } + if ($country === "CH") { + return "de_CH"; + } + return "de_DE"; + case "fre": + if ($country === "BE") { + return "fr_BE"; + } + return "fr_FR"; + case "dut": + if ($country === "BE") { + return "nl_BE"; + } + return "nl_NL"; + case "spa": + return "es_ES"; + case "ita": + return "it_IT"; + case "pol": + return "pl_PL"; + case "hun": + return "hu_HU"; + case "por": + return "pt_PT"; + case "nor": + return "nb_NO"; + case "swe": + return "sv_SE"; + case "fin": + return "fi_FI"; + case "dan": + return "da_DK"; + case "ice": + return "is_IS"; + default: + return "en_US"; + } + } + + /** + * @param Bestellung $order + * @param $hash + * @return array + */ + protected function getOrderData(Bestellung $order, $hash) + { + $locale = self::getLocale($_SESSION['cISOSprache'], $_SESSION['Kunde']->cLand); + + $_currencyFactor = (float)$order->Waehrung->fFaktor; + + $data = [ + 'locale' => $locale ?: 'de_DE', + 'amount' => (object)[ + 'currency' => $order->Waehrung->cISO, + //'value' => number_format($order->fGesamtsummeKundenwaehrung, 2, '.', ''), + // runden auf 5 Rappen berücksichtigt + 'value' => number_format($this->optionaleRundung($order->fGesamtsumme * $_currencyFactor), 2, '.', ''), + ], + 'orderNumber' => utf8_encode($order->cBestellNr), + 'lines' => [], + 'billingAddress' => new stdClass(), + 'metadata' => ['originalOrderNumber' => utf8_encode($order->cBestellNr)], + 'redirectUrl' => (int)$this->duringCheckout ? Shop::getURL() . '/bestellabschluss.php?mollie=' . md5(trim($hash, '_')) : $this->getReturnURL($order), + 'webhookUrl' => $this->getNotificationURL($hash), // . '&hash=' . md5(trim($hash, '_')), + ]; + + if (static::MOLLIE_METHOD !== '') { + $data['method'] = static::MOLLIE_METHOD; + } + + if (static::MOLLIE_METHOD === \Mollie\Api\Types\PaymentMethod::CREDITCARD && array_key_exists('mollieCardToken', $_SESSION)) { + $data['payment'] = new stdClass(); + $data['payment']->cardToken = trim($_SESSION['mollieCardToken']); + } + + if (($customerId = self::getMollieCustomerId((int)$_SESSION['Kunde']->kKunde)) !== false) { + if (!array_key_exists('payment', $data)) { + $data['payment'] = new stdClass(); + } + $data['payment']->customerId = $customerId; + } + + if ($organizationName = utf8_encode(trim($order->oRechnungsadresse->cFirma))) { + $data['billingAddress']->organizationName = $organizationName; + } + $data['billingAddress']->title = utf8_encode($order->oRechnungsadresse->cAnrede === 'm' ? Shop::Lang()->get('mr') : Shop::Lang()->get('mrs')); + $data['billingAddress']->givenName = utf8_encode($order->oRechnungsadresse->cVorname); + $data['billingAddress']->familyName = utf8_encode($order->oRechnungsadresse->cNachname); + $data['billingAddress']->email = utf8_encode($order->oRechnungsadresse->cMail); + $data['billingAddress']->streetAndNumber = utf8_encode($order->oRechnungsadresse->cStrasse . ' ' . $order->oRechnungsadresse->cHausnummer); + $data['billingAddress']->postalCode = utf8_encode($order->oRechnungsadresse->cPLZ); + $data['billingAddress']->city = utf8_encode($order->oRechnungsadresse->cOrt); + $data['billingAddress']->country = $order->oRechnungsadresse->cLand; + + if (array_key_exists('Kunde', $_SESSION)) { + if (isset($_SESSION['Kunde']->dGeburtstag) && preg_match('/^\d{4}-\d{2}-\d{2}$/', trim($_SESSION['Kunde']->dGeburtstag)) && trim($_SESSION['Kunde']->dGeburtstag) !== '0000-00-00') { + $data['consumerDateOfBirth'] = trim($_SESSION['Kunde']->dGeburtstag); + } + if (isset($_SESSION['Kunde']->cAdressZusatz) && trim($_SESSION['Kunde']->cAdressZusatz) !== '') { + $data['billingAddress']->streetAdditional = utf8_encode(trim($_SESSION['Kunde']->cAdressZusatz)); + } + } + + if ($order->Lieferadresse != null) { + $data['shippingAddress'] = new stdClass(); + if ($organizationName = utf8_encode(trim($order->Lieferadresse->cFirma))) { + $data['shippingAddress']->organizationName = $organizationName; + } + $data['shippingAddress']->title = utf8_encode($order->Lieferadresse->cAnrede === 'm' ? Shop::Lang()->get('mr') : Shop::Lang()->get('mrs')); + $data['shippingAddress']->givenName = utf8_encode($order->Lieferadresse->cVorname); + $data['shippingAddress']->familyName = utf8_encode($order->Lieferadresse->cNachname); + $data['shippingAddress']->email = utf8_encode($order->oRechnungsadresse->cMail); + $data['shippingAddress']->streetAndNumber = utf8_encode($order->Lieferadresse->cStrasse . ' ' . $order->Lieferadresse->cHausnummer); + $data['shippingAddress']->postalCode = utf8_encode($order->Lieferadresse->cPLZ); + $data['shippingAddress']->city = utf8_encode($order->Lieferadresse->cOrt); + $data['shippingAddress']->country = $order->Lieferadresse->cLand; + + if (array_key_exists('Lieferadresse', $_SESSION) && isset($_SESSION['Lieferadresse']->cAdressZusatz) && trim($_SESSION['Lieferadresse']->cAdressZusatz) !== '') { + $data['shippingAddress']->streetAdditional = utf8_encode(trim($_SESSION['Lieferadresse']->cAdressZusatz)); + } + } + + /** @var WarenkorbPos $oPosition */ + foreach ($order->Positionen as $oPosition) { + + $line = new stdClass(); + $line->name = utf8_encode($oPosition->cName); + + $_netto = round($oPosition->fPreis, 2); + $_vatRate = (float)$oPosition->fMwSt / 100; + $_amount = (float)$oPosition->nAnzahl; + + if (Helper::getSetting("supportQ") === 'Y') { + // Rationale Stückzahlen aktiviert + if ((int)$oPosition->nPosTyp === (int)C_WARENKORBPOS_TYP_ARTIKEL && $oPosition->Artikel->cTeilbar === 'Y' + && fmod($oPosition->nAnzahl, 1) !== 0.0) { + $_netto *= $_amount; + $_amount = 1; + $line->name .= sprintf(" (%.2f %s)", (float)$oPosition->nAnzahl, $oPosition->cEinheit); + } + } + + $unitPriceNetto = round(($_currencyFactor * $_netto), 2); + $unitPrice = round($unitPriceNetto * (1 + $_vatRate), 2); + $totalAmount = round($_amount * $unitPrice, 2); + $vatAmount = round($totalAmount - ($totalAmount / (1 + $_vatRate)), 2); + + $line->quantity = (int)$_amount; + $line->unitPrice = (object)[ + 'value' => number_format($unitPrice, 2, '.', ''), + 'currency' => $order->Waehrung->cISO, + ]; + $line->totalAmount = (object)[ + 'value' => number_format($totalAmount, 2, '.', ''), + 'currency' => $order->Waehrung->cISO, + ]; + $line->vatRate = "{$oPosition->fMwSt}"; + + $line->vatAmount = (object)[ + 'value' => number_format($vatAmount, 2, '.', ''), + 'currency' => $order->Waehrung->cISO, + ]; + + switch ((int)$oPosition->nPosTyp) { + case (int)C_WARENKORBPOS_TYP_GRATISGESCHENK: + case (int)C_WARENKORBPOS_TYP_ARTIKEL: + $line->type = OrderLineType::TYPE_PHYSICAL; + $line->sku = utf8_encode($oPosition->cArtNr); + break; + case (int)C_WARENKORBPOS_TYP_VERSANDPOS: + $line->type = OrderLineType::TYPE_SHIPPING_FEE; + break; + case (int)C_WARENKORBPOS_TYP_VERPACKUNG: + case (int)C_WARENKORBPOS_TYP_VERSANDZUSCHLAG: + case (int)C_WARENKORBPOS_TYP_ZAHLUNGSART: + case (int)C_WARENKORBPOS_TYP_VERSAND_ARTIKELABHAENGIG: + case (int)C_WARENKORBPOS_TYP_TRUSTEDSHOPS: + $line->type = OrderLineType::TYPE_SURCHARGE; + break; + case (int)C_WARENKORBPOS_TYP_GUTSCHEIN: + case (int)C_WARENKORBPOS_TYP_KUPON: + case (int)C_WARENKORBPOS_TYP_NEUKUNDENKUPON: + $line->type = OrderLineType::TYPE_DISCOUNT; + break; + } + if (isset($line->type)) { + $data['lines'][] = $line; + } + } + + if ((int)$order->GuthabenNutzen === 1 && $order->fGuthaben < 0) { + $line = new stdClass(); + $line->type = OrderLineType::TYPE_STORE_CREDIT; + $line->name = 'Guthaben'; + $line->quantity = 1; + $line->unitPrice = (object)[ + 'value' => number_format($order->Waehrung->fFaktor * $order->fGuthaben, 2, '.', ''), + 'currency' => $order->Waehrung->cISO, + ]; + $line->unitPrice = (object)[ + 'value' => number_format($order->Waehrung->fFaktor * $order->fGuthaben, 2, '.', ''), + 'currency' => $order->Waehrung->cISO, + ]; + $line->totalAmount = (object)[ + 'value' => number_format($order->Waehrung->fFaktor * $order->fGuthaben, 2, '.', ''), + 'currency' => $order->Waehrung->cISO, + ]; + $line->vatRate = "0.00"; + $line->vatAmount = (object)[ + 'value' => number_format(0, 2, '.', ''), + 'currency' => $order->Waehrung->cISO, + ]; + $data['lines'][] = $line; + } + + // RUNDUNGSAUSGLEICH + $sum = .0; + foreach ($data['lines'] as $line) { + $sum += (float)$line->totalAmount->value; + } + if (abs($sum - (float)$data['amount']->value) > 0) { + $diff = (round((float)$data['amount']->value - $sum, 2)); + if ($diff != 0) { + $line = new stdClass(); + $line->type = $diff > 0 ? OrderLineType::TYPE_SURCHARGE : OrderLineType::TYPE_DISCOUNT; + $line->name = 'Rundungsausgleich'; + $line->quantity = 1; + $line->unitPrice = (object)[ + 'value' => number_format($diff, 2, '.', ''), + 'currency' => $order->Waehrung->cISO, + ]; + $line->unitPrice = (object)[ + 'value' => number_format($diff, 2, '.', ''), + 'currency' => $order->Waehrung->cISO, + ]; + $line->totalAmount = (object)[ + 'value' => number_format($diff, 2, '.', ''), + 'currency' => $order->Waehrung->cISO, + ]; + $line->vatRate = "0.00"; + $line->vatAmount = (object)[ + 'value' => number_format(0, 2, '.', ''), + 'currency' => $order->Waehrung->cISO, + ]; + $data['lines'][] = $line; + } + } + return $data; + } + + public function optionaleRundung($gesamtsumme) + { + $conf = Shop::getSettings([CONF_KAUFABWICKLUNG]); + if (isset($conf['kaufabwicklung']['bestellabschluss_runden5']) && $conf['kaufabwicklung']['bestellabschluss_runden5'] == 1) { + $waehrung = isset($_SESSION['Waehrung']) ? $_SESSION['Waehrung'] : null; + if ($waehrung === null || !isset($waehrung->kWaehrung)) { + $waehrung = Shop::DB()->select('twaehrung', 'cStandard', 'Y'); + } + $faktor = $waehrung->fFaktor; + $gesamtsumme *= $faktor; + + // simplification. see https://de.wikipedia.org/wiki/Rundung#Rappenrundung + $gesamtsumme = round($gesamtsumme * 20) / 20; + $gesamtsumme /= $faktor; + } + + return $gesamtsumme; + } + + public static function getMollieCustomerId($kKunde) + { + if ($row = Shop::DB()->select('xplugin_ws_mollie_kunde', 'kKunde', (int)$kKunde)) { + return $row->customerId; + } + return false; + } + + public function updateHash($hash, $orderID) + { + $hash = trim($hash, '_'); + $_upd = new stdClass(); + $_upd->cNotifyID = $orderID; + return Shop::DB()->update('tzahlungsession', 'cZahlungsID', $hash, $_upd); + } + + /** + * @param Bestellung $order + * @param string $hash + * @param array $args + */ + public function handleNotification($order, $hash, $args) + { + + $logData = '#' . $order->kBestellung . "§" . $order->cBestellNr; + $this->doLog('JTLMollie::handleNotification
' . print_r([$hash, $args], 1) . '
', $logData, LOGLEVEL_DEBUG); + + try { + + $oMolliePayment = self::API()->orders->get($args['id'], ['embed' => 'payments']); + Mollie::handleOrder($oMolliePayment, $order->kBestellung); + + } catch (Exception $e) { + $this->doLog('JTLMollie::handleNotification: ' . $e->getMessage(), $logData); + } + } + + /** + * @param Bestellung $order + * @param string $hash + * @param array $args + * + * @return true, if $order should be finalized + */ + public function finalizeOrder($order, $hash, $args) + { + $result = false; + try { + if ($oZahlungSession = self::getZahlungSession(md5($hash))) { + if ((int)$oZahlungSession->kBestellung <= 0) { + + $logData = '$' . $args['id']; + $GLOBALS['mollie_notify_lock'] = new \ws_mollie\ExclusiveLock('mollie_' . $args['id'], PFAD_ROOT . PFAD_COMPILEDIR); + if ($GLOBALS['mollie_notify_lock']->lock()) { + $this->doLog("JTLMollie::finalizeOrder::locked ({$args['id']})", $logData, LOGLEVEL_DEBUG); + } else { + $this->doLog("JTLMollie::finalizeOrder::locked failed ({$args['id']})", $logData, LOGLEVEL_ERROR); + } + + $oOrder = self::API()->orders->get($args['id'], ['embed' => 'payments']); + $result = in_array($oOrder->status, [OrderStatus::STATUS_PAID, OrderStatus::STATUS_AUTHORIZED, OrderStatus::STATUS_PENDING, OrderStatus::STATUS_COMPLETED]); + $this->doLog('JTLMollie::finalizeOrder (' . ($result ? 'true' : 'false') . ')
' . print_r([$hash, $args, $oOrder], 1) . '
', $logData, LOGLEVEL_DEBUG); + //Payment::updateFromPayment($oMolliePayment, $order->kBestellung); + } + } + } catch (Exception $e) { + $this->doLog('JTLMollie::finalizeOrder: ' . $e->getMessage(), "#" . $hash); + } + return $result; + } + + public static function getZahlungSession($hash) + { + return Shop::DB()->executeQueryPrepared("SELECT * FROM tzahlungsession WHERE MD5(cZahlungsID) = :cZahlungsID", [':cZahlungsID' => trim($hash, '_')], 1); + } + + /** + * @return bool + */ + public function canPayAgain() + { + return true; + } + + /** + * determines, if the payment method can be selected in the checkout process + * + * @return bool + */ + public function isSelectable() + { + /** @var Warenkorb $wk */ + $wk = $_SESSION['Warenkorb']; + if (Helper::getSetting("supportQ") !== 'Y') { + // Rationale Stückzahlen vorhanden? + foreach ($wk->PositionenArr as $oPosition) { + if ((int)$oPosition->nPosTyp === (int)C_WARENKORBPOS_TYP_ARTIKEL && $oPosition->Artikel && $oPosition->Artikel->cTeilbar === 'Y' + && fmod($oPosition->nAnzahl, 1) !== 0.0) { + return false; + } + } + } + + $locale = self::getLocale($_SESSION['cISOSprache'], $_SESSION['Kunde']->cLand); + if (static::MOLLIE_METHOD !== '') { + try { + $method = self::PossiblePaymentMethods(static::MOLLIE_METHOD, $locale, $_SESSION['Kunde']->cLand, $_SESSION['Waehrung']->cISO, $wk->gibGesamtsummeWaren(true) * $_SESSION['Waehrung']->fFaktor); + if ($method !== null) { + + if ((int)$this->duringCheckout === 1 && !static::ALLOW_PAYMENT_BEFORE_ORDER) { + $this->doLog(static::MOLLIE_METHOD . " cannot be used for payment before order."); + return false; + } + + $this->updatePaymentMethod($_SESSION['cISOSprache'], $method); + $this->cBild = $method->image->size2x; + return true; + } + return false; + } catch (Exception $e) { + $this->doLog('Method ' . static::MOLLIE_METHOD . ' not selectable:' . $e->getMessage()); + return false; + } + } else { + $this->doLog("Global mollie PaymentMethod cannot be used for payments directly."); + } + return false; + } + + /** + * @param $method + * @param $locale + * @param $billingCountry + * @param $currency + * @param $amount + * @return mixed|null + * @throws ApiException + * @throws IncompatiblePlatform + */ + protected static function PossiblePaymentMethods($method, $locale, $billingCountry, $currency, $amount) + { + $key = md5(serialize([$locale, $billingCountry, $amount, $currency])); + if (!array_key_exists($key, self::$_possiblePaymentMethods)) { + self::$_possiblePaymentMethods[$key] = self::API()->methods->allActive(['amount' => ['currency' => $currency, 'value' => number_format($amount, 2, '.', '')], 'billingCountry' => $_SESSION['Kunde']->cLand, 'locale' => $locale, 'includeWallets' => 'applepay', 'include' => 'pricing,issuers', 'resource' => 'orders']); + } + + if ($method !== null) { + foreach (self::$_possiblePaymentMethods[$key] as $m) { + if ($m->id === $method) { + return $m; + } + } + return null; + } + return self::$_possiblePaymentMethods[$key]; + } + + /** + * @param $cISOSprache + * @param $method + */ + protected function updatePaymentMethod($cISOSprache, $method) + { + if (Helper::getSetting('paymentmethod_sync') === 'N') { + return; + } + $size = Helper::getSetting('paymentmethod_sync'); + if ((!isset($this->cBild) || $this->cBild === '') && isset($method->image->$size)) { + Shop::DB()->executeQueryPrepared("UPDATE tzahlungsart SET cBild = :cBild WHERE cModulId = :cModulId", [':cBild' => $method->image->$size, ':cModulId' => $this->cModulId], 3); + } + if ($za = Shop::DB()->executeQueryPrepared('SELECT kZahlungsart FROM tzahlungsart WHERE cModulID = :cModulID', [':cModulID' => $this->moduleID], 1)) { + Shop::DB()->executeQueryPrepared("INSERT INTO tzahlungsartsprache (kZahlungsart, cISOSprache, cName, cGebuehrname, cHinweisText) VALUES (:kZahlungsart, :cISOSprache, :cName, :cGebuehrname, :cHinweisText) ON DUPLICATE KEY UPDATE cName = IF(cName = '',:cName1,cName), cHinweisTextShop = IF(cHinweisTextShop = '' || cHinweisTextShop IS NULL,:cHinweisTextShop,cHinweisTextShop);", [ + ':kZahlungsart' => (int)$za->kZahlungsart, + ':cISOSprache' => $cISOSprache, + ':cName' => utf8_decode($method->description), + ':cGebuehrname' => '', + ':cHinweisText' => '', + ':cHinweisTextShop' => utf8_decode($method->description), + 'cName1' => $method->description, + ], 3); + } + } + + /** + * @param array $args_arr + * @return bool + */ + public function isValidIntern($args_arr = []) + { + if (Helper::getSetting("api_key")) { + return true; + } + $this->doLog("isValdid failed: init failed or no API Key given. Try clear the Cache."); + return false; + } +} diff --git a/version/107/paymentmethod/JTLMollieApplePay.php b/version/107/paymentmethod/JTLMollieApplePay.php new file mode 100644 index 0000000..ecf20a8 --- /dev/null +++ b/version/107/paymentmethod/JTLMollieApplePay.php @@ -0,0 +1,8 @@ +assign('profileId',$profileId) + ->assign('locale', self::getLocale($_SESSION['cISOSprache'], $_SESSION['Kunde']->cLand)) + ->assign('testmode', strpos(trim(Helper::getSetting('api_key')), 'test_') === 0) + ->assign('mollieLang', Helper::oPlugin()->oPluginSprachvariableAssoc_arr) + ->assign('trustBadge', Helper::getSetting('loadTrust') === 'Y' ? Helper::oPlugin()->cFrontendPfadURLSSL . 'img/trust_' . $_SESSION['cISOSprache'] . '.png' : false); + + return false; + } + + +} diff --git a/version/107/paymentmethod/JTLMollieDirectDebit.php b/version/107/paymentmethod/JTLMollieDirectDebit.php new file mode 100644 index 0000000..ce0441d --- /dev/null +++ b/version/107/paymentmethod/JTLMollieDirectDebit.php @@ -0,0 +1,8 @@ + + {$oMollieException->getMessage()} + +{/if} \ No newline at end of file diff --git a/version/107/paymentmethod/tpl/mollieComponents.tpl b/version/107/paymentmethod/tpl/mollieComponents.tpl new file mode 100644 index 0000000..9ad70bc --- /dev/null +++ b/version/107/paymentmethod/tpl/mollieComponents.tpl @@ -0,0 +1,101 @@ +

{$mollieLang.cctitle}

+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+ + +
+ +
+ {if $trustBadge} +
+ PCI-DSS SAQ-A compliant +
+ {/if} +
+ + + + + \ No newline at end of file diff --git a/version/107/sql/107.sql b/version/107/sql/107.sql new file mode 100644 index 0000000..debecf2 --- /dev/null +++ b/version/107/sql/107.sql @@ -0,0 +1,4 @@ +CREATE TABLE `xplugin_ws_mollie_kunde` ( + `kKunde` int NOT NULL PRIMARY KEY, + `customerId` varchar(32) NOT NULL +); \ No newline at end of file