1<?php
2/**
3 * Copyright since 2007 PrestaShop SA and Contributors
4 * PrestaShop is an International Registered Trademark & Property of PrestaShop SA
5 *
6 * NOTICE OF LICENSE
7 *
8 * This source file is subject to the Open Software License (OSL 3.0)
9 * that is bundled with this package in the file LICENSE.md.
10 * It is also available through the world-wide-web at this URL:
11 * https://opensource.org/licenses/OSL-3.0
12 * If you did not receive a copy of the license and are unable to
13 * obtain it through the world-wide-web, please send an email
14 * to license@prestashop.com so we can send you a copy immediately.
15 *
16 * DISCLAIMER
17 *
18 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
19 * versions in the future. If you wish to customize PrestaShop for your
20 * needs please refer to https://devdocs.prestashop.com/ for more information.
21 *
22 * @author    PrestaShop SA and Contributors <contact@prestashop.com>
23 * @copyright Since 2007 PrestaShop SA and Contributors
24 * @license   https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
25 */
26
27declare(strict_types=1);
28
29namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider;
30
31use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface;
32use PrestaShop\PrestaShop\Core\Domain\Product\Combination\Query\GetCombinationForEditing;
33use PrestaShop\PrestaShop\Core\Domain\Product\Combination\Query\GetCombinationSuppliers;
34use PrestaShop\PrestaShop\Core\Domain\Product\Combination\QueryResult\CombinationForEditing;
35use PrestaShop\PrestaShop\Core\Domain\Product\Supplier\Query\GetProductSupplierOptions;
36use PrestaShop\PrestaShop\Core\Domain\Product\Supplier\QueryResult\ProductSupplierInfo;
37use PrestaShop\PrestaShop\Core\Domain\Product\Supplier\QueryResult\ProductSupplierOptions;
38use PrestaShop\PrestaShop\Core\Util\DateTime\DateTime;
39
40/**
41 * Provides the data that is used to prefill the Combination form
42 */
43class CombinationFormDataProvider implements FormDataProviderInterface
44{
45    /**
46     * @var CommandBusInterface
47     */
48    private $queryBus;
49
50    /**
51     * @param CommandBusInterface $queryBus
52     */
53    public function __construct(
54        CommandBusInterface $queryBus
55    ) {
56        $this->queryBus = $queryBus;
57    }
58
59    /**
60     * {@inheritDoc}
61     */
62    public function getData($id): array
63    {
64        $combinationId = (int) $id;
65        /** @var CombinationForEditing $combinationForEditing */
66        $combinationForEditing = $this->queryBus->handle(new GetCombinationForEditing($combinationId));
67
68        return [
69            'id' => $combinationId,
70            'product_id' => $combinationForEditing->getProductId(),
71            'name' => $combinationForEditing->getName(),
72            'stock' => $this->extractStockData($combinationForEditing),
73            'price_impact' => $this->extractPriceImpactData($combinationForEditing),
74            'references' => $this->extractReferencesData($combinationForEditing),
75            'suppliers' => $this->extractSuppliersData($combinationForEditing),
76            'images' => $combinationForEditing->getImageIds(),
77        ];
78    }
79
80    /**
81     * @param CombinationForEditing $combinationForEditing
82     *
83     * @return array
84     */
85    private function extractStockData(CombinationForEditing $combinationForEditing): array
86    {
87        $stockInformation = $combinationForEditing->getStock();
88        $availableDate = $stockInformation->getAvailableDate();
89
90        return [
91            'quantities' => [
92                'quantity' => $stockInformation->getQuantity(),
93                'minimal_quantity' => $stockInformation->getMinimalQuantity(),
94            ],
95            'options' => [
96                'stock_location' => $stockInformation->getLocation(),
97                'low_stock_threshold' => $stockInformation->getLowStockThreshold() ?: null,
98                'low_stock_alert' => $stockInformation->isLowStockAlertEnabled(),
99            ],
100            'available_date' => $availableDate ? $availableDate->format(DateTime::DEFAULT_DATE_FORMAT) : '',
101        ];
102    }
103
104    /**
105     * @param CombinationForEditing $combinationForEditing
106     *
107     * @return array
108     */
109    private function extractPriceImpactData(CombinationForEditing $combinationForEditing): array
110    {
111        $priceImpactInformation = $combinationForEditing->getPrices();
112
113        return [
114            'wholesale_price' => (float) (string) $priceImpactInformation->getWholesalePrice(),
115            'price_tax_excluded' => (float) (string) $priceImpactInformation->getImpactOnPrice(),
116            'price_tax_included' => (float) (string) $priceImpactInformation->getImpactOnPriceTaxIncluded(),
117            'ecotax' => (float) (string) $priceImpactInformation->getEcoTax(),
118            'unit_price' => (float) (string) $priceImpactInformation->getImpactOnUnitPrice(),
119            'weight' => (float) (string) $combinationForEditing->getDetails()->getImpactOnWeight(),
120        ];
121    }
122
123    /**
124     * @param CombinationForEditing $combinationForEditing
125     *
126     * @return array
127     */
128    private function extractReferencesData(CombinationForEditing $combinationForEditing): array
129    {
130        $details = $combinationForEditing->getDetails();
131
132        return [
133            'reference' => $details->getReference(),
134            'isbn' => $details->getIsbn(),
135            'ean_13' => $details->getEan13(),
136            'upc' => $details->getUpc(),
137            'mpn' => $details->getMpn(),
138        ];
139    }
140
141    /**
142     * @param CombinationForEditing $combinationForEditing
143     *
144     * @return array<string, int|array<int, int|array<string, string|int>>>
145     */
146    private function extractSuppliersData(CombinationForEditing $combinationForEditing): array
147    {
148        /** @var ProductSupplierOptions $productSupplierOptions */
149        $productSupplierOptions = $this->queryBus->handle(new GetProductSupplierOptions($combinationForEditing->getProductId()));
150
151        /** @var ProductSupplierInfo[] $combinationSupplierInfos */
152        $combinationSupplierInfos = $this->queryBus->handle(new GetCombinationSuppliers($combinationForEditing->getCombinationId()));
153
154        if (empty($combinationSupplierInfos)) {
155            return [];
156        }
157
158        $defaultSupplierId = $productSupplierOptions->getDefaultSupplierId();
159        $suppliersData = [
160            'default_supplier_id' => $defaultSupplierId,
161        ];
162
163        foreach ($combinationSupplierInfos as $supplierOption) {
164            $supplierForEditing = $supplierOption->getProductSupplierForEditing();
165            $supplierId = $supplierOption->getSupplierId();
166
167            $suppliersData['supplier_ids'][] = $supplierId;
168            $suppliersData['product_suppliers'][$supplierId] = [
169                'supplier_id' => $supplierId,
170                'supplier_name' => $supplierOption->getSupplierName(),
171                'product_supplier_id' => $supplierForEditing->getProductSupplierId(),
172                'price_tax_excluded' => $supplierForEditing->getPriceTaxExcluded(),
173                'reference' => $supplierForEditing->getReference(),
174                'currency_id' => $supplierForEditing->getCurrencyId(),
175                'combination_id' => $supplierForEditing->getCombinationId(),
176            ];
177        }
178
179        return $suppliersData;
180    }
181
182    /**
183     * {@inheritDoc}
184     */
185    public function getDefaultData(): array
186    {
187        // Not supposed to happen, Combinations are created vie Generator
188
189        return [];
190    }
191}
192