Benjamin Roth authored on11/11/2024 10:47:55
Showing1 changed files
... ...
@@ -110,14 +110,14 @@ class ShopwareImportProductsJob extends AbstractController
110 110
                     'productNumber' => $Product->getSku(),
111 111
                     'taxId' => '018e65c0485071508949c072f8dc18bd',
112 112
                     'stock' => 999999,
113
-                    'name' => 'vrImport2__'.$Product->getName(),
114
-                    'active' => (bool) $Product->getPublished(),
113
+                    'name' => $Product->getName(),
115 114
                     'isCloseout' => true,
116 115
                     'purchaseUnit' => (float) $Product->getBaseprice(),
117 116
                     'referenceUnit' => 1,
118 117
                     'unitId' => $this->mappings->getUnitIdByName('Liter')
119 118
                 ];
120 119
 
120
+                if ($Product->getPublished() == '1' || $Product->getPublished() == '0') $arrData['active'] = (bool) $Product->getPublished() ;
121 121
                 if ($Product->getEan()) $arrData['ean'] = $Product->getEan();
122 122
                 if ($Product->getShipping_weight()) $arrData['weight'] = $Product->getShipping_weight();
123 123
                 if ($Product->getBesonderheit()) $arrData['description'] = $Product->getBesonderheit();
... ...
@@ -261,29 +261,35 @@ class ShopwareImportProductsJob extends AbstractController
261 261
                     $arrData['properties'] = $arrProperties;
262 262
                 }
263 263
 
264
+                // Price handling
265
+                if (($price = $Product->getPreis())) {
266
+                    $arrPrice = [
267
+                        'currencyId' => $this->mappings->getCurrencyIdByName('Euro'),
268
+                        'gross' => $price,
269
+                        'net' => $price/119*100,
270
+                        'linked' => true
271
+                    ];
264 272
 
265
-/*
266
-                    'ean' => $Product->getEan(),
267
-                    'price' => [
268
-                        [
269
-                            'currencyId' => 'b7d2554b0ce847cd82f3ac9bd1c0dfca',
270
-                            'gross' => $Product->getPreis(),
271
-                            'net' => $Product->getPreis()/119*100,
273
+                    if (($listprice = $Product->getPreis_uvp())) {
274
+                        $arrPrice['listPrice'] = [
275
+                            'currencyId' => $this->mappings->getCurrencyIdByName('Euro'),
276
+                            'gross' => $listprice,
277
+                            'net' => $listprice/119*100,
272 278
                             'linked' => true
273
-                        ]
274
-                    ],
275
-                    'customFields' => [
276
-                        'custom_wine_attributes_jahrgang' => $Product->getJahrgang()
277
-                    ],
278
-                    'properties' => [
279
-                        [
280
-                            'id' => $this->mappings->getPropertyIdByNameAndGroup($Product->getLage(),'Einzellage'),
281
-                            'groupId' => $this->mappings->getPropertyGroupIdByName('Einzellage'),
282
-                            'name' => $Product->getLage()
283
-                        ]
284
-                    ]
285
-                ];
286
-*/
279
+                        ];
280
+                    } else {
281
+                        $arrPrice['listPrice'] = [
282
+                            'currencyId' => $this->mappings->getCurrencyIdByName('Euro'),
283
+                            'gross' => 0,
284
+                            'net' => 0,
285
+                            'linked' => true
286
+                        ];
287
+                    }
288
+
289
+                    $arrData['price'] = [$arrPrice];
290
+                }
291
+
292
+
287 293
                 if (!$this->shopware->addOrUpdateProductBySku($Product->getSku(), $arrData))
288 294
                 {
289 295
                     if ($isCli) $io->error('Could not update/import Product ' . $Product->getSku());
... ...
@@ -294,7 +300,7 @@ class ShopwareImportProductsJob extends AbstractController
294 300
                 {
295 301
                     $io->progressAdvance();
296 302
                 }
297
-                return;
303
+//                return;
298 304
             }
299 305
             if ($isCli) $io->progressFinish();
300 306
         }
Benjamin Roth authored on07/11/2024 19:15:44
Showing1 changed files
... ...
@@ -175,16 +175,19 @@ class ShopwareImportProductsJob extends AbstractController
175 175
 
176 176
                 // Properties handling
177 177
                 $arrProperties = [];
178
+                $arrPropertyGroups = [];
178 179
 
179 180
                 if (
180 181
                     ($propertyVal = $Product->getLage())
181
-                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Einzellage')) !== null)
182
+                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Einzellage')) !== null
183
+                    && ($propertyId = $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true)) !== null)
182 184
                 {
183 185
                     $arrProperties[] = [
184
-                        'id' => $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true),
186
+                        'id' => $propertyId,
185 187
                         'groupId' => $propertyGroupId,
186 188
                         'name' => $propertyVal
187 189
                     ];
190
+                    $arrPropertyGroups[] = $propertyGroupId;
188 191
                 }
189 192
 
190 193
                 if (
... ...
@@ -197,54 +200,64 @@ class ShopwareImportProductsJob extends AbstractController
197 200
                         'groupId' => $propertyGroupId,
198 201
                         'name' => $propertyVal
199 202
                     ];
203
+                    $arrPropertyGroups[] = $propertyGroupId;
200 204
                 }
201 205
 
202 206
                 if (
203 207
                     ($propertyVal = $Product->getFarbe())
204
-                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Farbe')) !== null)
208
+                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Farbe')) !== null
209
+                    && ($propertyId = $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true)) !== null)
205 210
                 {
206 211
                     $arrProperties[] = [
207
-                        'id' => $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true),
212
+                        'id' => $propertyId,
208 213
                         'groupId' => $propertyGroupId,
209 214
                         'name' => $propertyVal
210 215
                     ];
216
+                    $arrPropertyGroups[] = $propertyGroupId;
211 217
                 }
212 218
 
213 219
                 if (
214 220
                     ($propertyVal = $Product->getGeschmack())
215
-                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Geschmack')) !== null)
221
+                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Geschmack')) !== null
222
+                    && ($propertyId = $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true)) !== null)
216 223
                 {
217 224
                     $arrProperties[] = [
218
-                        'id' => $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true),
225
+                        'id' => $propertyId,
219 226
                         'groupId' => $propertyGroupId,
220 227
                         'name' => $propertyVal
221 228
                     ];
229
+                    $arrPropertyGroups[] = $propertyGroupId;
222 230
                 }
223 231
 
224 232
                 if (
225 233
                     ($propertyVal = $Product->getRebsorte())
226
-                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Rebsorte')) !== null)
234
+                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Rebsorte')) !== null
235
+                    && ($propertyId = $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true)) !== null)
227 236
                 {
228 237
                     $arrProperties[] = [
229
-                        'id' => $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true),
238
+                        'id' => $propertyId,
230 239
                         'groupId' => $propertyGroupId,
231 240
                         'name' => $propertyVal
232 241
                     ];
242
+                    $arrPropertyGroups[] = $propertyGroupId;
233 243
                 }
234 244
 
235 245
                 if (
236 246
                     ($propertyVal = $Product->getWeinlinie())
237
-                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Weinlinie')) !== null)
247
+                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Weinlinie')) !== null
248
+                    && ($propertyId = $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true)) !== null)
238 249
                 {
239 250
                     $arrProperties[] = [
240
-                        'id' => $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true),
251
+                        'id' => $propertyId,
241 252
                         'groupId' => $propertyGroupId,
242 253
                         'name' => $propertyVal
243 254
                     ];
255
+                    $arrPropertyGroups[] = $propertyGroupId;
244 256
                 }
245 257
 
246 258
                 if (count($arrProperties))
247 259
                 {
260
+                    $this->shopware->truncatePropertiesForProductBySku($Product->getSku(),$arrPropertyGroups);
248 261
                     $arrData['properties'] = $arrProperties;
249 262
                 }
250 263
 
Benjamin Roth authored on07/11/2024 13:34:07
Showing1 changed files
... ...
@@ -26,6 +26,7 @@ use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
26 26
 use Symfony\Component\Serializer\Serializer;
27 27
 use Symfony\Component\Serializer\SerializerInterface;
28 28
 use vonRotenberg\ShopwareApiBundle\API\Shopware;
29
+use vonRotenberg\ShopwareApiBundle\Helper\ShopwareMappings;
29 30
 use vonRotenberg\WmfgoCevisioBundle\Model\Import\ProductModel;
30 31
 
31 32
 class ShopwareImportProductsJob extends AbstractController
... ...
@@ -36,9 +37,12 @@ class ShopwareImportProductsJob extends AbstractController
36 37
     /** @var SerializerInterface */
37 38
     private $serializer;
38 39
 
39
-    /** @var SerializerInterface */
40
+    /** @var Shopware */
40 41
     private $shopware;
41 42
 
43
+    /** @var ShopwareMappings */
44
+    private $mappings;
45
+
42 46
     private $csvContext = [];
43 47
 
44 48
     /** @var Finder */
... ...
@@ -53,12 +57,13 @@ class ShopwareImportProductsJob extends AbstractController
53 57
      */
54 58
     private $rdb;
55 59
 
56
-    public function __construct(Finder $finder, Shopware $shopware, Connection $db, LoggerInterface $logger)
60
+    public function __construct(Finder $finder, Shopware $shopware, ShopwareMappings $mappings, Connection $db, LoggerInterface $logger)
57 61
     {
58 62
         $this->finder = $finder;
59 63
         $this->db = $db;
60 64
         $this->logger = $logger;
61 65
         $this->shopware = $shopware;
66
+        $this->mappings = $mappings;
62 67
 
63 68
         $encoder      = [new CsvEncoder()];
64 69
         $normalizer   = [new ObjectNormalizer()];
... ...
@@ -102,7 +107,149 @@ class ShopwareImportProductsJob extends AbstractController
102 107
                 $Product = $this->serializer->denormalize($row,ProductModel::class);
103 108
 
104 109
                 $arrData = [
110
+                    'productNumber' => $Product->getSku(),
105 111
                     'taxId' => '018e65c0485071508949c072f8dc18bd',
112
+                    'stock' => 999999,
113
+                    'name' => 'vrImport2__'.$Product->getName(),
114
+                    'active' => (bool) $Product->getPublished(),
115
+                    'isCloseout' => true,
116
+                    'purchaseUnit' => (float) $Product->getBaseprice(),
117
+                    'referenceUnit' => 1,
118
+                    'unitId' => $this->mappings->getUnitIdByName('Liter')
119
+                ];
120
+
121
+                if ($Product->getEan()) $arrData['ean'] = $Product->getEan();
122
+                if ($Product->getShipping_weight()) $arrData['weight'] = $Product->getShipping_weight();
123
+                if ($Product->getBesonderheit()) $arrData['description'] = $Product->getBesonderheit();
124
+
125
+                // Custom fields handling
126
+                $arrCustomFields = [];
127
+                if (($customFieldVal = $Product->GetJahrgang())) {
128
+                    $arrCustomFields['custom_wine_attributes_jahrgang'] = $customFieldVal;
129
+                }
130
+
131
+                if (($customFieldVal = $Product->getAlkohol())) {
132
+                    $arrCustomFields['custom_wine_attributes_alkohol'] = $customFieldVal;
133
+                }
134
+
135
+                if (($customFieldVal = $Product->getSaeure())) {
136
+                    $arrCustomFields['custom_wine_attributes_saeure'] = $customFieldVal;
137
+                }
138
+
139
+                if (($customFieldVal = $Product->getrestzucker())) {
140
+                    $arrCustomFields['custom_wine_attributes_restzucker'] = $customFieldVal;
141
+                }
142
+
143
+                if (($customFieldVal = $Product->getZusatz())) {
144
+                    $arrCustomFields['custom_wine_attributes_zusatz'] = $customFieldVal;
145
+                }
146
+
147
+                if (($customFieldVal = $Product->getAllergene())) {
148
+                    $arrCustomFields['custom_wine_attributes_allergene'] = $customFieldVal;
149
+                }
150
+
151
+                if (($customFieldVal = $Product->getTrinktemperatur())) {
152
+                    $arrCustomFields['custom_wine_attributes_trinktemperatur'] = $customFieldVal;
153
+                }
154
+
155
+                if (($customFieldVal = $Product->getSpeiseempfehlung())) {
156
+                    $arrCustomFields['custom_wine_attributes_speiseempfehlung'] = $customFieldVal;
157
+                }
158
+
159
+                if (stripos($Product->getErzeuger(),'weinmanufaktur')) {
160
+                    $arrCustomFields['custom_wine_attributes_erzeuger'] = 'WMFGO';
161
+                }
162
+
163
+                if (stripos($Product->getAnbauregion(),'Baden')) {
164
+                    $arrCustomFields['custom_wine_attributes_anbauregion'] = 'Baden';
165
+                }
166
+
167
+                if (stripos($Product->getUrsprungsland(),'weinmanufaktur')) {
168
+                    $arrCustomFields['custom_wine_attributes_ursprungsland'] = 'DE';
169
+                }
170
+
171
+                if (count($arrCustomFields))
172
+                {
173
+                    $arrData['customFields'] = $arrCustomFields;
174
+                }
175
+
176
+                // Properties handling
177
+                $arrProperties = [];
178
+
179
+                if (
180
+                    ($propertyVal = $Product->getLage())
181
+                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Einzellage')) !== null)
182
+                {
183
+                    $arrProperties[] = [
184
+                        'id' => $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true),
185
+                        'groupId' => $propertyGroupId,
186
+                        'name' => $propertyVal
187
+                    ];
188
+                }
189
+
190
+                if (
191
+                    ($propertyVal = $Product->getQualitaet())
192
+                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Qualität')) !== null
193
+                    && ($propertyId = $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true)) !== null)
194
+                {
195
+                    $arrProperties[] = [
196
+                        'id' => $propertyId,
197
+                        'groupId' => $propertyGroupId,
198
+                        'name' => $propertyVal
199
+                    ];
200
+                }
201
+
202
+                if (
203
+                    ($propertyVal = $Product->getFarbe())
204
+                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Farbe')) !== null)
205
+                {
206
+                    $arrProperties[] = [
207
+                        'id' => $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true),
208
+                        'groupId' => $propertyGroupId,
209
+                        'name' => $propertyVal
210
+                    ];
211
+                }
212
+
213
+                if (
214
+                    ($propertyVal = $Product->getGeschmack())
215
+                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Geschmack')) !== null)
216
+                {
217
+                    $arrProperties[] = [
218
+                        'id' => $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true),
219
+                        'groupId' => $propertyGroupId,
220
+                        'name' => $propertyVal
221
+                    ];
222
+                }
223
+
224
+                if (
225
+                    ($propertyVal = $Product->getRebsorte())
226
+                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Rebsorte')) !== null)
227
+                {
228
+                    $arrProperties[] = [
229
+                        'id' => $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true),
230
+                        'groupId' => $propertyGroupId,
231
+                        'name' => $propertyVal
232
+                    ];
233
+                }
234
+
235
+                if (
236
+                    ($propertyVal = $Product->getWeinlinie())
237
+                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Weinlinie')) !== null)
238
+                {
239
+                    $arrProperties[] = [
240
+                        'id' => $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true),
241
+                        'groupId' => $propertyGroupId,
242
+                        'name' => $propertyVal
243
+                    ];
244
+                }
245
+
246
+                if (count($arrProperties))
247
+                {
248
+                    $arrData['properties'] = $arrProperties;
249
+                }
250
+
251
+
252
+/*
106 253
                     'ean' => $Product->getEan(),
107 254
                     'price' => [
108 255
                         [
... ...
@@ -112,22 +259,29 @@ class ShopwareImportProductsJob extends AbstractController
112 259
                             'linked' => true
113 260
                         ]
114 261
                     ],
115
-                    'stock' => 9999999,
116
-                    'name' => 'vrImport__'.$Product->getName(),
117 262
                     'customFields' => [
118 263
                         'custom_wine_attributes_jahrgang' => $Product->getJahrgang()
264
+                    ],
265
+                    'properties' => [
266
+                        [
267
+                            'id' => $this->mappings->getPropertyIdByNameAndGroup($Product->getLage(),'Einzellage'),
268
+                            'groupId' => $this->mappings->getPropertyGroupIdByName('Einzellage'),
269
+                            'name' => $Product->getLage()
270
+                        ]
119 271
                     ]
120 272
                 ];
121
-
273
+*/
122 274
                 if (!$this->shopware->addOrUpdateProductBySku($Product->getSku(), $arrData))
123 275
                 {
124 276
                     if ($isCli) $io->error('Could not update/import Product ' . $Product->getSku());
277
+                    dump($arrData);
125 278
                 }
126 279
 
127 280
                 if ($isCli)
128 281
                 {
129 282
                     $io->progressAdvance();
130 283
                 }
284
+                return;
131 285
             }
132 286
             if ($isCli) $io->progressFinish();
133 287
         }
Benjamin Roth authored on06/11/2024 20:50:22
Showing1 changed files
... ...
@@ -121,7 +121,7 @@ class ShopwareImportProductsJob extends AbstractController
121 121
 
122 122
                 if (!$this->shopware->addOrUpdateProductBySku($Product->getSku(), $arrData))
123 123
                 {
124
-                    if ($isCli) $io->error('Could not update');
124
+                    if ($isCli) $io->error('Could not update/import Product ' . $Product->getSku());
125 125
                 }
126 126
 
127 127
                 if ($isCli)
Benjamin Roth authored on06/11/2024 17:16:57
Showing1 changed files
1 1
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
+}