true]; public function __construct() { $this->adminSectionTree = ServiceContainer::getService(AdminSectionTree::class); } public function get_vars() { $cfg = \KupShop\KupShopBundle\Config::get(); $vars = parent::get_vars(); $ID = $this->getID(); $pageVars = getVal('body', $vars, []); $pageVars['vats'] = VatContext::getAdminVats(); // backward compatibility if (!isset($pageVars['vats'][$pageVars['data']['vat']])) { $pageVars['vats'][$pageVars['data']['vat']] = VatContext::getAdminVats(true)[$pageVars['data']['vat']]; } if (findModule(Modules::PRODUCTS, Modules::SUB_UNITS)) { $qb = sqlQueryBuilder()->select('id, short_name_admin')->from('products_units') ->orderBy('id'); if (findModule(Modules::PRODUCTS, Modules::SUB_UNITS_FLOAT)) { $qb->addSelect('pieces_precision'); } foreach ($qb->execute() as $units) { $pageVars['units'][$units['id']] = $units['short_name_admin']; if (findModule(Modules::PRODUCTS, Modules::SUB_UNITS_FLOAT)) { $pageVars['units_pieces_precision'][$units['id']] = $units['pieces_precision']; } } } if (findModule(Modules::PRODUCTS_CHARGES)) { $SQL = sqlQuery('SELECT *, IF(admin_title!="", admin_title, title) as title FROM charges WHERE type="product" ORDER BY id ASC '); $pageVars['charges'] = sqlFetchAll($SQL, ['id' => 'title']); } if (!empty($pageVars['data']['producer'])) { $pageVars['producer'] = $this->selectSQL('producers', ['id' => $pageVars['data']['producer']], ['name'])->fetch(); } $pageVars['POSITION_FIRST'] = POSITION_FIRST; $pageVars['POSITION_LAST'] = POSITION_LAST; $pageVars['positions'] = [POSITION_FIRST => 'Vpředu', '' => 'Standardní řazení', POSITION_LAST => 'Vzadu', '-1' => 'Konkrétní pozice']; $pageVars['parameters'] = []; // missing parameters $productSections = array_keys(sqlFetchAll($this->selectSQL('products_in_sections', ['id_product' => $ID]), 'id_section')); $sectionsMissingParameters = 0; $producersMissingParameters = 0; $sectionsRequiredParameters = []; $producersRequiredParameters = []; if (!empty($productSections)) { $sectionsRequiredParameters = sqlFetchAll( sqlQueryBuilder() ->select('id_parameter') ->from('parameters_sections') ->where(\Query\Operator::inIntArray($productSections, 'id_section')) ->andWhere(Operator::equals(['required' => 'Y'])) ->groupBy('id_parameter') ->execute(), 'id_parameter' ); $qb = sqlQueryBuilder()->select('('.count($sectionsRequiredParameters).' - COUNT(DISTINCT id_parameter))') ->from('parameters_products') ->where(\Query\Operator::inIntArray(array_keys($sectionsRequiredParameters), 'id_parameter')) ->andWhere(\Query\Operator::equals(['id_product' => $ID])) ->execute(); $sectionsMissingParameters = $qb->fetchColumn(); } if (findModule(Modules::PRODUCERS) && !empty($pageVars['data']['producer'])) { $producersRequiredParameters = sqlFetchAll( sqlQueryBuilder() ->select('id_parameter') ->from('parameters_producers') ->where(\Query\Operator::equals(['id_producer' => $pageVars['data']['producer']])) ->groupBy('id_parameter') ->execute(), 'id_parameter' ); $producersMissingParameters = sqlQueryBuilder()->select('('.count($producersRequiredParameters).' - COUNT(DISTINCT id_parameter))') ->from('parameters_products') ->where(\Query\Operator::inIntArray(array_keys($producersRequiredParameters), 'id_parameter')) ->andWhere(\Query\Operator::equals(['id_product' => $ID])) ->execute()->fetchColumn(); } $missingParameters = max(0, $producersMissingParameters + $sectionsMissingParameters); $pageVars['missingParameters'] = [ 'count' => $missingParameters, 'required' => !empty($sectionsRequiredParameters) || !empty($producersRequiredParameters), ]; if (!empty($ID)) { if (findModule('links')) { $SQL = sqlQueryBuilder()->select('*') ->from('links', 'pis') ->where(Operator::equals(['id_product' => $ID])) ->execute(); $pageVars['links'] = []; foreach ($SQL as $key => $row) { $pageVars['links'][$key] = $row; } } if (findModule('attachments')) { $SQL = sqlQueryBuilder()->select('*') ->from('attachments') ->where(\Query\Operator::equals(['id_product' => $ID])) ->orderBy('position', 'ASC') ->execute(); $pageVars['attachments'] = []; foreach ($SQL as $key => $row) { $pageVars['attachments'][$key] = $row; } } if (findModule('photos')) { $product_photos = sqlQueryBuilder()->select('*') ->from('photos_products_relation') ->where(\Query\Operator::equals(['id_product' => $ID])) ->execute()->fetchAll(); $pageVars['product_photos'] = $product_photos; } $product = new Product($ID); $pageVars['sets'] = $product->fetchSets(true); foreach ($pageVars['sets'] as &$set) { $set->fetchImages('admin'); $set->fetchVariations(); $variations = false; if (!empty($set['variations']['variations'])) { $variations = []; foreach ($set['variations']['variations'] as $variation) { $selected = false; if ($variation['id'] == $set['selected_variation']) { $selected = true; } $variations[] = ['label' => $variation['title'], 'value' => $variation['id'], 'selected' => $selected]; } } $set['variations'] = $variations; } if (findModule(\Modules::PRODUCTS_COLLECTIONS)) { $pageVars['collections'] = $product->fetchCollections(false); if (!empty($pageVars['collections']['own'])) { foreach ($pageVars['collections']['own'] as &$collection) { $collection->fetchImages('admin'); } } } if (findModule(Modules::PRODUCTS_CHARGES)) { // Příplatky $pageVars['data']['products_charges'] = $product->fetchCharges(onlyVisible: false); } $variations = sqlFetchAssoc(sqlQuery('SELECT COUNT(*) AS cnt, MAX(price) price FROM products_variations WHERE id_product=:id', ['id' => $ID])); $pageVars['variationCount'] = $variations['cnt']; $pageVars['variationPrice'] = $variations['price']; $pageVars['piecesOrdered'] = returnSQLResult('SELECT SUM(oi.pieces) FROM '.getTableName('order_items').' oi LEFT JOIN '.getTableName('orders')." o ON oi.id_order=o.id WHERE oi.id_product={$ID} AND o.status_storno=0 AND o.status IN (".join(',', getStatuses('notpacked')).')'); $pageVars['data']['in_store'] = floatval($pageVars['data']['in_store']); $pageVars['product'] = $product; } $dbcfg = Settings::getDefault(); $pageVars['data']['priceWithVat'] = $dbcfg['prod_prefer_price_vat'] == 'Y' || $dbcfg['prod_prefer_price_vat'] == 'F'; if ($pageVars['data']['priceWithVat'] && !empty($pageVars['data']['vat'])) { $pageVars['data']['price'] = calcPrice($pageVars['data']['price'], $pageVars['vats'][$pageVars['data']['vat']]['vat']); } else { $pageVars['data']['price'] = toDecimal($pageVars['data']['price']); } $pageVars['data']['discount'] = \Decimal::create($pageVars['data']['discount'], 8); $pageVars['data']['campaigns'] = explodeFlags($pageVars['data']['campaign']); $pageVars['tree'] = $this->adminSectionTree->getCategories(); $pageVars['selected'] = ($this->getID() ? $this->adminSectionTree->getSelected($this->getID(), 'products_in_sections', 'id_product') : []); $this->adminSectionTree->getOpened($pageVars['tree']); $pageVars['opened'] = $this->adminSectionTree->opened; $pageVars['disabled'] = $this->getDisabledSections(); if (findModule(Modules::PRICE_HISTORY) && !empty($pageVars['data']['price_for_discount'])) { $pageVars['data']['price_for_discount'] = toDecimal($pageVars['data']['price_for_discount']); } if ($this->isDuplicate()) { $pageVars['data']['code'] = $this->generateCode(); $pageVars['data']['pieces_sold'] = 0; $pageVars['data']['ean'] = ''; $pageVars['data']['price_for_discount'] = null; } if (findModule('templates')) { $categories = sqlQuery('SELECT CONCAT_WS(" - ", tc.name, t.name) name, t.id FROM '.getTableName('templates').' t LEFT JOIN '.getTableName('templates_categories').' tc ON t.id_category = tc.id ORDER BY tc.position, t.position, t.name'); $pageVars['templates'] = array_map(function ($x) { return $x['name']; }, sqlFetchAll($categories, 'id')); $pageVars['data']['templates'] = sqlFetchAll(sqlQueryBuilder() ->select('tp.id_template')->from('templates_products', 'tp') ->leftJoin('tp', 'templates', 't', 't.id=tp.id_template') ->leftJoin('t', 'templates_categories', 'tc', 'tc.id=t.id_category') ->where(Operator::equals(['tp.id_product' => $ID])) ->orderBy('tc.position')->addOrderBy('t.position')->addOrderBy('t.name') ->execute(), 'id_template'); } if (findModule(Modules::OSS_VATS)) { $ossSettings = \Settings::getDefault()['oss_vats'] ?? []; $ossIdCN = !empty($pageVars['data']['id_cn']) ? $pageVars['data']['id_cn'] : ($ossSettings['default'] ?? false); $ossCountryID = !empty($ossSettings['homeCountry']) ? $ossSettings['homeCountry'] : 'CZ'; if (!empty($ossIdCN)) { $pageVars['data']['selected_oss_vat'] = sqlQueryBuilder()->select('vc.id_vat, v.descr') ->from('vats_cns', 'vc') ->innerJoin('vc', 'vats', 'v', 'v.id=vc.id_vat AND v.id_country=:country') ->setParameter('country', $ossCountryID) ->where(Operator::equals(['id_cn' => $ossIdCN])) ->execute()->fetchAllAssociative(); $pageVars['data']['oss_vat'] = $pageVars['data']['selected_oss_vat'][0]['id_vat'] ?? null; } else { $pageVars['data']['oss_vat'] = sqlQueryBuilder()->select('id') ->from('vats')->setParameter('country', $ossCountryID) ->where(Operator::equals([ 'automanaged' => 1, 'is_default' => 'Y', 'id_country' => $ossCountryID, ])) ->execute()->fetchColumn(); } } if (findModule(Modules::LABELS, Modules::SUB_PRODUCT_LABELS)) { $pageVars['data']['product_labels'] = sqlQueryBuilder() ->select('l.id, COALESCE(l.name_admin, l.name) as name, l.short_name, plr.generated, plr.id_label, plr.id_product') ->from('labels', 'l') ->leftJoin('l', 'product_labels_relation', 'plr', 'l.id = plr.id_label AND plr.id_product = :idProduct') ->setParameter('idProduct', $ID) ->orderBy('l.name') ->execute() ->fetchAllAssociative(); } $this->unserializeCustomData($pageVars['data']); $vars['body'] = $pageVars; return $vars; } public function handleDeleteAttach() { $IDa = getVal('IDa'); sqlQuery('DELETE FROM '.getTableName('attachments')." WHERE id='".$IDa."' "); $this->returnOK(); } public function handleDeleteLink() { $IDl = getVal('IDl'); sqlQuery('DELETE FROM '.getTableName('links')." WHERE id='".$IDl."' "); $this->returnOK(); } public function handleFindCode() { $code = getVal('code'); $this->setID(returnSQLResult('SELECT id FROM products WHERE code=:code', ['code' => $code])); $this->redirect(); } public function getData() { $cfg = Config::get(); $data = parent::getData(); $acn = $this->getAction(); $ID = $this->getID(); if (getVal('Submit')) { if (isset($data['delivery_time']) && $data['delivery_time'] == 1) { $data['delivery_time'] = $data['deliveryTimeDays']; } if (empty($data['price_common'])) { $data['price_common'] = '0'; } if ($data['position'] == '-1') { if (is_numeric($data['position_abs'])) { $data['position'] = intval($data['position_abs']); } else { $data['position'] = null; } } if ($data['code'] == '') { $data['code'] = null; } else { if (findModule('products_variations', 'variationCode')) { $uniqueCode = Variations::makeCodeUnique(0, $data['code'], $ID); if ($uniqueCode != $data['code']) { $this->addError("Kód {$data['code']} není unikátní a byl změněn na {$uniqueCode}!"); } $data['code'] = $uniqueCode; } } if (!empty($data['price_buy'])) { $data['price_buy'] = $this->prepareVatPrice($data['price_buy']); } if (!empty($data['date_added'])) { $data['date_added'] = DateTime::createFromFormat('d.m.Y H:i:s', $data['date_added'])->format('Y-m-d H:i:s'); } if (!empty($data['date_stock_in'])) { $data['date_stock_in'] = DateTime::createFromFormat('d.m.Y H:i:s', $data['date_stock_in'])->format('Y-m-d H:i:s'); } if (!empty($data['ean'])) { $data['ean'] = StringUtil::unicode_trim($data['ean']); if (Settings::getDefault()->admin_ean_check === 'Y' && !EANValidator::checkEAN($data['ean']) ) { $this->addHTMLError("EAN {$data['ean']} není validní."); } $exists = Variations::eanExists(0, $data['ean'], $ID); if ($exists) { $this->updateSQL('products', ['ean' => null], ['id' => $ID]); $message = Variations::eanExistsMessage($exists); $this->addHTMLError($message); // EAN {ean} není unikátní. {odkaz na duplicitní produkt} } } if (!findRight('PROD_STOCK')) { $data['inStoreOverride'] = false; } if (!getVal('inStoreOverride', $data)) { unset($data['in_store']); } // Campaign $campaign = []; foreach ($GLOBALS['cfg']['Products']['Flags'] as $flag => $name) { if (getVal("camp{$flag}", $data) == 'ON') { $campaign[] = $flag; } } $data['campaign'] = join(',', $campaign); // uprava desetinnych znamenek $data['price'] = str_replace(',', '.', $data['price']); $data['price_common'] = str_replace(',', '.', $data['price_common']); // $data['discount'] = str_replace(',', '.', $data['discount']); $data['max_cpc'] = str_replace(',', '.', $data['max_cpc']); if (!empty($data['weight'])) { $data['weight'] = str_replace(',', '.', $data['weight']); } if (empty($data['discount'])) { $data['discount'] = 0; } if (findModule('seo')) { if (empty($data['meta_title_changed'])) { $data['meta_title'] = ''; } } if (findModule(Modules::OSS_VATS) && !empty($data['id_cn'])) { ServiceContainer::getService(\KupShop\OSSVatsBundle\Util\VatsUtil::class)->refreshVatsCnsRelations([$data['id_cn']]); } if ($acn == 'add') { if (getVal('ID') && $this->isDuplicate() && getVal('ignoreFlagNews')) { $dbcfg = Settings::getDefault(); try { $date_added = new DateTime(); $date_added->sub(new DateInterval('P'.($dbcfg->prod_flag_automatic_new + 1).'D')); $data['date_added'] = $date_added->format('Y-m-d H:i'); } catch (Exception $e) { } } else { $data['date_added'] = date('Y-m-d H:i'); } } $data['data'] = array_merge($this->getCustomData(), $data['data'] ?? []); $this->serializeCustomData($data); } if (($acn == 'add') && !getVal('Submit')) { $data['code'] = $this->generateCode(); $data['ean'] = ''; $data['price'] = '0'; $data['price_for_discount'] = null; $data['discount'] = '0'; $data['vat'] = $data['vat'] ?? getAdminVat()['id']; $data['guarantee'] = '24'; $data['in_store'] = '0'; $data['pieces_sold'] = '0'; $data['delivery_time'] = array_key_first($cfg['Products']['DeliveryTime'] ?? []); // -1; $data['campaign'] = ''; $data['showInLead'] = 'Y'; $data['figure'] = 'Y'; $data['max_cpc'] = 0; $data['show_in_feed'] = 'Y'; $data['show_in_search'] = 'Y'; $data['serial_number_require'] = 'N'; $data['showRawPrince'] = 'N'; $data['in_store_show_max'] = null; $data['position'] = null; $data['price_common'] = 0; $data['data'] = null; } $vatContext = Contexts::get(VatContext::class); $data['vatValue'] = $vatContext->getVat($data['vat'])['vat'] ?? 0; if (getVal('Submit')) { if ($data['priceWithVat']) { try { $data['price'] = calcPrice($data['price'], -$data['vatValue']); } catch (InvalidArgumentException $e) { $this->returnError('Špatný formát ceny!'); } } if (!empty($data['price_for_discount'])) { $data['price_for_discount'] = $this->prepareVatPrice(['value' => $data['price_for_discount'], 'vat' => $data['vatValue']]); } } return $data; } public function generateCode() { if (findModule(Modules::PRODUCTS, Modules::SUB_DONT_GENERATE_CODE)) { return ''; } $code = ''; $strAlpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; for ($i = 0; $i < 5; $i++) { if ($i < 2) { $code .= $strAlpha[rand(0, strlen($strAlpha) - 1)]; } if ($i >= 2) { $code .= rand(0, 9); } } return $code; } public function handleUpdate() { $acn = $this->getAction(); if ($acn == 'edit' && !findRight('PROD_EDIT')) { redirect('launch.php?s=error.php&id=1'); } if ($acn == 'add' && !findRight('PROD_ADD')) { redirect('launch.php?s=error.php&id=1'); } $oldInStore = $this->getObject()['in_store'] ?? 0; parent::handleUpdate(); $ID = $this->getID(); $data = $this->getData(); $duplicate = $this->isDuplicate(); // zalogovat, ze byla rucne zmenena skladovost if (($data['inStoreOverride'] ?? false) && ($data['in_store'] ?? false) !== false) { addActivityLog( ActivityLog::SEVERITY_NOTICE, ActivityLog::TYPE_CHANGE, sprintf( translate('activityEdited', 'products'), $this->getID(), sprintf(translate('activityInStoreEdited', 'products'), $oldInStore, $data['in_store']) ) ); } global $dbcfg, $cfg; if (!empty($dbcfg['prod_flag_automatic_new']) && !empty($cfg['Products']['Flags']['N'])) { Product::automaticUpdateFlagForNewProducts($ID); } $ID = $this->getID(); // ############################################ // # ZAPSANI ODKAZU $links = getVal('links', $data, []); foreach ($links as $id => $link) { $link['id'] = intval($link['id']); $link['id_product'] = $ID; if ($duplicate && $id > 0) { unset($link['id']); $id = -99; } if (!empty($link['delete']) || !$id || !$link['link']) { if ($id > 0) { $this->deleteSQL('links', ['id' => $link['id']]); } continue; } if ($id < 0) { $this->insertSQL('links', $link); } else { $this->updateSQL('links', $link, ['id' => $link['id']]); } } // ############################################ // # ZAPSANI PRILOH $attach = getVal('attach', $data, []); foreach ($attach as $id => $att) { $att['id'] = intval($att['id']); $att['id_product'] = $ID; if ($duplicate && $id > 0) { unset($att['id']); $id = -99; } if (!empty($att['delete']) || !$id || !$att['link']) { if ($id > 0) { $this->deleteSQL('attachments', ['id' => $att['id']]); } continue; } if (isset($att['title']) && empty($att['title']) && !empty($att['link'])) { $att['title'] = basename($att['link']); } if ($id < 0) { $this->insertSQL('attachments', $att); } else { $this->updateSQL('attachments', $att, ['id' => $att['id']]); } } // ############################################ // # ZAPSANI SETU $sets = getVal('sets', $data, []); foreach ($sets as $id => $set) { $set['id_product_set'] = intval($set['id_product_set']); $set['id_product'] = $ID; if (empty($set['id_variation'])) { $set['id_variation'] = null; } $this->prepareNull($set['price']); if (!empty($set['price'])) { $setProductVatId = sqlQueryBuilder() ->select('vat') ->from('products') ->where(Operator::equals(['id' => $set['id_product_set']])) ->execute()->fetchOne(); $set['price'] = toDecimal($set['price'])->removeVat(getVat($setProductVatId)); } if (!ctype_digit($set['pieces']) || $set['pieces'] < 1) { $set['pieces'] = 1; } if ($duplicate && $id > 0) { $id = -99; } if (!empty($set['delete']) || !$id || $set['id_product_set'] <= 0) { if ($id > 0) { $this->deleteSQL('products_sets', ['id' => $set['id']]); } continue; } if ($id < 0) { $this->insertSQL('products_sets', $set); } else { $this->updateSQL('products_sets', $set, ['id' => $set['id']]); } } // ############################################ // # ZAPSANI SABLON if (findModule('templates')) { $templates = getVal('templates', $data, []); foreach ($templates as $id_template_old => $template) { $template['id_template'] = intval(getVal('id_template', $template)); $template['id_product'] = $ID; if ($duplicate && $id_template_old > 0) { unset($template['id']); $id_template_old = -99; } $where = ['id_template' => $id_template_old, 'id_product' => $ID]; if (!empty($template['delete']) || !$id_template_old) { if ($id_template_old > 0) { $this->deleteSQL('templates_products', $where); } continue; } if ($template['id_template'] <= 0) { continue; } if ($id_template_old < 0) { $this->insertSQL('templates_products', $template); } else { $this->updateSQL('templates_products', $template, $where); } } } // ZAPSANI PRIPLATKU if (findModule(Modules::PRODUCTS_CHARGES)) { $products_charges = getVal('products_charges', $data, []); foreach ($products_charges as $key => $charge) { $charge['id'] = intval($charge['id']); $charge['id_product'] = $ID; if ($duplicate && $key > 0) { unset($charge['id']); $key = -99; } if (!empty($charge['delete']) || !$key) { if ($key > 0) { $this->deleteSQL('products_charges', ['id' => $charge['id']]); } continue; } if ($key < 0) { $this->insertSQL('products_charges', $charge); } else { $this->updateSQL('products_charges', $charge, ['id' => $charge['id']]); } } } $duplicateID = getVal('duplicateID'); // ############################################ // # DUPLIKACE OBRAZKU if (findModule('photos') && getVal('duplicateImages') && getVal('duplicateID')) { $fromID = intval(getVal('duplicateID')); $toID = intval($ID); sqlQuery('INSERT INTO '.getTableName('photos_products_relation')." (id_photo, id_product, show_in_lead, active, date_added, position) SELECT id_photo, {$toID}, show_in_lead, active, date_added, position FROM photos_products_relation WHERE id_product={$fromID} GROUP BY id_photo"); } // ############################################ // # DUPLIKACE Variant if (findModule('products_variations') && getVal('duplicateVariants') && getVal('duplicateID')) { Variations::duplicateVariations(intval(getVal('duplicateID')), intval($ID)); } if (findModule('photos') && getVal('duplicateImages') && getVal('duplicateID')) { Photos::checkLeadPhoto('photos_products_relation', 'id_product', intval($ID)); } // duplikace sekci if (findModule(Modules::PRODUCTS_SECTIONS) && $duplicateID) { sqlQuery('INSERT INTO products_in_sections (id_product, id_section, figure, generated) SELECT :id_product_new, id_section, figure, generated FROM products_in_sections WHERE id_product = :id_product;', [ 'id_product' => $duplicateID, 'id_product_new' => $ID, ]); } // duplikace souvisejiciho zbozi if (findModule(Modules::PRODUCTS_RELATED) && $duplicateID) { $relatedTypeFiled = ''; if (findModule(Modules::PRODUCTS_RELATED, Modules::SUB_TYPES)) { $relatedTypeFiled = ', type'; } sqlQuery('INSERT INTO products_related (id_top_product, id_rel_product, position'.$relatedTypeFiled.') SELECT :id_product_new, id_rel_product, position'.$relatedTypeFiled.' FROM products_related WHERE id_top_product = :id_product;', [ 'id_product' => $duplicateID, 'id_product_new' => $ID, ]); } // duplikace kolekci if (findModule(\Modules::PRODUCTS_COLLECTIONS) && $duplicateID) { sqlQuery('INSERT INTO products_collections (id_product, id_product_related) SELECT :id_product_new, id_product_related FROM products_collections WHERE id_product = :id_product;', [ 'id_product' => $duplicateID, 'id_product_new' => $ID, ]); } if (findModule(\Modules::ARTICLES) && $duplicateID) { sqlQuery('INSERT INTO products_in_articles (id_product, id_article) SELECT :id_product_new, id_article FROM products_in_articles WHERE id_product = :id_product;', [ 'id_product' => $duplicateID, 'id_product_new' => $ID, ]); } // Duplikace parametru if (findModule(Modules::PRODUCTS_PARAMETERS) && getVal('duplicateID')) { $fromID = intval(getVal('duplicateID')); $toID = intval($ID); $additionalField = ''; if (findModule(Modules::PRODUCTS_PARAMETERS.Modules::SUB_CONFIGURATIONS)) { $additionalField = ', configuration_price'; } sqlQuery('INSERT INTO parameters_products (id_product, id_parameter, value_list, value_char, value_float, unit, weight'.$additionalField.') SELECT '.$toID.', id_parameter, value_list, value_char, value_float, unit, weight'.$additionalField.' FROM parameters_products WHERE id_product=:id_product', ['id_product' => $fromID]); // konfigurace parametru if (findModule(Modules::PRODUCTS_PARAMETERS.Modules::SUB_CONFIGURATIONS)) { sqlQuery('INSERT INTO parameters_configurations (id_parameter, id_product) SELECT id_parameter, '.$toID.' FROM parameters_configurations WHERE id_product=:id_product', ['id_product' => $fromID]); } // skupina parametru if (findModule(Modules::PARAMETER_GROUPS)) { sqlQuery('UPDATE products SET id_parameter_group = ( SELECT id_parameter_group FROM products WHERE id = :from_id ) WHERE id = :to_id', ['to_id' => $toID, 'from_id' => $fromID]); } } // Zapsani stitku if (findModule(Modules::LABELS, Modules::SUB_PRODUCT_LABELS)) { $labels = $data['labels'] ?? []; // odfiltruju generovany stitky na produktu $labels = array_filter($labels); $labelIds = array_keys($labels); // nactu si aktualni stitky na produktu $oldLabelIds = sqlQueryBuilder() ->select('id_label') ->from('product_labels_relation') ->andWhere(Operator::equals(['id_product' => $ID])) ->andWhere(Operator::equals(['generated' => 0])) ->execute() ->fetchFirstColumn(); // najdu si hodnoty, ktere mam smazat $deleteLabelIds = array_diff($oldLabelIds, $labelIds); // najdu si hodnoty, ktere mam insertovat $insertLabelsIds = array_diff($labelIds, $oldLabelIds); // provedu delete if (!empty($deleteLabelIds)) { sqlQueryBuilder() ->delete('product_labels_relation') ->andWhere(Operator::equals([ 'id_product' => $ID, 'generated' => 0])) ->andWhere(Operator::inIntArray($deleteLabelIds, 'id_label')) ->execute(); } // provedu insert foreach ($insertLabelsIds as $labelId) { sqlQueryBuilder() ->insert('product_labels_relation') ->directValues([ 'id_label' => $labelId, 'id_product' => $ID, ]) ->onDuplicateKeyUpdate(['id_label' => 'id_label']) ->execute(); } if (!empty($insertLabelsIds) || !empty($deleteLabelIds)) { $this->updateSQL('products', ['updated' => date('Y-m-d H:i:s')], ['id' => $ID]); } } // ############################################ // # Aktualizace fulltextového vyhledávání if (findModule(\Modules::SEARCH)) { $fulltext = ServiceContainer::getService(FulltextInterface::class); $languageContext = Contexts::get(\KupShop\KupShopBundle\Context\LanguageContext::class); foreach ($languageContext->getSupported() as $language) { $languageContext->activate($language->getId()); $fulltext->updateProduct($ID); } } if ($acn == 'add') { $product = new Product(); $product->createFromDB($this->getID()); $eventDispatcher = ServiceContainer::getService('event_dispatcher'); $event = new ProductEvent($product); $eventDispatcher->dispatch($event, ProductEvent::PRODUCT_CREATED); } return true; } // Vypisovani aktivit protected function activityMessage($name, array $additionalData = []) { $acn = $this->getAction(); $ID = $this->getID(); $data = sqlQueryBuilder()->select('title, code')->fromProducts()->where(\Query\Operator::equals(['id' => $ID]))->execute()->fetch(); if ($acn == 'add') { writeDownActivity(sprintf(getTextString('products', 'activityAdded'), $ID, $data['title'].($data['code'] ? " ({$data['code']})" : ''))); } elseif ($acn == 'edit') { writeDownActivity(sprintf(getTextString('products', 'activityEdited'), $ID, $data['title'].($data['code'] ? " ({$data['code']})" : ''))); } } public function handleDelete() { if (!findRight('PROD_ERASE')) { redirect('launch.php?s=error.php&id=1'); } $ID = $this->getID(); $data = sqlQueryBuilder()->select('title, code')->fromProducts()->where(\Query\Operator::equals(['id' => $ID]))->execute()->fetch(); writeDownActivity(sprintf(getTextString('products', 'activityDeleted'), $ID, $data['title'].($data['code'] ? " ({$data['code']})" : ''))); $classProd = new Product($this->getID()); $classProd->delete(); // ############################################ // # Aktualizace fulltextového vyhledávání if (findModule(\Modules::SEARCH) && !findModule(Modules::KAFKA)) { $fulltext = ServiceContainer::getService(FulltextInterface::class); $fulltext->updateProduct($this->getID()); } redirect('launch.php?s=products.php&acn=erased'); } public function handleEraseSelected() { if (!findRight('PROD_ERASE')) { redirect('launch.php?s=error.php&id=1'); } $ID = $this->getID(); $no = count($ID); for ($i = 0; $i < $no; $i++) { $ID = $ID[$i]; writeDownActivity('smazáno zboží: '.returnSQLResult('SELECT title FROM '.getTableName('products')." WHERE id='".$ID."' ")); $classProd = new Product($ID); $classProd->delete(); } $ErrStr = 'Bylo smazáno '.$no.' položek'; $url = 'launch.php?s=products.php&acn=erased&ErrStr='.urlencode($ErrStr); redirect($url); } public function handleGenerateCouponPhoto() { $data = $this->getData(); $id_discount = ($data['data']['generate_coupon_discount'] ?? null); if ($id_discount) { $discountGenerator = ServiceContainer::getService(DiscountGenerator::class); $result = $discountGenerator->generateCouponPhoto($id_discount, $this->getID()); if ($result === true) { $this->returnOK(); } else { $this->returnError($result); } } } public function handleGenerateEan() { if ($ID = $this->getID()) { $ean = EANValidator::generateEan(['id_product' => $ID]); $exists = Variations::eanExists(0, $ean, $ID); if ($exists) { $message = Variations::eanExistsMessage($exists); $this->addHTMLError('Vygenerovaný '.$message); // Vygenerovaný EAN {ean} není unikátní. {odkaz na duplicitní produkt} } else { sqlQueryBuilder()->update('products') ->directValues(['ean' => $ean]) ->where(Operator::equals(['id' => $ID])) ->execute(); $this->returnOK(); } } } private function getDisabledSections(): array { $sections = sqlQueryBuilder() ->select('id_section') ->from('products_in_sections') ->where(Operator::equals(['id_product' => $this->getID(), 'generated' => 1])) ->execute()->fetchAll(); return \KupShop\KupShopBundle\Util\Functional\Mapping::mapKeys($sections, function ($k, $v) { return [$v['id_section'], true]; }); } public function handleDeactivatePriceForDiscount() { if ($ID = $this->getID()) { sqlQueryBuilder()->update('products') ->directValues(['price_for_discount' => -1]) ->where(Operator::equals(['id' => $ID])) ->execute(); sqlQueryBuilder()->update('products_variations') ->directValues(['price_for_discount' => -1]) ->where(Operator::equals(['id_product' => $ID])) ->andWhere('price_for_discount IS NOT NULL') ->execute(); if (findModule(Modules::PRICELISTS)) { sqlQueryBuilder()->update('pricelists_products') ->directValues(['price_for_discount' => -1]) ->where(Operator::equals(['id_product' => $ID])) ->execute(); } } $this->returnOK(); } public function handleActivatePriceForDiscount() { if ($ID = $this->getID()) { sqlQueryBuilder()->update('products') ->directValues(['price_for_discount' => null]) ->where(Operator::equals(['id' => $ID])) ->execute(); sqlQueryBuilder()->update('products_variations') ->directValues(['price_for_discount' => null]) ->where(Operator::equals(['id_product' => $ID])) ->andWhere('price_for_discount = -1') ->execute(); if (findModule(Modules::PRICELISTS)) { sqlQueryBuilder()->update('pricelists_products') ->directValues(['price_for_discount' => null]) ->where(Operator::equals(['id_product' => $ID])) ->andWhere('price_for_discount = -1') ->execute(); } } $this->returnOK(); } public function handleException($e) { switch (intval($e->getPrevious()->errorInfo[1])) { case 1062: $badFields = $this->getBadValues($this->getTableName(), ['id' => $this->ID]); $ErrStr = ''; if (in_array('title', $badFields)) { $ErrStr .= 'Produkt s tímto názvem již existuje. Zvolte prosím jiný název. '; } foreach ($badFields as $key => $value) { if ($value == 'title') { continue; } if ($key == 0) { $ErrStr .= 'Duplicitní '; } $ErrStr .= '{'.$value.'} '; } if (!$badFields) { $ErrStr = "Duplicitní záznam: \n".$e->getMessage(); } $this->addError($ErrStr); return; } parent::handleException($e); } public function hasRights($name = null) { switch ($name) { case Window::RIGHT_DELETE: return findRight('PROD_ERASE') && parent::hasRights($name); default: return parent::hasRights($name); } } } return Products::class;