Benjamin Roth authored on06/11/2024 17:16:57
Showing7 changed files
... ...
@@ -23,6 +23,8 @@
23 23
         "symfony/config": "^5.4 || ^6.4",
24 24
         "symfony/dependency-injection": "^5.4 || ^6.4",
25 25
         "symfony/http-kernel": "^5.4 || ^6.4",
26
+        "symfony/serializer": "^5.4 || ^6.4",
27
+        "symfony/property-access": "^5.4 || ^6.4",
26 28
         "vonrotenberg/shopware-api-bundle": "dev-master"
27 29
     },
28 30
     "require-dev": {
... ...
@@ -69,6 +71,10 @@
69 71
         "unit-tests": "@php vendor/bin/phpunit --colors=always"
70 72
     },
71 73
     "repositories": {
74
+        "shopware-repo": {
75
+            "type": "path",
76
+            "url": "C:\\Work\\PhpstormProjects\\vonRotenberg\\contao-shopware-api-bundle"
77
+        },
72 78
         "vonrotenberg": {
73 79
             "type": "composer",
74 80
             "url": "https://satis.esales-media.de"
... ...
@@ -7,3 +7,9 @@ services:
7 7
     vonRotenberg\WmfgoCevisioBundle\:
8 8
         resource: ../src
9 9
         exclude: ../src/{VonrotenbergWmfgoCevisioBundle.php,ContaoManager,Entity,Migrations,Model,Resources,Tests,Widget}
10
+
11
+    Symfony\Component\Finder\Finder:
12
+        shared: false
13
+
14
+    vonRotenberg\WmfgoCevisioBundle\Cron\ShopwareImportProductsJob:
15
+        public: true
10 16
new file mode 100644
... ...
@@ -0,0 +1,61 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of vonRotenberg WMFGO Cevisio Bundle.
7
+ *
8
+ * (c) vonRotenberg
9
+ *
10
+ * @license proprietary
11
+ */
12
+
13
+namespace vonRotenberg\WmfgoCevisioBundle\Command;
14
+
15
+use Contao\CoreBundle\Framework\ContaoFramework;
16
+use Contao\System;
17
+use Symfony\Component\Console\Command\Command;
18
+use Symfony\Component\Console\Input\InputInterface;
19
+use Symfony\Component\Console\Output\OutputInterface;
20
+use Symfony\Component\Console\Style\SymfonyStyle;
21
+use vonRotenberg\WmfgoCevisioBundle\Cron\ShopwareImportProductsJob;
22
+
23
+class ShopwareImportProductsCommand extends Command
24
+{
25
+    protected static $defaultName = 'shopware:import-products';
26
+
27
+    /**
28
+     * @var ContaoFramework
29
+     */
30
+    private $framework;
31
+
32
+    public function __construct(ContaoFramework $framework)
33
+    {
34
+        $this->framework = $framework;
35
+
36
+        parent::__construct();
37
+    }
38
+
39
+    protected function configure(): void
40
+    {
41
+        $this
42
+            ->setName(self::$defaultName)
43
+            ->setDescription('Import products in Shopware instance')
44
+        ;
45
+    }
46
+
47
+    protected function execute(InputInterface $input, OutputInterface $output): int
48
+    {
49
+        $this->framework->initialize();
50
+
51
+        $io = new SymfonyStyle($input, $output);
52
+        $io->title('Product import to Shopware');
53
+
54
+        /** @var ShopwareImportProductsJob $import */
55
+        $import = System::getContainer()->get(ShopwareImportProductsJob::class);
56
+
57
+        $import->import('cli', $io);
58
+
59
+        return 0;
60
+    }
61
+}
0 62
new file mode 100644
... ...
@@ -0,0 +1,135 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of vonRotenberg WMFGO Cevisio Bundle.
7
+ *
8
+ * (c) vonRotenberg
9
+ *
10
+ * @license proprietary
11
+ */
12
+
13
+namespace vonRotenberg\WmfgoCevisioBundle\Cron;
14
+
15
+use Contao\CoreBundle\Controller\AbstractController;
16
+use Contao\Date;
17
+use Contao\System;
18
+use Doctrine\DBAL\Connection;
19
+use Psr\Log\LoggerInterface;
20
+use Symfony\Component\Console\Helper\ProgressBar;
21
+use Symfony\Component\Console\Output\ConsoleOutput;
22
+use Symfony\Component\Console\Style\SymfonyStyle;
23
+use Symfony\Component\Finder\Finder;
24
+use Symfony\Component\Serializer\Encoder\CsvEncoder;
25
+use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
26
+use Symfony\Component\Serializer\Serializer;
27
+use Symfony\Component\Serializer\SerializerInterface;
28
+use vonRotenberg\ShopwareApiBundle\API\Shopware;
29
+use vonRotenberg\WmfgoCevisioBundle\Model\Import\ProductModel;
30
+
31
+class ShopwareImportProductsJob extends AbstractController
32
+{
33
+    /** @var LoggerInterface */
34
+    private $logger;
35
+
36
+    /** @var SerializerInterface */
37
+    private $serializer;
38
+
39
+    /** @var SerializerInterface */
40
+    private $shopware;
41
+
42
+    private $csvContext = [];
43
+
44
+    /** @var Finder */
45
+    private $finder;
46
+
47
+    /** @var Connection */
48
+    private $db;
49
+
50
+    /**
51
+     * Remote
52
+     * @var Connection
53
+     */
54
+    private $rdb;
55
+
56
+    public function __construct(Finder $finder, Shopware $shopware, Connection $db, LoggerInterface $logger)
57
+    {
58
+        $this->finder = $finder;
59
+        $this->db = $db;
60
+        $this->logger = $logger;
61
+        $this->shopware = $shopware;
62
+
63
+        $encoder      = [new CsvEncoder()];
64
+        $normalizer   = [new ObjectNormalizer()];
65
+        $this->serializer = new Serializer($normalizer,$encoder);
66
+
67
+        $this->csvContext = [
68
+            'csv_delimiter' => ';',
69
+            'csv_enclosure' => '"',
70
+        ];
71
+    }
72
+
73
+    public function import(string $scope, ?SymfonyStyle &$io = null): void
74
+    {
75
+        $intCounter = 0;
76
+        $isCli = false;
77
+        if (strtolower($scope) == 'cli' && $io !== null) {
78
+            $isCli = true;
79
+        }
80
+        $translator = System::getContainer()->get('translator');
81
+        $translator->setLocale('de');
82
+        $projectDir = System::getContainer()->getParameter('kernel.project_dir');
83
+        $srcDir = $projectDir.'/import/products';
84
+        if (!file_exists($srcDir)) {
85
+            mkdir($srcDir, 0777,true);
86
+        }
87
+
88
+        $Today = new Date();
89
+
90
+        $importFiles = $this->finder->files()->in($srcDir)->name('*.csv');
91
+
92
+        if (!$importFiles->count())
93
+        {
94
+            return;
95
+        }
96
+
97
+        foreach ($importFiles as $importFile) {
98
+            $data = $this->serializer->decode($importFile->getContents(), 'csv',$this->csvContext);
99
+            if ($isCli) $io->progressStart(count($data));
100
+            foreach ($data as $row) {
101
+                /** @var ProductModel $Product */
102
+                $Product = $this->serializer->denormalize($row,ProductModel::class);
103
+
104
+                $arrData = [
105
+                    'taxId' => '018e65c0485071508949c072f8dc18bd',
106
+                    'ean' => $Product->getEan(),
107
+                    'price' => [
108
+                        [
109
+                            'currencyId' => 'b7d2554b0ce847cd82f3ac9bd1c0dfca',
110
+                            'gross' => $Product->getPreis(),
111
+                            'net' => $Product->getPreis()/119*100,
112
+                            'linked' => true
113
+                        ]
114
+                    ],
115
+                    'stock' => 9999999,
116
+                    'name' => 'vrImport__'.$Product->getName(),
117
+                    'customFields' => [
118
+                        'custom_wine_attributes_jahrgang' => $Product->getJahrgang()
119
+                    ]
120
+                ];
121
+
122
+                if (!$this->shopware->addOrUpdateProductBySku($Product->getSku(), $arrData))
123
+                {
124
+                    if ($isCli) $io->error('Could not update');
125
+                }
126
+
127
+                if ($isCli)
128
+                {
129
+                    $io->progressAdvance();
130
+                }
131
+            }
132
+            if ($isCli) $io->progressFinish();
133
+        }
134
+    }
135
+}
0 136
new file mode 100644
... ...
@@ -0,0 +1,42 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of vonRotenberg Shopware API Bundle.
7
+ *
8
+ * (c) vonRotenberg
9
+ *
10
+ * @license proprietary
11
+ */
12
+
13
+namespace vonRotenberg\WmfgoCevisioBundle\DependencyInjection;
14
+
15
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
16
+use Symfony\Component\Config\Definition\ConfigurationInterface;
17
+
18
+class Configuration implements ConfigurationInterface
19
+{
20
+    public function getConfigTreeBuilder(): TreeBuilder
21
+    {
22
+        $treeBuilder = new TreeBuilder('vonrotenberg_wmfgo_cevisio');
23
+        $treeBuilder
24
+            ->getRootNode()
25
+            ->children()
26
+                ->arrayNode('mappings')
27
+                    ->addDefaultsIfNotSet()
28
+                    ->children()
29
+                        ->arrayNode('properties')
30
+                            ->info('Shopware property mappings')
31
+                            ->defaultValue('')
32
+                            ->arrayPrototype()
33
+                            ->children()
34
+                        ->end()
35
+                    ->end()
36
+                ->end()
37
+            ->end()
38
+        ;
39
+
40
+        return $treeBuilder;
41
+    }
42
+}
... ...
@@ -16,11 +16,19 @@ use Symfony\Component\Config\FileLocator;
16 16
 use Symfony\Component\DependencyInjection\ContainerBuilder;
17 17
 use Symfony\Component\DependencyInjection\Extension\Extension;
18 18
 use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
19
+use vonRotenberg\ShopwareApiBundle\DependencyInjection\Configuration;
19 20
 
20 21
 class VonrotenbergWmfgoCevisioExtension extends Extension
21 22
 {
22 23
     public function load(array $configs, ContainerBuilder $container): void
23 24
     {
25
+        $config = $this->processConfiguration(new Configuration(), $configs);
26
+
27
+        foreach($config['mappings'] as $key=>$val)
28
+        {
29
+            $container->setParameter('vonrotenberg_wmfgo_cevisio.mappings.'.$key,$val);
30
+        }
31
+
24 32
         $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../../config'));
25 33
         $loader->load('services.yml');
26 34
     }
27 35
new file mode 100644
... ...
@@ -0,0 +1,67 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of Affentaler customizations for Contao.
7
+ *
8
+ * (c) Benjamin Roth
9
+ *
10
+ * @license commercial
11
+ */
12
+
13
+namespace vonRotenberg\WmfgoCevisioBundle\Model\Import;
14
+
15
+class ProductModel
16
+{
17
+    /**
18
+     * @var array
19
+     */
20
+    private array $arrData;
21
+
22
+    public function __get($name)
23
+    {
24
+        return $this->get($name);
25
+    }
26
+
27
+    public function __set($name, $value)
28
+    {
29
+        $this->set($name,$value);
30
+    }
31
+
32
+
33
+    public function __call($name, $arguments)
34
+    {
35
+        if (strncmp($name, 'get', 3) === 0)
36
+        {
37
+            $name = lcfirst(substr($name, 3));
38
+
39
+            return $this->get($name);
40
+        } else if (strncmp($name, 'set', 3) === 0)
41
+        {
42
+            $name = lcfirst(substr($name, 3));
43
+
44
+            $this->set($name,$arguments[0]);
45
+        }
46
+    }
47
+
48
+    public function get(string $name)
49
+    {
50
+        if (isset($this->arrData[$name]))
51
+        {
52
+            return $this->arrData[$name];
53
+        }
54
+
55
+        return null;
56
+    }
57
+
58
+    public function set(string $name, $value): void
59
+    {
60
+        $this->arrData[$name] = $value;
61
+    }
62
+
63
+    public function getData(): ?array
64
+    {
65
+        return $this->arrData;
66
+    }
67
+}