baby_in_magento

Untitled

Dec 27th, 2023
198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 62.48 KB | None | 0 0
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6.  
  7. namespace Froogal\Catalog\Model\Import;
  8.  
  9. use Magento\Catalog\Api\ProductRepositoryInterface;
  10. use Magento\Catalog\Model\Config as CatalogConfig;
  11. use Magento\Catalog\Model\Product\Visibility;
  12. use Magento\CatalogImportExport\Model\Import\Product\ImageTypeProcessor;
  13. use Magento\CatalogImportExport\Model\Import\Product\LinkProcessor;
  14. use Magento\CatalogImportExport\Model\Import\Product\MediaGalleryProcessor;
  15. use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface as ValidatorInterface;
  16. use Magento\CatalogImportExport\Model\Import\Product\StatusProcessor;
  17. use Magento\CatalogImportExport\Model\Import\Product\StockProcessor;
  18. use Magento\CatalogImportExport\Model\StockItemImporterInterface;
  19. use Magento\CatalogInventory\Api\Data\StockItemInterface;
  20. use Magento\Framework\App\Filesystem\DirectoryList;
  21. use Magento\Framework\App\ObjectManager;
  22. use Magento\Framework\Exception\LocalizedException;
  23. use Magento\Framework\Exception\NoSuchEntityException;
  24. use Magento\Framework\Filesystem;
  25. use Magento\Framework\Filesystem\Driver\File;
  26. use Magento\Framework\Filesystem\DriverPool;
  27. use Magento\Framework\Intl\DateTimeFactory;
  28. use Magento\Framework\Model\ResourceModel\Db\ObjectRelationProcessor;
  29. use Magento\Framework\Model\ResourceModel\Db\TransactionManagerInterface;
  30. use Magento\Framework\Stdlib\DateTime;
  31. use Magento\ImportExport\Model\Import;
  32. use Magento\ImportExport\Model\Import\Entity\AbstractEntity;
  33. use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingError;
  34. use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface;
  35. use Magento\Store\Model\Store;
  36. use Magento\CatalogImportExport\Model\Import\Product as ProductImport;
  37.  
  38.  
  39. /**
  40. * Import entity product model
  41. *
  42. * @api
  43. *
  44. * @SuppressWarnings(PHPMD.TooManyFields)
  45. * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
  46. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  47. * @SuppressWarnings(PHPMD.ExcessivePublicCount)
  48. * @since 100.0.2
  49. */
  50. class Product extends ProductImport
  51. {
  52. private const DEFAULT_GLOBAL_MULTIPLE_VALUE_SEPARATOR = ',';
  53. public const CONFIG_KEY_PRODUCT_TYPES = 'global/importexport/import_product_types';
  54. private const HASH_ALGORITHM = 'sha256';
  55.  
  56. /**
  57. * Size of bunch - part of products to save in one step.
  58. */
  59. public const BUNCH_SIZE = 20;
  60.  
  61. /**
  62. * Size of bunch to delete attributes of products in one step.
  63. */
  64. public const ATTRIBUTE_DELETE_BUNCH = 1000;
  65.  
  66. /**
  67. * Pseudo multi line separator in one cell.
  68. *
  69. * Can be used as custom option value delimiter or in configurable fields cells.
  70. */
  71. public const PSEUDO_MULTI_LINE_SEPARATOR = '|';
  72.  
  73. /**
  74. * Symbol between Name and Value between Pairs.
  75. */
  76. public const PAIR_NAME_VALUE_SEPARATOR = '=';
  77.  
  78. /**
  79. * Value that means all entities (e.g. websites, groups etc.)
  80. */
  81. public const VALUE_ALL = 'all';
  82.  
  83. /**
  84. * Data row scopes.
  85. */
  86. public const SCOPE_DEFAULT = 1;
  87.  
  88. public const SCOPE_WEBSITE = 2;
  89.  
  90. public const SCOPE_STORE = 0;
  91.  
  92. public const SCOPE_NULL = -1;
  93.  
  94. /**
  95. * Permanent column names.
  96. *
  97. * Names that begins with underscore is not an attribute. This name convention is for
  98. * to avoid interference with same attribute name.
  99. */
  100.  
  101. /**
  102. * Column product store.
  103. */
  104. public const COL_STORE = '_store';
  105.  
  106. /**
  107. * Column product store view code.
  108. */
  109. public const COL_STORE_VIEW_CODE = 'store_view_code';
  110.  
  111. /**
  112. * Column website.
  113. */
  114. public const COL_WEBSITE = 'website_code';
  115.  
  116. /**
  117. * Column product attribute set.
  118. */
  119. public const COL_ATTR_SET = '_attribute_set';
  120.  
  121. /**
  122. * Column product type.
  123. */
  124. public const COL_TYPE = 'product_type';
  125.  
  126. /**
  127. * Column product category.
  128. */
  129. public const COL_CATEGORY = 'categories';
  130.  
  131. /**
  132. * Column product visibility.
  133. */
  134. public const COL_VISIBILITY = 'visibility';
  135.  
  136. /**
  137. * Column product sku.
  138. */
  139. public const COL_SKU = 'sku';
  140.  
  141. /**
  142. * Column product name.
  143. */
  144. public const COL_NAME = 'name';
  145.  
  146. /**
  147. * Column product website.
  148. */
  149. public const COL_PRODUCT_WEBSITES = '_product_websites';
  150.  
  151. /**
  152. * Attribute code for media gallery.
  153. */
  154. public const MEDIA_GALLERY_ATTRIBUTE_CODE = 'media_gallery';
  155.  
  156. /**
  157. * Column media image.
  158. */
  159. public const COL_MEDIA_IMAGE = '_media_image';
  160.  
  161. /**
  162. * Inventory use config label.
  163. */
  164. public const INVENTORY_USE_CONFIG = 'Use Config';
  165.  
  166. /**
  167. * Prefix for inventory use config.
  168. */
  169. public const INVENTORY_USE_CONFIG_PREFIX = 'use_config_';
  170.  
  171. /**
  172. * Url key attribute code
  173. */
  174. public const URL_KEY = 'url_key';
  175.  
  176. /**
  177. * @var array
  178. */
  179. protected $_attributeCache = [];
  180.  
  181. /**
  182. * Pairs of attribute set ID-to-name.
  183. *
  184. * @var array
  185. */
  186. protected $_attrSetIdToName = [];
  187.  
  188. /**
  189. * Pairs of attribute set name-to-ID.
  190. *
  191. * @var array
  192. */
  193. protected $_attrSetNameToId = [];
  194.  
  195. /**
  196. * @var string
  197. * @since 100.0.4
  198. */
  199. protected $mediaGalleryTableName;
  200.  
  201. /**
  202. * @var string
  203. * @since 100.0.4
  204. */
  205. protected $mediaGalleryValueTableName;
  206. /**
  207. * @var string
  208. * @since 100.0.4
  209. */
  210. protected $mediaGalleryEntityToValueTableName;
  211.  
  212. /**
  213. * @var string
  214. * @since 100.0.4
  215. */
  216. protected $productEntityTableName;
  217.  
  218. /**
  219. * Attributes with index (not label) value.
  220. *
  221. * @var string[]
  222. */
  223. protected $_indexValueAttributes = [
  224. 'status',
  225. 'tax_class_id',
  226. ];
  227.  
  228. /**
  229. * Links attribute name-to-link type ID.
  230. *
  231. * @deprecated 101.1.0 use DI for LinkProcessor class if you want to add additional types
  232. *
  233. * @var array
  234. */
  235. protected $_linkNameToId = [
  236. '_related_' => \Magento\Catalog\Model\Product\Link::LINK_TYPE_RELATED,
  237. '_crosssell_' => \Magento\Catalog\Model\Product\Link::LINK_TYPE_CROSSSELL,
  238. '_upsell_' => \Magento\Catalog\Model\Product\Link::LINK_TYPE_UPSELL,
  239. ];
  240.  
  241. /**
  242. * @var array
  243. * @since 100.1.2
  244. */
  245. protected $dateAttrCodes = [
  246. 'special_from_date',
  247. 'special_to_date',
  248. 'news_from_date',
  249. 'news_to_date',
  250. 'custom_design_from',
  251. 'custom_design_to'
  252. ];
  253.  
  254. /**
  255. * @var bool
  256. */
  257. protected $logInHistory = true;
  258.  
  259. /**
  260. * Attribute id for product images storage.
  261. *
  262. * @var array
  263. */
  264. protected $_mediaGalleryAttributeId = null;
  265.  
  266. /**
  267. * @var array
  268. * @codingStandardsIgnoreStart
  269. */
  270. protected $_messageTemplates = [
  271. ValidatorInterface::ERROR_INVALID_SCOPE => 'Invalid value in Scope column',
  272. ValidatorInterface::ERROR_INVALID_WEBSITE => 'Invalid value in Website column (website does not exist?)',
  273. ValidatorInterface::ERROR_INVALID_STORE => 'Invalid value in Store column (store doesn\'t exist?)',
  274. ValidatorInterface::ERROR_INVALID_ATTR_SET => 'Invalid value for Attribute Set column (set doesn\'t exist?)',
  275. ValidatorInterface::ERROR_INVALID_TYPE => 'Product Type is invalid or not supported',
  276. ValidatorInterface::ERROR_INVALID_CATEGORY => 'Category does not exist',
  277. ValidatorInterface::ERROR_VALUE_IS_REQUIRED => 'Please make sure attribute "%s" is not empty.',
  278. ValidatorInterface::ERROR_TYPE_CHANGED => 'Trying to change type of existing products',
  279. ValidatorInterface::ERROR_SKU_IS_EMPTY => 'SKU is empty',
  280. ValidatorInterface::ERROR_NO_DEFAULT_ROW => 'Default values row does not exist',
  281. ValidatorInterface::ERROR_CHANGE_TYPE => 'Product type change is not allowed',
  282. ValidatorInterface::ERROR_DUPLICATE_SCOPE => 'Duplicate scope',
  283. ValidatorInterface::ERROR_DUPLICATE_SKU => 'Duplicate SKU',
  284. ValidatorInterface::ERROR_CHANGE_ATTR_SET => 'Attribute set change is not allowed',
  285. ValidatorInterface::ERROR_TYPE_UNSUPPORTED => 'Product type is not supported',
  286. ValidatorInterface::ERROR_ROW_IS_ORPHAN => 'Orphan rows that will be skipped due default row errors',
  287. ValidatorInterface::ERROR_INVALID_TIER_PRICE_QTY => 'Tier Price data price or quantity value is invalid',
  288. ValidatorInterface::ERROR_INVALID_TIER_PRICE_SITE => 'Tier Price data website is invalid',
  289. ValidatorInterface::ERROR_INVALID_TIER_PRICE_GROUP => 'Tier Price customer group ID is invalid',
  290. ValidatorInterface::ERROR_TIER_DATA_INCOMPLETE => 'Tier Price data is incomplete',
  291. ValidatorInterface::ERROR_SKU_NOT_FOUND_FOR_DELETE => 'Product with specified SKU not found',
  292. ValidatorInterface::ERROR_SUPER_PRODUCTS_SKU_NOT_FOUND => 'Product with specified super products SKU not found',
  293. ValidatorInterface::ERROR_MEDIA_DATA_INCOMPLETE => 'Media data is incomplete',
  294. ValidatorInterface::ERROR_EXCEEDED_MAX_LENGTH => 'Attribute %s exceeded max length',
  295. ValidatorInterface::ERROR_INVALID_ATTRIBUTE_TYPE => 'Value for \'%s\' attribute contains incorrect value',
  296. ValidatorInterface::ERROR_ABSENT_REQUIRED_ATTRIBUTE => 'Attribute %s is required',
  297. ValidatorInterface::ERROR_INVALID_ATTRIBUTE_OPTION => 'Value for \'%s\' attribute contains incorrect value, see acceptable values on settings specified for Admin',
  298. ValidatorInterface::ERROR_DUPLICATE_UNIQUE_ATTRIBUTE => 'Duplicated unique attribute',
  299. ValidatorInterface::ERROR_INVALID_VARIATIONS_CUSTOM_OPTIONS => 'Value for \'%s\' sub attribute in \'%s\' attribute contains incorrect value, acceptable values are: \'dropdown\', \'checkbox\', \'radio\', \'text\'',
  300. ValidatorInterface::ERROR_INVALID_MEDIA_URL_OR_PATH => 'Wrong URL/path used for attribute %s',
  301. ValidatorInterface::ERROR_MEDIA_PATH_NOT_ACCESSIBLE => 'Imported resource (image) does not exist in the local media storage',
  302. ValidatorInterface::ERROR_MEDIA_URL_NOT_ACCESSIBLE => 'Imported resource (image) could not be downloaded from external resource due to timeout or access permissions',
  303. ValidatorInterface::ERROR_INVALID_WEIGHT => 'Product weight is invalid',
  304. ValidatorInterface::ERROR_DUPLICATE_URL_KEY => 'Url key: \'%s\' was already generated for an item with the SKU: \'%s\'. You need to specify the unique URL key manually',
  305. ValidatorInterface::ERROR_DUPLICATE_MULTISELECT_VALUES => 'Value for multiselect attribute %s contains duplicated values',
  306. 'invalidNewToDateValue' => 'Make sure new_to_date is later than or the same as new_from_date',
  307. // Can't add new translated strings in patch release
  308. 'invalidLayoutUpdate' => 'Invalid format.',
  309. 'insufficientPermissions' => 'Invalid format.',
  310. ValidatorInterface::ERROR_SKU_MARGINAL_WHITESPACES => 'SKU contains marginal whitespaces'
  311. ];
  312. //@codingStandardsIgnoreEnd
  313.  
  314. /**
  315. * Map between import file fields and system fields/attributes.
  316. *
  317. * @var array
  318. */
  319. protected $_fieldsMap = [
  320. 'image' => 'base_image',
  321. 'image_label' => "base_image_label",
  322. 'thumbnail' => 'thumbnail_image',
  323. 'thumbnail_label' => 'thumbnail_image_label',
  324. self::COL_MEDIA_IMAGE => 'additional_images',
  325. '_media_image_label' => 'additional_image_labels',
  326. '_media_is_disabled' => 'hide_from_product_page',
  327. Product::COL_STORE => 'store_view_code',
  328. Product::COL_ATTR_SET => 'attribute_set_code',
  329. Product::COL_TYPE => 'product_type',
  330. Product::COL_PRODUCT_WEBSITES => 'product_websites',
  331. 'status' => 'product_online',
  332. 'news_from_date' => 'new_from_date',
  333. 'news_to_date' => 'new_to_date',
  334. 'options_container' => 'display_product_options_in',
  335. 'minimal_price' => 'map_price',
  336. 'msrp' => 'msrp_price',
  337. 'msrp_enabled' => 'map_enabled',
  338. 'special_from_date' => 'special_price_from_date',
  339. 'special_to_date' => 'special_price_to_date',
  340. 'min_qty' => 'out_of_stock_qty',
  341. 'backorders' => 'allow_backorders',
  342. 'min_sale_qty' => 'min_cart_qty',
  343. 'max_sale_qty' => 'max_cart_qty',
  344. 'notify_stock_qty' => 'notify_on_stock_below',
  345. '_related_sku' => 'related_skus',
  346. '_related_position' => 'related_position',
  347. '_crosssell_sku' => 'crosssell_skus',
  348. '_crosssell_position' => 'crosssell_position',
  349. '_upsell_sku' => 'upsell_skus',
  350. '_upsell_position' => 'upsell_position',
  351. 'meta_keyword' => 'meta_keywords',
  352. ];
  353.  
  354. /**
  355. * Existing products SKU-related information in form of array:
  356. *
  357. * [SKU] => array(
  358. * 'type_id' => (string) product type
  359. * 'attr_set_id' => (int) product attribute set ID
  360. * 'entity_id' => (int) product ID
  361. * 'supported_type' => (boolean) is product type supported by current version of import module
  362. * )
  363. *
  364. * @var array
  365. */
  366. protected $_oldSku = [];
  367.  
  368. /**
  369. * Column names that holds values with particular meaning.
  370. *
  371. * @var string[]
  372. */
  373. protected $_specialAttributes = [
  374. self::COL_STORE,
  375. self::COL_ATTR_SET,
  376. self::COL_TYPE,
  377. self::COL_CATEGORY,
  378. '_product_websites',
  379. self::COL_PRODUCT_WEBSITES,
  380. '_tier_price_website',
  381. '_tier_price_customer_group',
  382. '_tier_price_qty',
  383. '_tier_price_price',
  384. '_related_sku',
  385. '_related_position',
  386. '_crosssell_sku',
  387. '_crosssell_position',
  388. '_upsell_sku',
  389. '_upsell_position',
  390. '_custom_option_store',
  391. '_custom_option_type',
  392. '_custom_option_title',
  393. '_custom_option_is_required',
  394. '_custom_option_price',
  395. '_custom_option_sku',
  396. '_custom_option_max_characters',
  397. '_custom_option_sort_order',
  398. '_custom_option_file_extension',
  399. '_custom_option_image_size_x',
  400. '_custom_option_image_size_y',
  401. '_custom_option_row_title',
  402. '_custom_option_row_price',
  403. '_custom_option_row_sku',
  404. '_custom_option_row_sort',
  405. '_media_attribute_id',
  406. self::COL_MEDIA_IMAGE,
  407. '_media_label',
  408. '_media_position',
  409. '_media_is_disabled',
  410. ];
  411.  
  412. /**
  413. * @var array
  414. */
  415. protected $defaultStockData = [
  416. 'manage_stock' => 1,
  417. 'use_config_manage_stock' => 1,
  418. 'qty' => 0,
  419. 'min_qty' => 0,
  420. 'use_config_min_qty' => 1,
  421. 'min_sale_qty' => 1,
  422. 'use_config_min_sale_qty' => 1,
  423. 'max_sale_qty' => 10000,
  424. 'use_config_max_sale_qty' => 1,
  425. 'is_qty_decimal' => 0,
  426. 'backorders' => 0,
  427. 'use_config_backorders' => 1,
  428. 'notify_stock_qty' => 1,
  429. 'use_config_notify_stock_qty' => 1,
  430. 'enable_qty_increments' => 0,
  431. 'use_config_enable_qty_inc' => 1,
  432. 'qty_increments' => 0,
  433. 'use_config_qty_increments' => 1,
  434. 'is_in_stock' => 1,
  435. 'low_stock_date' => null,
  436. 'stock_status_changed_auto' => 0,
  437. 'is_decimal_divided' => 0,
  438. ];
  439.  
  440. /**
  441. * Column names that holds images files names
  442. *
  443. * Note: the order of array items has a value in order to properly set 'position' value
  444. * of media gallery items.
  445. *
  446. * @var string[]
  447. */
  448. protected $_imagesArrayKeys = [];
  449.  
  450. /**
  451. * Permanent entity columns.
  452. *
  453. * @var string[]
  454. */
  455. protected $_permanentAttributes = [self::COL_SKU];
  456.  
  457. /**
  458. * Array of supported product types as keys with appropriate model object as value.
  459. *
  460. * @var \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType[]
  461. */
  462. protected $_productTypeModels = [];
  463.  
  464. /**
  465. * Media files uploader
  466. *
  467. * @var \Magento\CatalogImportExport\Model\Import\Uploader
  468. */
  469. protected $_fileUploader;
  470.  
  471. /**
  472. * Import entity which provide import of product custom options
  473. *
  474. * @var \Magento\CatalogImportExport\Model\Import\Product\Option
  475. */
  476. protected $_optionEntity;
  477.  
  478. /**
  479. * @var \Magento\Catalog\Helper\Data
  480. */
  481. protected $_catalogData = null;
  482.  
  483. /**
  484. * @var \Magento\CatalogInventory\Api\StockRegistryInterface
  485. */
  486. protected $stockRegistry;
  487.  
  488. /**
  489. * @var \Magento\CatalogInventory\Api\StockConfigurationInterface
  490. */
  491. protected $stockConfiguration;
  492.  
  493. /**
  494. * @var \Magento\CatalogInventory\Model\Spi\StockStateProviderInterface
  495. */
  496. protected $stockStateProvider;
  497.  
  498. /**
  499. * Core event manager proxy
  500. *
  501. * @var \Magento\Framework\Event\ManagerInterface
  502. */
  503. protected $_eventManager = null;
  504.  
  505. /**
  506. * @var \Magento\ImportExport\Model\Import\Config
  507. */
  508. protected $_importConfig;
  509.  
  510. /**
  511. * @var \Magento\CatalogImportExport\Model\Import\Proxy\Product\ResourceModelFactory
  512. */
  513. protected $_resourceFactory;
  514.  
  515. /**
  516. * @var \Magento\CatalogImportExport\Model\Import\Proxy\Product\ResourceModel
  517. */
  518. protected $_resource;
  519.  
  520. /**
  521. * @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory
  522. */
  523. protected $_setColFactory;
  524.  
  525. /**
  526. * @var \Magento\CatalogImportExport\Model\Import\Product\Type\Factory
  527. */
  528. protected $_productTypeFactory;
  529.  
  530. /**
  531. * @var \Magento\Catalog\Model\ResourceModel\Product\LinkFactory
  532. */
  533. protected $_linkFactory;
  534.  
  535. /**
  536. * @var \Magento\CatalogImportExport\Model\Import\Proxy\ProductFactory
  537. */
  538. protected $_proxyProdFactory;
  539.  
  540. /**
  541. * @var \Magento\CatalogImportExport\Model\Import\UploaderFactory
  542. */
  543. protected $_uploaderFactory;
  544.  
  545. /**
  546. * @var \Magento\Framework\Filesystem\Directory\WriteInterface
  547. */
  548. protected $_mediaDirectory;
  549.  
  550. /**
  551. * @var \Magento\CatalogInventory\Model\ResourceModel\Stock\ItemFactory
  552. * @deprecated 101.0.0 this variable isn't used anymore.
  553. */
  554. protected $_stockResItemFac;
  555.  
  556. /**
  557. * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
  558. */
  559. protected $_localeDate;
  560.  
  561. /**
  562. * @var DateTime
  563. */
  564. protected $dateTime;
  565.  
  566. /**
  567. * @var \Magento\Framework\Indexer\IndexerRegistry
  568. */
  569. protected $indexerRegistry;
  570.  
  571. /**
  572. * @var Product\StoreResolver
  573. */
  574. protected $storeResolver;
  575.  
  576. /**
  577. * @var Product\SkuProcessor
  578. */
  579. protected $skuProcessor;
  580.  
  581. /**
  582. * @var Product\CategoryProcessor
  583. */
  584. protected $categoryProcessor;
  585.  
  586. /**
  587. * @var \Magento\Framework\App\Config\ScopeConfigInterface
  588. * @since 100.0.3
  589. */
  590. protected $scopeConfig;
  591.  
  592. /**
  593. * @var \Magento\Catalog\Model\Product\Url
  594. * @since 100.0.3
  595. */
  596. protected $productUrl;
  597.  
  598. /**
  599. * @var array
  600. */
  601. protected $websitesCache = [];
  602.  
  603. /**
  604. * @var array
  605. */
  606. protected $categoriesCache = [];
  607.  
  608. /**
  609. * @var array
  610. * @since 100.0.3
  611. */
  612. protected $productUrlSuffix = [];
  613.  
  614. /**
  615. * @var array
  616. * @deprecated 100.0.3
  617. * @since 100.0.3
  618. */
  619. protected $productUrlKeys = [];
  620.  
  621. /**
  622. * Instance of product tax class processor.
  623. *
  624. * @var Product\TaxClassProcessor
  625. */
  626. protected $taxClassProcessor;
  627.  
  628. /**
  629. * @var Product\Validator
  630. */
  631. protected $validator;
  632.  
  633. /**
  634. * Array of validated rows.
  635. *
  636. * @var array
  637. */
  638. protected $validatedRows;
  639.  
  640. /**
  641. * @var \Psr\Log\LoggerInterface
  642. */
  643. private $_logger;
  644.  
  645. /**
  646. * @var string
  647. */
  648. protected $masterAttributeCode = 'sku';
  649.  
  650. /**
  651. * @var ObjectRelationProcessor
  652. */
  653. protected $objectRelationProcessor;
  654.  
  655. /**
  656. * @var TransactionManagerInterface
  657. */
  658. protected $transactionManager;
  659.  
  660. /**
  661. * Flag for replace operation.
  662. *
  663. * @var null
  664. */
  665. protected $_replaceFlag = null;
  666.  
  667. /**
  668. * Flag for replace operation.
  669. *
  670. * @var null
  671. */
  672. protected $cachedImages = null;
  673.  
  674. /**
  675. * @var array
  676. * @since 100.0.3
  677. */
  678. protected $urlKeys = [];
  679.  
  680. /**
  681. * @var array
  682. * @since 100.0.3
  683. */
  684. protected $rowNumbers = [];
  685.  
  686. /**
  687. * @var string
  688. */
  689. private $productEntityLinkField;
  690.  
  691. /**
  692. * @var string
  693. */
  694. private $productEntityIdentifierField;
  695.  
  696. /**
  697. * Escaped separator value for regular expression.
  698. * The value is based on PSEUDO_MULTI_LINE_SEPARATOR constant.
  699. * @var string
  700. */
  701. private $multiLineSeparatorForRegexp;
  702.  
  703. /**
  704. * Container for filesystem object.
  705. *
  706. * @var Filesystem
  707. */
  708. private $filesystem;
  709.  
  710. /**
  711. * @var CatalogConfig
  712. */
  713. private $catalogConfig;
  714.  
  715. /**
  716. * @var StockItemImporterInterface
  717. */
  718. private $stockItemImporter;
  719.  
  720. /**
  721. * @var ImageTypeProcessor
  722. */
  723. private $imageTypeProcessor;
  724.  
  725. /**
  726. * Provide ability to process and save images during import.
  727. *
  728. * @var MediaGalleryProcessor
  729. */
  730. private $mediaProcessor;
  731.  
  732. /**
  733. * @var DateTimeFactory
  734. */
  735. private $dateTimeFactory;
  736.  
  737. /**
  738. * @var ProductRepositoryInterface
  739. */
  740. private $productRepository;
  741.  
  742. /**
  743. * @var StatusProcessor
  744. */
  745. private $statusProcessor;
  746. /**
  747. * @var StockProcessor
  748. */
  749. private $stockProcessor;
  750.  
  751. /**
  752. * @var LinkProcessor
  753. */
  754. private $linkProcessor;
  755.  
  756. public $productFactoryData;
  757.  
  758. /**
  759. * @param \Magento\Framework\Json\Helper\Data $jsonHelper
  760. * @param \Magento\ImportExport\Helper\Data $importExportData
  761. * @param \Magento\ImportExport\Model\ResourceModel\Import\Data $importData
  762. * @param \Magento\Eav\Model\Config $config
  763. * @param \Magento\Framework\App\ResourceConnection $resource
  764. * @param \Magento\ImportExport\Model\ResourceModel\Helper $resourceHelper
  765. * @param \Magento\Framework\Stdlib\StringUtils $string
  766. * @param ProcessingErrorAggregatorInterface $errorAggregator
  767. * @param \Magento\Framework\Event\ManagerInterface $eventManager
  768. * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
  769. * @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration
  770. * @param \Magento\CatalogInventory\Model\Spi\StockStateProviderInterface $stockStateProvider
  771. * @param \Magento\Catalog\Helper\Data $catalogData
  772. * @param \Magento\ImportExport\Model\Import\Config $importConfig
  773. * @param Proxy\Product\ResourceModelFactory $resourceFactory
  774. * @param Product\OptionFactory $optionFactory
  775. * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory $setColFactory
  776. * @param Product\Type\Factory $productTypeFactory
  777. * @param \Magento\Catalog\Model\ResourceModel\Product\LinkFactory $linkFactory
  778. * @param Proxy\ProductFactory $proxyProdFactory
  779. * @param UploaderFactory $uploaderFactory
  780. * @param \Magento\Framework\Filesystem $filesystem
  781. * @param \Magento\CatalogInventory\Model\ResourceModel\Stock\ItemFactory $stockResItemFac
  782. * @param DateTime\TimezoneInterface $localeDate
  783. * @param DateTime $dateTime
  784. * @param \Psr\Log\LoggerInterface $logger
  785. * @param \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry
  786. * @param Product\StoreResolver $storeResolver
  787. * @param Product\SkuProcessor $skuProcessor
  788. * @param Product\CategoryProcessor $categoryProcessor
  789. * @param Product\Validator $validator
  790. * @param ObjectRelationProcessor $objectRelationProcessor
  791. * @param TransactionManagerInterface $transactionManager
  792. * @param Product\TaxClassProcessor $taxClassProcessor
  793. * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
  794. * @param \Magento\Catalog\Model\Product\Url $productUrl
  795. * @param array $data
  796. * @param array $dateAttrCodes
  797. * @param CatalogConfig $catalogConfig
  798. * @param ImageTypeProcessor $imageTypeProcessor
  799. * @param MediaGalleryProcessor $mediaProcessor
  800. * @param StockItemImporterInterface|null $stockItemImporter
  801. * @param DateTimeFactory $dateTimeFactory
  802. * @param ProductRepositoryInterface|null $productRepository
  803. * @param StatusProcessor|null $statusProcessor
  804. * @param StockProcessor|null $stockProcessor
  805. * @param LinkProcessor|null $linkProcessor
  806. * @param File|null $fileDriver
  807. * @throws LocalizedException
  808. * @throws \Magento\Framework\Exception\FileSystemException
  809. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  810. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  811. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  812. */
  813. public function __construct(
  814. \Magento\Framework\Json\Helper\Data $jsonHelper,
  815. \Magento\ImportExport\Helper\Data $importExportData,
  816. \Magento\ImportExport\Model\ResourceModel\Import\Data $importData,
  817. \Magento\Eav\Model\Config $config,
  818. \Magento\Framework\App\ResourceConnection $resource,
  819. \Magento\ImportExport\Model\ResourceModel\Helper $resourceHelper,
  820. \Magento\Framework\Stdlib\StringUtils $string,
  821. ProcessingErrorAggregatorInterface $errorAggregator,
  822. \Magento\Framework\Event\ManagerInterface $eventManager,
  823. \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
  824. \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration,
  825. \Magento\CatalogInventory\Model\Spi\StockStateProviderInterface $stockStateProvider,
  826. \Magento\Catalog\Helper\Data $catalogData,
  827. \Magento\ImportExport\Model\Import\Config $importConfig,
  828. \Magento\CatalogImportExport\Model\Import\Proxy\Product\ResourceModelFactory $resourceFactory,
  829. \Magento\CatalogImportExport\Model\Import\Product\OptionFactory $optionFactory,
  830. \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory $setColFactory,
  831. \Magento\CatalogImportExport\Model\Import\Product\Type\Factory $productTypeFactory,
  832. \Magento\Catalog\Model\ResourceModel\Product\LinkFactory $linkFactory,
  833. \Magento\CatalogImportExport\Model\Import\Proxy\ProductFactory $proxyProdFactory,
  834. \Magento\CatalogImportExport\Model\Import\UploaderFactory $uploaderFactory,
  835. \Magento\Framework\Filesystem $filesystem,
  836. \Magento\CatalogInventory\Model\ResourceModel\Stock\ItemFactory $stockResItemFac,
  837. \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
  838. DateTime $dateTime,
  839. \Psr\Log\LoggerInterface $logger,
  840. \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry,
  841. \Magento\CatalogImportExport\Model\Import\Product\StoreResolver $storeResolver,
  842. \Magento\CatalogImportExport\Model\Import\Product\SkuProcessor $skuProcessor,
  843. \Magento\CatalogImportExport\Model\Import\Product\CategoryProcessor $categoryProcessor,
  844. \Magento\CatalogImportExport\Model\Import\Product\Validator $validator,
  845. ObjectRelationProcessor $objectRelationProcessor,
  846. TransactionManagerInterface $transactionManager,
  847. \Magento\CatalogImportExport\Model\Import\Product\TaxClassProcessor $taxClassProcessor,
  848. \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
  849. \Magento\Catalog\Model\Product\Url $productUrl,
  850. array $data = [],
  851. array $dateAttrCodes = [],
  852. CatalogConfig $catalogConfig = null,
  853. ImageTypeProcessor $imageTypeProcessor = null,
  854. MediaGalleryProcessor $mediaProcessor = null,
  855. StockItemImporterInterface $stockItemImporter = null,
  856. DateTimeFactory $dateTimeFactory = null,
  857. ProductRepositoryInterface $productRepository = null,
  858. StatusProcessor $statusProcessor = null,
  859. StockProcessor $stockProcessor = null,
  860. LinkProcessor $linkProcessor = null,
  861. File $fileDriver = null,
  862. \Magento\Catalog\Model\ProductFactory $productFactoryData,
  863. \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory
  864.  
  865. ) {
  866. $this->_eventManager = $eventManager;
  867. $this->stockRegistry = $stockRegistry;
  868. $this->stockConfiguration = $stockConfiguration;
  869. $this->stockStateProvider = $stockStateProvider;
  870. $this->_catalogData = $catalogData;
  871. $this->_importConfig = $importConfig;
  872. $this->_resourceFactory = $resourceFactory;
  873. $this->_setColFactory = $setColFactory;
  874. $this->_productTypeFactory = $productTypeFactory;
  875. $this->_linkFactory = $linkFactory;
  876. $this->_proxyProdFactory = $proxyProdFactory;
  877. $this->_uploaderFactory = $uploaderFactory;
  878. $this->filesystem = $filesystem;
  879. $this->_mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
  880. $this->_stockResItemFac = $stockResItemFac;
  881. $this->_localeDate = $localeDate;
  882. $this->dateTime = $dateTime;
  883. $this->indexerRegistry = $indexerRegistry;
  884. $this->_logger = $logger;
  885. $this->storeResolver = $storeResolver;
  886. $this->skuProcessor = $skuProcessor;
  887. $this->categoryProcessor = $categoryProcessor;
  888. $this->validator = $validator;
  889. $this->objectRelationProcessor = $objectRelationProcessor;
  890. $this->transactionManager = $transactionManager;
  891. $this->taxClassProcessor = $taxClassProcessor;
  892. $this->scopeConfig = $scopeConfig;
  893. $this->productUrl = $productUrl;
  894. $this->dateAttrCodes = array_merge($this->dateAttrCodes, $dateAttrCodes);
  895. $this->catalogConfig = $catalogConfig ?: ObjectManager::getInstance()->get(CatalogConfig::class);
  896. $this->imageTypeProcessor = $imageTypeProcessor ?: ObjectManager::getInstance()->get(ImageTypeProcessor::class);
  897. $this->mediaProcessor = $mediaProcessor ?: ObjectManager::getInstance()->get(MediaGalleryProcessor::class);
  898. $this->stockItemImporter = $stockItemImporter ?: ObjectManager::getInstance()
  899. ->get(StockItemImporterInterface::class);
  900. $this->statusProcessor = $statusProcessor ?: ObjectManager::getInstance()
  901. ->get(StatusProcessor::class);
  902. $this->stockProcessor = $stockProcessor ?: ObjectManager::getInstance()
  903. ->get(StockProcessor::class);
  904. $this->linkProcessor = $linkProcessor ?? ObjectManager::getInstance()
  905. ->get(LinkProcessor::class);
  906. $this->linkProcessor->addNameToIds($this->_linkNameToId);
  907. $this->data = $data;
  908. $this->productFactoryData = $productFactoryData;
  909. $this->productCollectionFactory = $productCollectionFactory;
  910.  
  911.  
  912.  
  913. parent::__construct(
  914. $jsonHelper,
  915. $importExportData,
  916. $importData,
  917. $config,
  918. $resource,
  919. $resourceHelper,
  920. $string,
  921. $errorAggregator,
  922. $eventManager,
  923. $stockRegistry,
  924. $stockConfiguration,
  925. $stockStateProvider,
  926. $catalogData,$importConfig,$resourceFactory,$optionFactory,$setColFactory,$productTypeFactory,
  927. $linkFactory,$proxyProdFactory,$uploaderFactory,$filesystem,$stockResItemFac,$localeDate,$dateTime,$logger,$indexerRegistry,$storeResolver,$skuProcessor,$categoryProcessor,$validator,$objectRelationProcessor,$transactionManager,$taxClassProcessor,
  928. $scopeConfig,$productUrl,$data,$dateAttrCodes,$catalogConfig,$imageTypeProcessor,$mediaProcessor,
  929. $stockItemImporter,$dateTimeFactory,$productRepository,$statusProcessor,$stockProcessor,
  930. $linkProcessor,$fileDriver
  931. );
  932.  
  933.  
  934. $this->_optionEntity = $data['option_entity'] ??
  935. $optionFactory->create(['data' => ['product_entity' => $this]]);
  936. $this->_initAttributeSets()
  937. ->_initTypeModels()
  938. ->_initSkus()
  939. ->initImagesArrayKeys();
  940. $this->validator->init($this);
  941. $this->dateTimeFactory = $dateTimeFactory ?? ObjectManager::getInstance()->get(DateTimeFactory::class);
  942. $this->productRepository = $productRepository ?? ObjectManager::getInstance()
  943. ->get(ProductRepositoryInterface::class);
  944. }
  945.  
  946. /**
  947. * Save products data.
  948. *
  949. * @return $this
  950. * @throws LocalizedException
  951. */
  952. protected function _saveProductsData()
  953. {
  954.  
  955. $writer = new \Zend_Log_Writer_Stream(BP . '/var/log/custom.log');
  956. $logger = new \Zend_Log();
  957. $logger->addWriter($writer);
  958. $logger->info('_saveProductsData');
  959. $this->_saveProducts();
  960. foreach ($this->_productTypeModels as $productTypeModel) {
  961. $productTypeModel->saveData();
  962. }
  963. $this->linkProcessor->saveLinks($this, $this->_dataSourceModel, $this->getProductEntityLinkField());
  964. $this->_saveStockItem();
  965. if ($this->_replaceFlag) {
  966. $this->getOptionEntity()->clearProductsSkuToId();
  967. }
  968. $this->getOptionEntity()->importData();
  969.  
  970. return $this;
  971. }
  972.  
  973. /**
  974. * Stock item saving.
  975. *
  976. * @return $this
  977. */
  978. protected function _saveStockItem()
  979. {
  980. $writer = new \Zend_Log_Writer_Stream(BP . '/var/log/custom.log');
  981. $logger = new \Zend_Log();
  982. $logger->addWriter($writer);
  983. $logger->info('save stockitem');
  984. while ($bunch = $this->_dataSourceModel->getNextBunch()) {
  985. $stockData = [];
  986. $productIdsToReindex = [];
  987. $stockChangedProductIds = [];
  988. // Format bunch to stock data rows
  989. foreach ($bunch as $rowNum => $rowData) {
  990. $logger->info('rowdata'.json_encode($rowData));
  991. $logger->info('rowNum'.json_encode($rowNum));
  992. if($rowNum == 0)
  993. {
  994. $this->getConnection()->truncateTable('product_constituents');
  995. }
  996. if (!$this->isRowAllowedToImport($rowData, $rowNum)) {
  997. continue;
  998. }
  999.  
  1000. $row = [];
  1001. $sku = $rowData[self::COL_SKU];
  1002. if ($this->skuProcessor->getNewSku($sku) !== null) {
  1003. $stockItem = $this->getRowExistingStockItem($rowData);
  1004. $existingStockItemData = $stockItem->getData();
  1005. $row = $this->formatStockDataForRow($rowData);
  1006. $productIdsToReindex[] = $row['product_id'];
  1007. $storeId = $this->getRowStoreId($rowData);
  1008. if (!empty(array_diff_assoc($row, $existingStockItemData))
  1009. || $this->statusProcessor->isStatusChanged($sku, $storeId)
  1010. ) {
  1011. $stockChangedProductIds[] = $row['product_id'];
  1012. }
  1013. $this->productConstitutesProcess($row, $rowData);
  1014. }
  1015.  
  1016. if (!isset($stockData[$sku])) {
  1017. $stockData[$sku] = $row;
  1018. }
  1019. }
  1020.  
  1021.  
  1022. // Insert rows
  1023. if (!empty($stockData)) {
  1024. $this->stockItemImporter->import($stockData);
  1025. //$logger->info('stockData ='.json_encode($stockData));
  1026. foreach($stockData as $product)
  1027. {
  1028.  
  1029.  
  1030. //$logger->info('stock product ='.json_encode($product));
  1031. }
  1032. }
  1033.  
  1034. $this->reindexStockStatus($stockChangedProductIds);
  1035. $this->reindexProducts($productIdsToReindex);
  1036.  
  1037. }
  1038. return $this;
  1039. }
  1040.  
  1041. public function getDefaultVariantId($product)
  1042. {
  1043. $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
  1044. $productVariantIds = $objectManager->create('Froogal\Catalog\Model\ProductVariant')
  1045. ->getCollection()
  1046. ->addFieldToFilter('product_id', $product['product_id'])
  1047. ->addFieldToFilter('variant_name', 'default')
  1048. ->getData();
  1049. if(empty($productVariantIds))
  1050. {
  1051. $model = $objectManager->create('Froogal\Catalog\Model\ProductVariantFactory')->create();
  1052. $model->addData([
  1053. "product_id" => $product['product_id'],
  1054. "variant_name" => "default"
  1055. ]);
  1056. $model->save();
  1057. return $model->getData()['id'];
  1058. } else {
  1059. return $productVariantIds[0]['id'];
  1060. }
  1061. }
  1062.  
  1063. public function deleteAllConsituents($product, $variantId)
  1064. {
  1065. $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
  1066. $model = $objectManager->create('Froogal\Catalog\Model\ProductRelation')
  1067. ->getCollection()
  1068. ->addFieldToFilter('product_id', $product['product_id'])
  1069. ->addFieldToFilter('variant_id', $variantId)
  1070. ->load();
  1071. foreach ($model as $m) {
  1072. $m->delete();
  1073. }
  1074. }
  1075.  
  1076. protected $customLogger;
  1077.  
  1078. public function productConstitutesProcess($product,$rowData)
  1079. {
  1080.  
  1081. $variantId = $this->getDefaultVariantId($product);
  1082. // $this->deleteAllConsituents($product, $variantId);
  1083. $this->saveGoldProductConstituents($product, $variantId, $rowData);
  1084. $this->savePlatinumProductConstituents($product, $variantId, $rowData);
  1085. $this->saveDiamondProductConstituents($product, $variantId, $rowData);
  1086. }
  1087.  
  1088. public function saveGoldProductConstituents($product, $variantId, $rowData)
  1089. {
  1090. $writer = new \Zend_Log_Writer_Stream(BP . '/var/log/custom.log');
  1091. $logger = new \Zend_Log();
  1092. $logger->addWriter($writer);
  1093. if (isset($rowData['gold_weight']) && $rowData['gold_weight'] > 0) {
  1094. if (empty($rowData['gold_carat'])) {
  1095. throw new LocalizedException(__('gold_carat not found!'));
  1096. }
  1097. if (empty($rowData['gold_color'])) {
  1098. throw new LocalizedException(__('gold_color not found!'));
  1099. }
  1100. $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
  1101.  
  1102. $productId = $product['product_id'];
  1103. $goldWeight = $rowData['gold_weight'];
  1104. $goldCarat = $rowData['gold_carat'];
  1105. $goldColor = $rowData['gold_color'];
  1106. $logger->info('row gold color'.$goldColor);
  1107. $logger->info('row gold carat'.$goldCarat);
  1108. $attribute = $objectManager->create('\Magento\Catalog\Api\ProductAttributeRepositoryInterface');
  1109. $attributeColor= $attribute->get('gold_color');
  1110. $attributeCarat= $attribute->get('gold_carat');
  1111. $attributeConstituentType= $attribute->get('constituent_type');
  1112. $attributeColorId = $attributeColor->getAttributeId();
  1113. $attributeCaratId = $attributeCarat->getAttributeId();
  1114. $attributeConstituentTypeId = $attributeConstituentType->getAttributeId();
  1115.  
  1116.  
  1117. $attributeconfig = $objectManager->create('\Magento\Eav\Model\Config');
  1118. $attributeType = $attributeconfig->getAttribute('catalog_product', $attributeConstituentTypeId);
  1119. $attributeColor = $attributeconfig->getAttribute('catalog_product', $attributeColorId);
  1120. $attributeCarat = $attributeconfig->getAttribute('catalog_product', $attributeCaratId);
  1121. $attributeColoroptions = $attributeColor->getSource()->getAllOptions();
  1122. $attributeCaratoptions = $attributeCarat->getSource()->getAllOptions();
  1123. $attributeTypeoptions = $attributeType->getSource()->getAllOptions();
  1124.  
  1125. $constitute_type_id = null;
  1126. foreach($attributeTypeoptions as $type)
  1127. {
  1128. if($type['label'] == "Gold")
  1129. {
  1130. $constitute_type_id = $type['value'];
  1131. break;
  1132. }
  1133. }
  1134.  
  1135. foreach($attributeColoroptions as $option)
  1136. {
  1137. $goldColorId = $option['value'];
  1138. $logger->info('inside foreach color id'.$goldColorId);
  1139. if($option['label'] == ucfirst($goldColor))
  1140. {
  1141. $logger->info('inside foreach color label'.$option['label']);
  1142. foreach($attributeCaratoptions as $optionvalues)
  1143. {
  1144. $goldCaratId = $optionvalues['value'];
  1145. $logger->info('inside foreach carat id'.$goldCarat);
  1146. if($optionvalues['label'] == $goldCarat)
  1147. {
  1148. $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
  1149. $productCollectionFactory = $objectManager->create('\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory');
  1150. $collection = $productCollectionFactory->create();
  1151. $collection->addAttributeToFilter('is_constituent', array('like' => '%1%'));
  1152. $collection->addAttributeToFilter('constituent_type', array('like' => "%$constitute_type_id%"));
  1153. $collection->addAttributeToFilter('gold_color', array('like' => "%$goldColorId%"));
  1154. $collection->addAttributeToFilter('gold_carat', array('like' => "%$goldCaratId%"));
  1155. $collection->addAttributeToSelect('*')->setPageSize(1,1);
  1156. $logger->info('gold collection'.json_encode($collection->getData()));
  1157. $collectionData = $collection->getData();
  1158. if(!empty($collectionData))
  1159. {
  1160. $model = $objectManager->create('Froogal\Catalog\Model\ProductRelationFactory')->create();
  1161. $model->addData([
  1162. "product_id" => $productId,
  1163. "contituent_product_id" => $collectionData[0]['entity_id'],
  1164. "variant_id" => $variantId,
  1165. 'carat' => null,
  1166. "qty" => $goldWeight,
  1167. ]);
  1168. $model->save();
  1169. $logger->info('goldcolor'.$goldColor);
  1170. $logger->info('goldcarat'.$goldCarat);
  1171. }
  1172. // else
  1173. // {
  1174. // throw new LocalizedException(__('constituent product not found!'));
  1175.  
  1176. // }
  1177. }
  1178. }
  1179. }
  1180.  
  1181. }
  1182.  
  1183. }
  1184. }
  1185.  
  1186. public function savePlatinumProductConstituents($product,$variantId,$rowData)
  1187. {
  1188. $writer = new \Zend_Log_Writer_Stream(BP . '/var/log/custom.log');
  1189. $logger = new \Zend_Log();
  1190. $logger->addWriter($writer);
  1191. if (isset($rowData['platinum_weight']) && $rowData['platinum_weight'] > 0) {
  1192. if (empty($rowData['platinum_weight'])) {
  1193. throw new LocalizedException(__('platinum_weight not found!'));
  1194. }
  1195.  
  1196. $productId = $product['product_id'];
  1197. $platinumWeight = $rowData['platinum_weight'];
  1198.  
  1199. $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
  1200. $attribute = $objectManager->create('\Magento\Catalog\Api\ProductAttributeRepositoryInterface');
  1201. $attributeConstituentType= $attribute->get('constituent_type');
  1202. $attributeConstituentTypeId = $attributeConstituentType->getAttributeId();
  1203. $attributeConstituentTypeId = $attributeConstituentType->getAttributeId();
  1204. $attributeconfig = $objectManager->create('\Magento\Eav\Model\Config');
  1205. $attributeType = $attributeconfig->getAttribute('catalog_product', $attributeConstituentTypeId);
  1206. $attributeTypeoptions = $attributeType->getSource()->getAllOptions();
  1207. $constitute_type_id = null;
  1208. foreach($attributeTypeoptions as $type)
  1209. {
  1210. if($type['label'] == "Platinum")
  1211. {
  1212. $constitute_type_id = $type['value'];
  1213. break;
  1214. }
  1215. }
  1216.  
  1217.  
  1218. // $constituentProduct = $objectManager->create('Froogal\Catalog\Model\ProductRelation')->getCollection()->addFieldToFilter('product_id', $productId)->getFirstItem();
  1219.  
  1220.  
  1221. $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
  1222. $productCollectionFactory = $objectManager->create('\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory');
  1223. $collection = $productCollectionFactory->create();
  1224. $collection->addAttributeToFilter('is_constituent', array('like' => '%1%'));
  1225. $collection->addAttributeToFilter('constituent_type', array('like' => "%$constitute_type_id%"));
  1226. $collection->addAttributeToSelect('*')->setPageSize(1,1);
  1227. $logger->info('platinum constituentProduct'.json_encode($collection->getData()));
  1228. $collectionData = $collection->getData();
  1229. if(!empty($collectionData))
  1230. {
  1231. $model = $objectManager->create('Froogal\Catalog\Model\ProductRelationFactory')->create();
  1232.  
  1233. // $model = $productRelationFactory->create(getAllOptionsgetAllOptions);
  1234. $model->addData([
  1235. "product_id" => $productId,
  1236. "contituent_product_id" => $collectionData[0]['entity_id'],
  1237. "variant_id" => $variantId,
  1238. 'carat' => null,
  1239. "qty" => $platinumWeight,
  1240. ]);
  1241. $model->save();
  1242. }
  1243. else
  1244. {
  1245. throw new LocalizedException(
  1246. __('Please enter a correct entity model')
  1247. );
  1248. }
  1249.  
  1250. }
  1251. }
  1252.  
  1253. public function saveDiamondProductConstituents($product, $variantId, $rowData)
  1254. {
  1255. $writer = new \Zend_Log_Writer_Stream(BP . '/var/log/custom.log');
  1256. $logger = new \Zend_Log();
  1257. $logger->addWriter($writer);
  1258.  
  1259. $logger->info('row data elements'.json_encode($rowData));
  1260. if(isset($rowData['diamond_shape']))
  1261. {
  1262.  
  1263. $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
  1264. $attribute = $objectManager->create('\Magento\Catalog\Api\ProductAttributeRepositoryInterface');
  1265. $attributeConstituentType= $attribute->get('constituent_type');
  1266. $attributeShape= $attribute->get('diamond_shape');
  1267. $attributeQuality= $attribute->get('diamond_quality');
  1268. $attributeDiamondSlab= $attribute->get('diamond_slab');
  1269.  
  1270. $attributeConstituentTypeId = $attributeConstituentType->getAttributeId();
  1271. $attributeShapeId = $attributeShape->getAttributeId();
  1272. $attributeQualityId = $attributeQuality->getAttributeId();
  1273. $attributeDiamondSlabId = $attributeDiamondSlab->getAttributeId();
  1274.  
  1275.  
  1276. $attributeconfig = $objectManager->create('\Magento\Eav\Model\Config');
  1277. $attributeType = $attributeconfig->getAttribute('catalog_product', $attributeConstituentTypeId);
  1278. $attributeShape = $attributeconfig->getAttribute('catalog_product', $attributeShapeId);
  1279. $attributeQuality = $attributeconfig->getAttribute('catalog_product', $attributeQualityId);
  1280. $attributeSlab = $attributeconfig->getAttribute('catalog_product', $attributeDiamondSlabId);
  1281.  
  1282. $attributeShapeoptions = $attributeShape->getSource()->getAllOptions();
  1283. $attributeQualityoptions = $attributeQuality->getSource()->getAllOptions();
  1284. $attributeTypeoptions = $attributeType->getSource()->getAllOptions();
  1285. $attributeSlabOptions = $attributeSlab->getSource()->getAllOptions();
  1286.  
  1287. $constitute_type_id = null;
  1288. $slabId=null;
  1289. $carat = null;
  1290. $qty = 0;
  1291. foreach($attributeTypeoptions as $type)
  1292. {
  1293. if($type['label'] == "Diamond")
  1294. {
  1295. $constitute_type_id = $type['value'];
  1296. break;
  1297. }
  1298. }
  1299.  
  1300. if(!empty($rowData))
  1301. {
  1302. $productId = $product['product_id'];
  1303. // $diamondType = $rowData['constituent_type'];
  1304. $shape = $rowData['diamond_shape'];
  1305. // $category = $rowData['diamond_category'];
  1306. $quality = $rowData['diamond_quality'];
  1307. $slab = $rowData['diamond_slab'];
  1308. $carat = $rowData['diamond_carat'];
  1309. $qty = $rowData['diamond_qty'];
  1310.  
  1311.  
  1312.  
  1313.  
  1314. if($attributeSlabOptions)
  1315. {
  1316. foreach($attributeSlabOptions as $slaboption)
  1317. {
  1318. if($slaboption['label'] == $slab)
  1319. {
  1320. $slabId = $slaboption['value'];
  1321. break;
  1322. }
  1323. }
  1324. }
  1325. foreach($attributeShapeoptions as $option)
  1326. {
  1327. $shapeId = $option['value'];
  1328. if($option['label'] == $shape)
  1329. {
  1330. foreach($attributeQualityoptions as $optionvalues)
  1331. {
  1332. $qualityId = $optionvalues['value'];
  1333. if($optionvalues['label'] == $quality)
  1334. {
  1335. $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
  1336. $productCollectionFactory = $objectManager->create('\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory');
  1337. $collection = $productCollectionFactory->create();
  1338. $collection->addAttributeToFilter('is_constituent', array('like' => '%1%'));
  1339. $collection->addAttributeToFilter('constituent_type', array('like' => "%$constitute_type_id%"));
  1340. $collection->addAttributeToFilter('diamond_shape', array('like' => "%$shapeId%"));
  1341. $collection->addAttributeToFilter('diamond_quality', array('like' => "%$qualityId%"));
  1342. $collection->addAttributeToFilter('diamond_slab', array('like' => $slabId));
  1343. $collection->addAttributeToSelect('*')->setPageSize(1,1);
  1344. $collectionData = $collection->getData();
  1345.  
  1346. $logger->info('collection data'.json_encode($collectionData));
  1347.  
  1348. if(!empty($collectionData))
  1349. {
  1350. $model = $objectManager->create('Froogal\Catalog\Model\ProductRelationFactory')->create();
  1351.  
  1352. // $model = $productRelationFactory->create();
  1353. $model->addData([
  1354. "product_id" => $productId,
  1355. "contituent_product_id" => $collectionData[0]['entity_id'],
  1356. "variant_id" => $variantId,
  1357. 'carat' => $carat,
  1358. "qty" => $qty,
  1359. ]);
  1360. $model->save();
  1361. }
  1362. else
  1363. {
  1364. $cproduct = $shape.'_'.$quality.'_'.$slab;
  1365. throw new LocalizedException(__($cproduct.' constituent product not found!'));
  1366.  
  1367. }
  1368.  
  1369.  
  1370.  
  1371.  
  1372. }
  1373.  
  1374. }
  1375.  
  1376.  
  1377.  
  1378.  
  1379.  
  1380. }
  1381.  
  1382.  
  1383.  
  1384. }
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391. }
  1392. }
  1393. }
  1394.  
  1395.  
  1396.  
  1397. // {
  1398. // return $this->productFactoryData->create()->loadByAttribute($field, $value);
  1399. // }
  1400. /**
  1401. * Initialize image array keys.
  1402. *
  1403. * @return $this
  1404. */
  1405. private function initImagesArrayKeys()
  1406. {
  1407. $this->_imagesArrayKeys = $this->imageTypeProcessor->getImageTypes();
  1408. return $this;
  1409. }
  1410.  
  1411. /**
  1412. * Whether a url key is needed to be change.
  1413. *
  1414. * @param array $rowData
  1415. * @return bool
  1416. */
  1417. private function isNeedToChangeUrlKey(array $rowData): bool
  1418. {
  1419. $urlKey = $this->getUrlKey($rowData);
  1420. $productExists = $this->isSkuExist($rowData[self::COL_SKU]);
  1421. $markedToEraseUrlKey = isset($rowData[self::URL_KEY]);
  1422. // The product isn't new and the url key index wasn't marked for change.
  1423. if (!$urlKey && $productExists && !$markedToEraseUrlKey) {
  1424. // Seems there is no need to change the url key
  1425. return false;
  1426. }
  1427.  
  1428. return true;
  1429. }
  1430.  
  1431. /**
  1432. * Get product entity link field
  1433. *
  1434. * @return string
  1435. */
  1436. private function getProductEntityLinkField()
  1437. {
  1438. if (!$this->productEntityLinkField) {
  1439. $this->productEntityLinkField = $this->getMetadataPool()
  1440. ->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class)
  1441. ->getLinkField();
  1442. }
  1443. return $this->productEntityLinkField;
  1444. }
  1445.  
  1446. /**
  1447. * Get product entity identifier field
  1448. *
  1449. * @return string
  1450. */
  1451. private function getProductIdentifierField()
  1452. {
  1453. if (!$this->productEntityIdentifierField) {
  1454. $this->productEntityIdentifierField = $this->getMetadataPool()
  1455. ->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class)
  1456. ->getIdentifierField();
  1457. }
  1458. return $this->productEntityIdentifierField;
  1459. }
  1460.  
  1461. /**
  1462. * Update media gallery labels
  1463. *
  1464. * @param array $labels
  1465. * @return void
  1466. */
  1467. private function updateMediaGalleryLabels(array $labels)
  1468. {
  1469. if (!empty($labels)) {
  1470. $this->mediaProcessor->updateMediaGalleryLabels($labels);
  1471. }
  1472. }
  1473.  
  1474. /**
  1475. * Update 'disabled' field for media gallery entity
  1476. *
  1477. * @param array $images
  1478. * @return $this
  1479. */
  1480. private function updateMediaGalleryVisibility(array $images)
  1481. {
  1482. if (!empty($images)) {
  1483. $this->mediaProcessor->updateMediaGalleryVisibility($images);
  1484. }
  1485.  
  1486. return $this;
  1487. }
  1488.  
  1489. /**
  1490. * Parse values from multiple attributes fields
  1491. *
  1492. * @param string $labelRow
  1493. * @return array
  1494. */
  1495. private function parseMultipleValues($labelRow)
  1496. {
  1497. return $this->parseMultiselectValues(
  1498. $labelRow,
  1499. $this->getMultipleValueSeparator()
  1500. );
  1501. }
  1502.  
  1503. /**
  1504. * Check if product exists for specified SKU
  1505. *
  1506. * @param string $sku
  1507. * @return bool
  1508. */
  1509. private function isSkuExist($sku)
  1510. {
  1511. if ($sku !== null) {
  1512. $sku = strtolower($sku);
  1513. return isset($this->_oldSku[$sku]);
  1514. }
  1515. return false;
  1516. }
  1517.  
  1518. /**
  1519. * Get existing product data for specified SKU
  1520. *
  1521. * @param string $sku
  1522. * @return array
  1523. */
  1524. private function getExistingSku($sku)
  1525. {
  1526. return $this->_oldSku[strtolower($sku)];
  1527. }
  1528.  
  1529. /**
  1530. * Format row data to DB compatible values.
  1531. *
  1532. * @param array $rowData
  1533. * @return array
  1534. */
  1535. private function formatStockDataForRow(array $rowData): array
  1536. {
  1537. $sku = $rowData[self::COL_SKU];
  1538. $row['product_id'] = $this->skuProcessor->getNewSku($sku)['entity_id'];
  1539. $row['website_id'] = $this->stockConfiguration->getDefaultScopeId();
  1540. $row['stock_id'] = $this->stockRegistry->getStock($row['website_id'])->getStockId();
  1541.  
  1542. $stockItemDo = $this->stockRegistry->getStockItem($row['product_id'], $row['website_id']);
  1543. $existStockData = $stockItemDo->getData();
  1544.  
  1545. $row = array_merge(
  1546. $this->defaultStockData,
  1547. array_intersect_key($existStockData, $this->defaultStockData),
  1548. array_intersect_key($rowData, $this->defaultStockData),
  1549. $row
  1550. );
  1551.  
  1552. if ($this->stockConfiguration->isQty($this->skuProcessor->getNewSku($sku)['type_id'])) {
  1553. $stockItemDo->setData($row);
  1554. $row['is_in_stock'] = $this->stockStateProvider->verifyStock($stockItemDo)
  1555. ? (int) $row['is_in_stock']
  1556. : 0;
  1557. if ($this->stockStateProvider->verifyNotification($stockItemDo)) {
  1558. $date = $this->dateTimeFactory->create('now', new \DateTimeZone('UTC'));
  1559. $row['low_stock_date'] = $date->format(DateTime::DATETIME_PHP_FORMAT);
  1560. }
  1561. $row['stock_status_changed_auto'] = (int)!$this->stockStateProvider->verifyStock($stockItemDo);
  1562. } else {
  1563. $row['qty'] = 0;
  1564. }
  1565.  
  1566. return $row;
  1567. }
  1568.  
  1569. /**
  1570. * Retrieve product by sku.
  1571. *
  1572. * @param string $sku
  1573. * @return \Magento\Catalog\Api\Data\ProductInterface|null
  1574. */
  1575. private function retrieveProductBySku($sku)
  1576. {
  1577. try {
  1578. $product = $this->productRepository->get($sku);
  1579. } catch (NoSuchEntityException $e) {
  1580. return null;
  1581. }
  1582. return $product;
  1583. }
  1584.  
  1585. /**
  1586. * Add row as skipped
  1587. *
  1588. * @param int $rowNum
  1589. * @param string $errorCode Error code or simply column name
  1590. * @param string $errorLevel error level
  1591. * @param string|null $colName optional column name
  1592. * @return $this
  1593. */
  1594. private function skipRow(
  1595. $rowNum,
  1596. string $errorCode,
  1597. string $errorLevel = ProcessingError::ERROR_LEVEL_NOT_CRITICAL,
  1598. $colName = null
  1599. ): self {
  1600. $this->addRowError($errorCode, $rowNum, $colName, null, $errorLevel);
  1601. $this->getErrorAggregator()
  1602. ->addRowToSkip($rowNum);
  1603. return $this;
  1604. }
  1605.  
  1606. /**
  1607. * Returns errorLevel for validation
  1608. *
  1609. * @param string $sku
  1610. * @return string
  1611. */
  1612. private function getValidationErrorLevel($sku): string
  1613. {
  1614. return (!$this->isSkuExist($sku) && Import::BEHAVIOR_REPLACE !== $this->getBehavior())
  1615. ? ProcessingError::ERROR_LEVEL_CRITICAL
  1616. : ProcessingError::ERROR_LEVEL_NOT_CRITICAL;
  1617. }
  1618.  
  1619. /**
  1620. * Get row store ID
  1621. *
  1622. * @param array $rowData
  1623. * @return int
  1624. */
  1625. private function getRowStoreId(array $rowData): int
  1626. {
  1627. return !empty($rowData[self::COL_STORE])
  1628. ? (int) $this->getStoreIdByCode($rowData[self::COL_STORE])
  1629. : Store::DEFAULT_STORE_ID;
  1630. }
  1631.  
  1632. /**
  1633. * Get row stock item model
  1634. *
  1635. * @param array $rowData
  1636. * @return StockItemInterface
  1637. */
  1638. private function getRowExistingStockItem(array $rowData): StockItemInterface
  1639. {
  1640. $productId = $this->skuProcessor->getNewSku($rowData[self::COL_SKU])['entity_id'];
  1641. $websiteId = $this->stockConfiguration->getDefaultScopeId();
  1642. return $this->stockRegistry->getStockItem($productId, $websiteId);
  1643. }
  1644.  
  1645. /**
  1646. * Returns image that matches the provided hash
  1647. *
  1648. * @param array $images
  1649. * @param string $hash
  1650. * @return string
  1651. */
  1652. private function findImageByHash(array $images, string $hash): string
  1653. {
  1654. $value = '';
  1655. if ($hash) {
  1656. foreach ($images as $image) {
  1657. if (isset($image['hash']) && $image['hash'] === $hash) {
  1658. $value = $image['value'];
  1659. break;
  1660. }
  1661. }
  1662. }
  1663. return $value;
  1664. }
  1665.  
  1666. /**
  1667. * Returns product media
  1668. *
  1669. * @return string relative path to root folder
  1670. */
  1671. private function getProductMediaPath(): string
  1672. {
  1673. return $this->joinFilePaths($this->getMediaBasePath(), 'catalog', 'product');
  1674. }
  1675.  
  1676. /**
  1677. * Returns media base path
  1678. *
  1679. * @return string relative path to root folder
  1680. */
  1681. private function getMediaBasePath(): string
  1682. {
  1683. $mediaDir = !is_a($this->_mediaDirectory->getDriver(), File::class)
  1684. // make media folder a primary folder for media in external storages
  1685. ? $this->filesystem->getDirectoryReadByPath(DirectoryList::MEDIA)
  1686. : $this->filesystem->getDirectoryRead(DirectoryList::MEDIA);
  1687.  
  1688. return $this->_mediaDirectory->getRelativePath($mediaDir->getAbsolutePath());
  1689. }
  1690.  
  1691. /**
  1692. * Joins two paths and remove redundant directory separator
  1693. *
  1694. * @param array $paths
  1695. * @return string
  1696. */
  1697. private function joinFilePaths(...$paths): string
  1698. {
  1699. $result = '';
  1700. if ($paths) {
  1701. $firstPath = array_shift($paths);
  1702. $result = $firstPath !== null ? rtrim($firstPath, DIRECTORY_SEPARATOR) : '';
  1703. foreach ($paths as $path) {
  1704. $result .= DIRECTORY_SEPARATOR . ltrim($path, DIRECTORY_SEPARATOR);
  1705. }
  1706. }
  1707. return $result;
  1708. }
  1709.  
  1710. /**
  1711. * Reindex stock status for provided product IDs
  1712. *
  1713. * @param array $productIds
  1714. */
  1715. private function reindexStockStatus(array $productIds): void
  1716. {
  1717. if ($productIds) {
  1718. $this->stockProcessor->reindexList($productIds);
  1719. }
  1720. }
  1721.  
  1722. /**
  1723. * Initiate product reindex by product ids
  1724. *
  1725. * @param array $productIdsToReindex
  1726. * @return void
  1727. */
  1728. private function reindexProducts($productIdsToReindex = [])
  1729. {
  1730. $indexer = $this->indexerRegistry->get('catalog_product_category');
  1731. if (is_array($productIdsToReindex) && count($productIdsToReindex) > 0 && !$indexer->isScheduled()) {
  1732. $indexer->reindexList($productIdsToReindex);
  1733. }
  1734. }
  1735.  
  1736.  
  1737.  
  1738. }
  1739.  
Add Comment
Please, Sign In to add comment