Files
kupshop/bundles/KupShop/FeedsBundle/Wrapper/ProductWrapper.php
2025-08-02 16:30:27 +02:00

1022 lines
30 KiB
PHP

<?php
namespace KupShop\FeedsBundle\Wrapper;
use KupShop\CatalogBundle\Util\RelatedProductsUtil;
use KupShop\ConvertorsBundle\Utils\ConvertorsUtil;
use KupShop\FeedsBundle\FeedProductCollection;
use KupShop\FeedsBundle\Utils\FeedUtils;
use KupShop\GraphQLBundle\ApiAdmin\Annotation\Module;
use KupShop\I18nBundle\Util\PriceConverter;
use KupShop\KupShopBundle\Config;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\UnitsBundle\Utils\MeasureUnitUtil;
use Query\Operator;
use Symfony\Contracts\Service\Attribute\Required;
class ProductWrapper extends BaseWrapper
{
protected static $objectType = \Product::class;
/** @var FeedProductCollection */
protected $products;
/**
* @var ProductPriceWithLayersWrapper
*/
protected $productPriceWrapper;
/** @var PriceWrapper */
protected $priceForDiscountWrapper;
/**
* @var PhotoWrapper
*/
protected $photoWrapper;
/**
* @var PhotoWrapper
*/
protected $producerPhotoWrapper;
/** @var SectionWrapper */
protected $sectionWrapper;
/**
* @var DeliveryWrapper
*/
protected $deliveryWrapper;
/** @var MultiWrapper */
protected $sectionsWrapper;
/** @var MultiWrapper */
protected $photosWrapper;
/** @var MultiWrapper */
protected $variationPhotosWrapper;
/** @var MultiWrapper */
protected $giftsWrapper;
protected MultiWrapper $setsWrapper;
/** @var MultiWrapper */
protected $blocksWrapper;
/** @var ObjectMultiWrapper */
protected $pricelistsWrapper;
protected ObjectMultiWrapper $priceLevelsWrapper;
protected ObjectMultiWrapper $templateWrapper;
protected ObjectMultiWrapper $chargeWrapper;
protected ObjectMultiWrapper $labelsWrapper;
protected MultiWrapper $quantityDiscountsWrapper;
/** @var CurrencyContext */
protected $currencyContext;
/** @var PriceConverter */
protected $priceConverter;
protected FeedUtils $feedUtils;
/** @var array */
protected $feedRow;
protected ?ConvertorsUtil $convertorsUtil = null;
protected ?MeasureUnitUtil $measureUnitUtil = null;
protected RelatedProductsUtil $relatedProductsUtil;
public function __construct(
ProductPriceWithLayersWrapper $productPriceWrapper,
PriceWrapper $priceForDiscountWrapper,
PhotoWrapper $photoWrapper,
SectionWrapper $sectionWrapper,
DeliveryWrapper $deliveryWrapper,
CurrencyContext $currencyContext,
PriceConverter $priceConverter,
SectionWrapperFactory $sectionWrapperFactory,
PhotoWrapperFactory $photoWrapperFactory,
GiftWrapperFactory $giftWrapperFactory,
SetWrapperFactory $setWrapperFactory,
BlockWrapper $blockWrapper,
BlockWrapperFactory $blockWrapperFactory,
PricelistWrapperFactory $pricelistWrapperFactory,
PriceLevelsWrapperFactory $priceLevelsWrapperFactory,
TemplateWrapperFactory $templateWrapperFactory,
ChargeWrapperFactory $chargeWrapperFactory,
LabelWrapperFactory $labelWrapperFactory,
QuantityDiscountWrapper $quantityDiscountWrapper,
QuantityDiscountWrapperFactory $quantityDiscountWrapperFactory,
FeedUtils $feedUtils,
) {
$this->productPriceWrapper = $productPriceWrapper;
$this->priceForDiscountWrapper = $priceForDiscountWrapper;
$this->photoWrapper = $photoWrapper;
$this->producerPhotoWrapper = $photoWrapperFactory->create();
$this->sectionWrapper = $sectionWrapper;
$this->deliveryWrapper = $deliveryWrapper;
$this->sectionsWrapper = new MultiWrapper($sectionWrapper, $sectionWrapperFactory);
$this->photosWrapper = new MultiWrapper($photoWrapper, $photoWrapperFactory);
$this->variationPhotosWrapper = new MultiWrapper($photoWrapperFactory->create(), $photoWrapperFactory);
$this->giftsWrapper = new ObjectMultiWrapper($giftWrapperFactory);
$this->setsWrapper = new MultiWrapper($setWrapperFactory->create(), $setWrapperFactory);
$this->currencyContext = $currencyContext;
$this->priceConverter = $priceConverter;
$this->blocksWrapper = new MultiWrapper($blockWrapper, $blockWrapperFactory);
$this->pricelistsWrapper = new ObjectMultiWrapper($pricelistWrapperFactory);
$this->priceLevelsWrapper = new PriceLevelsWrapper($priceLevelsWrapperFactory);
$this->templateWrapper = new ObjectMultiWrapper($templateWrapperFactory);
$this->chargeWrapper = new ObjectMultiWrapper($chargeWrapperFactory);
$this->labelsWrapper = new ObjectMultiWrapper($labelWrapperFactory);
$this->quantityDiscountsWrapper = new MultiWrapper($quantityDiscountWrapper, $quantityDiscountWrapperFactory);
$this->feedUtils = $feedUtils;
}
/**
* @param array|null $feedRow
*
* @private
*/
public function setFeedRow($feedRow)
{
$this->feedRow = $feedRow;
$this->sectionWrapper->setFeedRow($feedRow);
}
/**
* @private
*/
public function setProductCollection(FeedProductCollection $products)
{
$this->products = $products;
}
/**
* @private
*/
#[Required]
public function setConvertorsUtil(?ConvertorsUtil $convertorsUtil): void
{
$this->convertorsUtil = $convertorsUtil;
}
/**
* @private
*/
#[Required]
public function setMeasureUnitUtil(?MeasureUnitUtil $measureUnitUtil): void
{
$this->measureUnitUtil = $measureUnitUtil;
}
/**
* @private
*/
#[Required]
public function setRelatedProductsUtil(RelatedProductsUtil $relatedProductsUtil): void
{
$this->relatedProductsUtil = $relatedProductsUtil;
}
/** @var \Product */
protected $object;
/** SEO */
public function field_seo()
{
$product = $this->object;
return [
'title' => $product->meta_title === '' ? $product->title : $product->meta_title,
'description' => $product->meta_description,
];
}
/**
* @module PRODUCTS_RELATED
*/
public function field_related_products()
{
if (!isset($this->products->_related_products_fetched)) {
$related = $this->relatedProductsUtil->getRelatedProductList($this->products->getProductIds());
$qb = $related->getQueryBuilder()->select('p.title as title, p.ean as ean, p.code as code,
pr.id_top_product, pr.id_rel_product as related_id, pr.position');
if (findModule(\Modules::PRODUCTS_RELATED, \Modules::SUB_TYPES)) {
$qb->addSelect('GROUP_CONCAT(pr.type) as types');
}
$productsArray = $this->products->toArray();
foreach ($qb->execute() as $row) {
$id_top_product = $row['id_top_product'];
unset($row['id_top_product']);
$topProducts = array_filter($productsArray, function ($product) use ($id_top_product) {
return $product->id == $id_top_product;
});
foreach ($topProducts as $topProduct) {
$topProduct->related_products[] = $row;
}
}
$this->products->_related_products_fetched = true;
}
return $this->object->related_products ?? [];
}
/** Název produktu */
public function field_title()
{
return $this->object['fp_title'] ?? $this->object['title'];
}
/** Obecný název produktu */
public function field_title_original()
{
return $this->object['title'];
}
/** Kód hlavního produktu, pod kterým jsou varianty */
public function field_product_code(): ?string
{
return $this->object['product_code'] ?? null;
}
/** Kód produktu / varianty */
public function field_code()
{
return $this->object->code;
}
/** Interní ID produktu */
public function field_id()
{
return $this->object->id;
}
/** Interní ID varianty */
public function field_variation_id()
{
return $this->object->variationId ?? '';
}
/** Jmenovky varianty. */
public function field_variation()
{
$this->products->fetchVariationLabels();
return !empty($this->object->variationLabels) ? $this->object->variationLabels : [];
}
/** CPC */
public function field_cpc()
{
return $this->object['fp_cpc'] ?? $this->object['max_cpc'] ?? '';
}
/** Čas doručení */
public function field_delivery_time()
{
return $this->object->deliveryTime;
}
/** EAN */
public function field_ean()
{
return formatEAN($this->object->ean);
}
/** Hlavní sekce */
public function field_section()
{
$this->products->fetchSections();
$section = $this->object->sections[0] ?? false;
if ($section) {
$section = $this->sectionWrapper->setObject($section);
$section->setProduct($this->object);
}
return $section;
}
/** Všechny sekce */
public function field_sections()
{
$this->products->fetchSections();
$this->sectionsWrapper->setObject($this->object->sections);
return $this->sectionsWrapper;
}
/** Hlavní obrázek */
public function field_main_photo()
{
return ($this->object->image['src'] ?? false) ? $this->photoWrapper->setObject($this->object->image) : null;
}
/** Dodatečné obrázky */
public function field_photos()
{
$this->products->fetchPhotos('default_feed');
$photos = $this->object->photos;
// deduplicate photos
if (findModule(\Modules::PRODUCTS_VARIATIONS_PHOTOS)) {
$tmpPhotos = [];
foreach ($photos as $photo) {
if ($photo['id'] == ($this->object->image['id'] ?? false)) {
continue; // skip main photo
}
$tmpPhotos[$photo['id']] = $photo;
}
// array_values() to reindex photos from 0, otherwise js2php doesn't work properly
$photos = array_values($tmpPhotos);
}
$this->photosWrapper->setObject($photos);
return $this->photosWrapper;
}
/** Dodatečné obrázky variant.
*
* Obsahuje všechny obrázky pro danou variantu produktu nebo pro produkt bez variant. Využijte v případě, že používáte obrázky k variantám.
*
* @module PRODUCTS_VARIATIONS_PHOTOS
*/
public function field_variation_photos()
{
$cfg = Config::get();
// fetch separately by product IDs and assign using product/variation ID (ignore photo type)
if (!isset($this->products->_variation_photos_fetched)) {
$qb = sqlQueryBuilder()->select("CONCAT_WS('/', pp.id_product, pp.id_variation) AS object_id, pp.id_product, pp.id_variation, p.id, p.descr, p.source, p.image_2, pp.show_in_lead, p.date_update")
->from('photos', 'p')
->join('p', 'photos_products_relation', 'pp', 'pp.id_photo=p.id')
->where('pp.active=\'Y\'')
->andWhere(Operator::inIntArray($this->products->getProductIds(), 'pp.id_product'))
->orderBy('pp.id_product, pp.position, pp.id_variation IS NULL, pp.id_variation');
$tmpPhotos = [];
foreach ($qb->execute() as $photo) {
$existing = $tmpPhotos[$photo['id']] ?? [];
$types = $existing['_types'] ?? [];
$types[$photo['show_in_lead']] = $cfg['Photo']['kind'][$photo['show_in_lead']] ?? $photo['show_in_lead'];
$tmpPhotos[$photo['id']] = array_merge(
getImage($photo['id'], $photo['image_2'], $photo['source'], 102, $photo['descr'], strtotime($photo['date_update'])),
[
'show_in_lead' => $photo['show_in_lead'],
'id_variation' => $photo['id_variation'],
'id_product' => $photo['id_product'],
'_types' => $types,
'_variation_ids' => array_unique(array_merge(
$existing['_variation_ids'] ?? [],
!empty($photo['id_variation']) ? [$photo['id_variation']] : []
)),
]
);
}
if (!empty($tmpPhotos)) {
foreach ($this->products as &$product) {
$product->_variation_photos = $product->_variation_photos ?? [];
foreach ($tmpPhotos as $photoID => $photo) {
if ($photo['id_product'] != $product->id) {
continue; // skip other products
}
if (!empty($photo['_variation_ids']) && !in_array($product->variationId, $photo['_variation_ids'])) {
continue; // skip VARIATION photos from other variations (photo has some id_variation, but current variation ID doesn't match)
}
if ($photo['id'] == ($product->image['id'] ?? false)) {
continue; // skip main photo
}
$product->_variation_photos[] = $photo; // index from 0, otherwise js2php doesn't work properly
}
}
}
$this->products->_variation_photos_fetched = true;
}
$this->variationPhotosWrapper->setObject($this->object->_variation_photos ?? []);
return $this->variationPhotosWrapper;
}
/** Cena */
public function field_price(): ProductPriceWithLayersWrapper
{
return $this->productPriceWrapper->setObject($this->object->getProductPrice());
}
/** Cena pro slevu.
*
* @module PRICE_HISTORY
*/
public function field_price_for_discount()
{
if (!isset($this->object->priceForDiscount)) {
return null;
}
return $this->priceForDiscountWrapper->setObject($this->object->priceForDiscount);
}
/** Sleva */
public function field_discount()
{
return $this->object->discount->asFloat();
}
/** Nákupní cena.
*
* (bez DPH)
*
* @module PRODUCTS__PRICE_BUY
*/
public function field_price_buy()
{
return \Decimal::ensureDecimal($this->object['price_buy']['value_without_vat'] ?? 0)->asFloat();
}
/** Skrtlá cena.
* @module PRODUCTS__PRICE_COMMON
*/
public function field_price_common()
{
return \Decimal::ensureDecimal($this->object['priceCommon']['value_with_vat'] ?? 0)->asFloat();
}
/** Pole aktivních kampaní u produktu. Indexované podle kódu kampaně. */
public function field_campaigns()
{
return $this->object->campaign_codes;
}
/** URL adresa detailu produkt */
public function field_url()
{
return createScriptURL([
's' => 'product',
'IDproduct' => $this->object->id,
'TITLE' => $this->object->title,
'absolute' => true,
]);
}
/** Počet kusů skladem */
public function field_in_store(): int
{
return $this->object->inStore ?? 0;
}
/** Reálný počet kusů skladem.
*
* Počet bez omezení hodnotou "Zobrazit max."
*
* @module PRODUCTS__SHOW_MAX
*/
public function field_in_store_real(): int
{
if (!isset($this->products->_in_store_real_fetched)) {
$qb = sqlQueryBuilder()->select("CONCAT_WS('/', p.id, pv.id) AS id, COALESCE(pv.in_store, p.in_store) AS in_store")->from('products', 'p')
->joinVariationsOnProducts()
->where(Operator::inIntArray($this->products->getProductIds(), 'p.id'))
->groupBy('p.id, pv.id')
->orderBy('p.id, pv.id');
foreach ($qb->execute() as $row) {
if (isset($this->products[$row['id']])) {
$this->products[$row['id']]->_in_store_real = $row['in_store'];
}
}
$this->products->_in_store_real_fetched = true;
}
return $this->object->_in_store_real ?? 0;
}
/**
* @module CONVERTORS
*/
public function field_convertors()
{
if (!isset($this->products->_convertors_fetched)) {
$qb = $this->convertorsUtil->getConvertorsQueryBuilder($this->products->getProductIds(), showHiddenVariations: true)
->select("CONCAT_WS('/', pv.id_product, pv.id) id, cdp.name param_name, pl.value param_value, pvcv.value label_value, cd.name convertor_name, cd.id id_convertor, pl.id_parameter");
foreach ($qb->execute() as $row) {
if (isset($this->products[$row['id']])) {
if (!isset($this->products[$row['id']]->convertors)) {
$this->products[$row['id']]->convertors = [];
}
if (!isset($this->products[$row['id']]->convertors[$row['id_convertor']])) {
$this->products[$row['id']]->convertors[$row['id_convertor']] = [
'name' => $row['convertor_name'],
'parameters' => [],
];
}
if (!isset($this->products[$row['id']]->convertors[$row['id_convertor']]['parameters'][$row['id_parameter']])) {
$this->products[$row['id']]->convertors[$row['id_convertor']]['parameters'][$row['id_parameter']]['name'] = $row['param_name'];
}
$this->products[$row['id']]->convertors[$row['id_convertor']]['parameters'][$row['id_parameter']]['values'][] = $row['param_value'];
}
}
$this->products->_convertors_fetched = true;
}
return $this->object->convertors ?? [];
}
/**
* Měrné jednotky.
*
* @module PRODUCTS__UNITS
*/
public function field_measure_unit()
{
$this->products->fetchMeasureUnits();
if (empty($this->object->measureUnits)) {
return [];
}
$data = $this->object->measureUnits[array_key_first($this->object->measureUnits)] ?? null;
if ($this->object->variationId) {
$data = $this->object->measureUnits[$this->object->variationId] ?? null;
}
$result = $this->measureUnitUtil->calculatePriceUnit($this->object->getProductPrice(), $data);
if (!$result) {
return [];
}
$result['price'] = $result['price']->getPriceWithVat()->asFloat();
if (isset($result['price_without_discount'])) {
$result['price_without_discount'] = $result['price_without_discount']->getPriceWithVat()->asFloat();
}
return $result;
}
/**
* Počet kusů skladem u dodavatele.
*
* @module PRODUCTS_SUPPLIERS
*/
public function field_in_store_suppliers(): int
{
$this->products->fetchProductOfSuppliersInStore();
return $this->object->in_store_suppliers_original ?? 0;
}
/**
* Dodavatelé.
*
* @module SUPPLIERS
*/
public function field_suppliers(): array
{
$this->products->fetchSuppliers();
return $this->object->suppliers ?? [];
}
/**
* Minimální počet kusů skladem.
*
* @module MISSING_PRODUCTS
*/
public function field_in_store_min(): int
{
return $this->object->in_store_min ?? 0;
}
/** Počet kusů v jednotlivých skladech.
* @module STORES
*/
public function field_stores()
{
$this->products->fetchStoresInStore();
return !empty($this->object->storesInStore) ? $this->object->storesInStore : [];
}
/**
* Výrobce.
*
* title - název výrobce
* photo - url fotky výrobce.
* qpsr - GPSR kontaktní údaje
*/
public function field_producer()
{
$this->products->fetchProducers();
if (!isset($this->object->producer['id'])) {
return false;
}
$producer = $this->object->producer;
$photo = $producer['image'] ?? false;
if ($photo) {
$photo = $this->producerPhotoWrapper->setObject($producer['image']);
}
$data = [
'title' => $producer['title'],
'photo' => $photo,
];
if (isset($producer['import_company_name'])) {
$data['gpsr'] = [
'name' => $producer['import_company_name'],
'street' => $producer['import_company_street'],
'city' => $producer['import_company_city'],
'zip' => $producer['import_company_zip'],
'country' => $producer['import_company_country'],
'email' => $producer['import_company_email'],
'web' => $producer['import_company_web'],
];
} else {
$data['gpsr'] = [
'name' => $producer['company_name'],
'street' => $producer['company_street'],
'city' => $producer['company_city'],
'zip' => $producer['company_zip'],
'country' => $producer['company_country'],
'email' => $producer['company_email'],
'web' => $producer['company_web'],
];
}
return $data;
}
/** Anotace produktu */
public function field_annotation()
{
return $this->object->descr;
}
/** Popis produktu */
public function field_description()
{
return $this->object->longDescr;
}
/** Rozšiřující popis produktu */
public function field_extended_description()
{
return $this->object->parameters;
}
/** Doprava */
public function field_delivery()
{
return $this->deliveryWrapper->setObject($this->object);
}
/** Seznam doprav */
public function field_deliveries()
{
$this->deliveryWrapper->setObject($this->object);
return $this->deliveryWrapper->getDeliveryWrappers();
}
/** Seznam všech doprav bez omezení */
public function field_deliveries_all()
{
$this->deliveryWrapper->setObject($this->object);
return $this->deliveryWrapper->getDeliveryWrappers(false, true);
}
/**
* Parametry.
*/
public function field_params()
{
$this->products->fetchParameters();
if (!isset($this->object->param_feeds)) {
$this->object->param_feeds = array_map(function ($param) {
return [
'name' => $param['name'],
'value' => $param['value'],
'unit' => $param['unit'],
'value_type' => $param['value_type'],
'value_id' => $param['value_id'],
'value_desc' => $param['description'],
'values' => array_map(function ($value) {
return [
'id' => $value['id'] ?? null,
'name' => $value['value'],
'desc' => $value['descr'] ?? '',
'unit' => $value['unit'],
'weight' => $value['weight'] ?? null,
];
}, $param['values']),
];
}, $this->object->param);
}
return $this->object->param_feeds;
}
/** Hmotnost */
public function field_weight()
{
return $this->object->weight ?? '';
}
/** Odkazy */
public function field_links()
{
$this->products->fetchLinks();
return $this->object->links;
}
/**
* Dárky.
*
* @module PRODUCT_GIFTS
*/
public function field_gifts()
{
$this->products->fetchGifts();
$this->giftsWrapper->setObjects($this->object->gifts ?? []);
$tmp = [];
foreach ($this->giftsWrapper as $key => $value) {
$tmp[$key] = $value;
}
return $this->giftsWrapper->getAsArray();
}
/**
* Sety.
*
* @module PRODUCT_SETS
*/
public function field_sets()
{
if (isset($this->feedRow['id'])) {
$this->products->fetchSets();
}
$this->setsWrapper->setObject($this->object->sets ?? []);
return $this->setsWrapper;
}
/**
* Množstevní slevy.
*
* pieces - počet kusů, od kterých začíná sleva
* discount - sleva
*
* @module QUANTITY_DISCOUNT
*/
public function field_quantity_discounts()
{
$this->products->fetchQuantityDiscounts();
$this->quantityDiscountsWrapper->setObject($this->object->quantityDiscounts ?? []);
return $this->quantityDiscountsWrapper;
}
/** Záruka */
public function field_guarantee()
{
return $this->object->guarantee ?? 24;
}
/** Datum vytvoření */
public function field_date_added()
{
return $this->object->date_added ?? '';
}
/**
* Datum naskladnění.
*
* Použití kompatibilní s V8: typeof date_stock_in.format === 'function' ? date_stock_in.format('Y-m-d\\TH:i:s') : (typeof date_stock_in.toISOString === 'function' ? date_stock_in.toISOString().substring(0, 19) : date_stock_in)
*
* @module STOCK_IN
*/
public function field_date_stock_in(): ?\DateTime
{
// legacy support: typeof date_stock_in.format === 'function' ? date_stock_in.format('Y-m-d H:i:s') : (typeof date_stock_in.toISOString === 'function' ? date_stock_in.toISOString().replace('T', ' ').substring(0, 19) : date_stock_in)
return $this->object->date_stock_in ?? null;
}
/** Viditelnost zboží.
*
* Y - Viditelné
* N - Skryté
* O - Prodej ukončen
*/
public function field_visibility()
{
return $this->object->visible ?? '';
}
/** Viditelnost varianty.
*
* Y - Viditelné
* N - Skryté
*/
public function field_variation_visibility(): ?string
{
return $this->object->variationVisible ?? null;
}
/**
* Šablony produktů.
*
* @module TEMPLATES
*/
public function field_templates()
{
$this->products->fetchTemplates();
return !empty($this->object->templates) ? $this->templateWrapper->setObjects($this->object->templates)->getAsArray() : [];
}
/**
* Bloky (obsah).
*
* @module PRODUCTS__DESCR_PLUS
*/
public function field_blocks()
{
$this->feedUtils->fetchCollectionBlocks($this->products);
return !empty($this->object->_raw_blocks) ? $this->blocksWrapper->setObject($this->object->_raw_blocks) : [];
}
/**
* Ceníky.
*
* @module PRICELISTS
*/
public function field_pricelists()
{
$this->products->fetchPricelists();
return $this->pricelistsWrapper->setObjects($this->object->pricelists ?? [])->getAsArray();
}
/**
* Cenové hladiny.
*
* @module PRICE_LEVELS
*/
public function field_price_levels()
{
$this->products->fetchSections();
return $this->priceLevelsWrapper->setProduct($this->object)->getAsArray();
}
/** Rozměry zboží.
*
* width - šířka
* height - výška
* depth - hloubka
*/
public function field_dimensions()
{
$dimensions = [];
if (!empty($this->object->width)) {
$dimensions['width'] = (float) $this->object->width;
}
if (!empty($this->object->height)) {
$dimensions['height'] = (float) $this->object->height;
}
if (!empty($this->object->depth)) {
$dimensions['depth'] = (float) $this->object->depth;
}
return $dimensions;
}
/**
* Příplatky.
*
* @module PRODUCTS_CHARGES
*/
public function field_charges()
{
$this->products->fetchCharges();
return !empty($this->object->charges) ? $this->chargeWrapper->setObjects($this->object->charges)->getAsArray() : [];
}
/**
* Přílohy k produktu.
*
* link - odkaz
* title - název
* position - pozice
*
* @module ATTACHMENTS
*/
public function field_attachments(): array
{
$this->products->fetchAttachments();
return $this->object->attachments ?? [];
}
/**
* Štítky produktu.
*
* @module LABELS
*/
public function field_labels(): array
{
$this->products->fetchProductLabels('all');
return $this->labelsWrapper->setObjects($this->object->labels ?? [])->getAsArray();
}
/**
* Hlavní produkt kolekcí.
*
* id - id hlavního produktu
* code - kod hlavního produktu
*
* @module PRODUCTS_COLLECTIONS
*/
public function field_collection_master_products(): array
{
// nactu produkty v jejichz kolekcich se produkt nachazi
$othersCollections = $this->object->fetchCollections()['others'] ?? [];
$masterProducts = [];
foreach ($othersCollections as $key => $item) {
$masterProducts[$key] = [
'id' => $item->id,
'code' => $item->code,
];
}
return $masterProducts;
}
/**
* @module PRODUCT_RESERVATIONS
*/
public function field_reservations(): array
{
$this->products->fetchReservations();
return [
'total' => array_sum(array_map(fn ($x) => $x['quantity'], $this->object->reservations ?? [])),
'items' => $this->object->reservations ?? [],
];
}
/**
* Recyklační příspěvek.
*
* @module PRODUCTS__RECYCLING_FEE
*/
public function field_recycling_fee(): ?float
{
if ($recyclingFee = ($this->object->getData()['recycling_fee'] ?? null)) {
return (float) $recyclingFee;
}
return null;
}
/**
* OSS kód.
*
* @module OSS_VATS
*/
public function field_vat_cn_code(): ?int
{
return $this->object->id_cn;
}
/**
* Poznámka na produktu.
*
* @module PRODUCTS__NOTE
*/
public function field_note(): ?string
{
return $this->object->note_;
}
}