private function initQuantitiesForm() { if (!$this->context->controller->default_form_language) { $this->languages = $this->context->controller->getLanguages(); } if ($this->product->product_id) { if ($this->product_exists_in_shop) { //Get all product_attribute_id $attributes = $this->product->getAttributesResume($this->context->language->lang_id); if (empty($attributes)) { $attributes[] = new JObject(); $attributes[0]->set('product_attribute_id', 0); $attributes[0]->set('attribute_designation', ''); } /** get available quantities **/ $available_quantity = array(); $product_designation = array(); foreach ($attributes as $attribute) { $product_attribute_id = is_object($attribute) ? $attribute->product_attribute_id : $attribute['product_attribute_id']; $attribute_designation = is_object($attribute) ? $attribute->attribute_designation : $attribute['attribute_designation']; // Get available quantity for the current product attribute in the current shop $available_quantity[$product_attribute_id] = JeproshopStockAvailableModelStockAvailable::getQuantityAvailableByProduct((int) $this->product->product_id, $product_attribute_id); // Get all product designation $product_designation[$product_attribute_id] = rtrim($this->product->name[$this->context->language->lang_id] . ' - ' . $attribute_designation, ' - '); } $show_quantities = true; $shop_context = JeproshopShopModelShop::getShopContext(); $shop_group = new JeproshopShopGroupModelShopGroup((int) JeproshopShopModelShop::getContextShopGroupID()); // if we are in all shops context, it's not possible to manage quantities at this level if (JeproshopShopModelShop::isFeaturePublished() && $shop_context == JeproshopShopModelShop::CONTEXT_ALL) { $show_quantities = false; // if we are in group shop context } elseif (JeproshopShopModelShop::isFeaturePublished() && $shop_context == JeproshopShopModelShop::CONTEXT_GROUP) { // if quantities are not shared between shops of the group, it's not possible to manage them at group level if (!$shop_group->share_stock) { $show_quantities = false; } } else { // if we are in shop context // if quantities are shared between shops of the group, it's not possible to manage them for a given shop if ($shop_group->share_stock) { $show_quantities = false; } } $stock_management = JeproshopSettingModelSetting::getValue('stock_management'); $this->assignRef('stock_management', $stock_management); $has_attribute = $this->product->hasAttributes(); $this->assignRef('has_attribute', $has_attribute); // Check if product has combination, to display the available date only for the product or for each combination $db = JFactory::getDBO(); if (JeproshopCombinationModelCombination::isFeaturePublished()) { $query = "SELECT COUNT(product_id) FROM " . $db->quoteName('#__jeproshop_product_attribute') . " WHERE "; $query .= " product_id = " . (int) $this->product->product_id; $db->setQuery($query); $countAttributes = (int) $db->loadResult(); } else { $countAttributes = false; } $this->assignRef('count_attributes', $countAttributes); // if advanced stock management is active, checks associations $advanced_stock_management_warning = false; if (JeproshopSettingModelSetting::getValue('advanced_stock_management') && $this->product->advanced_stock_management) { $product_attributes = JeproshopProductModelProduct::getProductAttributesIds($this->product->product_id); $warehouses = array(); if (!$product_attributes) { $warehouses[] = JeproshopWarehouseModelWarehouse::getProductWarehouseList($this->product->product_id, 0); } foreach ($product_attributes as $product_attribute) { $ws = JeproshopWarehouseModelWarehouse::getProductWarehouseList($this->product->product_id, $product_attribute->product_attribute_id); if ($ws) { $warehouses[] = $ws; } } $warehouses = JeproshopTools::arrayUnique($warehouses); if (empty($warehouses)) { $advanced_stock_management_warning = true; } } if ($advanced_stock_management_warning) { JError::raiseWarning(500, JText::_('If you wish to use the advanced stock management, you must:')); JError::raiseWarning(500, '- ' . JText::_('associate your products with warehouses.')); JError::raiseWarning(500, '- ' . JText::_('associate your warehouses with carriers.')); JError::raiseWarning(500, '- ' . JText::_('associate your warehouses with the appropriate shops.')); } $pack_quantity = null; // if product is a pack if (JeproshopProductPack::isPack($this->product->product_id)) { $items = JeproshopProductPack::getItems((int) $this->product->product_id, JeproshopSettingModelSetting::getValue('default_lang')); // gets an array of quantities (quantity for the product / quantity in pack) $pack_quantities = array(); foreach ($items as $item) { if (!$item->isAvailableWhenOutOfStock((int) $item->out_of_stock)) { $pack_id_product_attribute = JeproshopProductModelProduct::getDefaultAttribute($item->product_id, 1); $pack_quantities[] = JeproshopProductModelProduct::getQuantity($item->id, $pack_id_product_attribute) / ($item->pack_quantity !== 0 ? $item->pack_quantity : 1); } } // gets the minimum if (count($pack_quantities)) { $pack_quantity = $pack_quantities[0]; foreach ($pack_quantities as $value) { if ($pack_quantity > $value) { $pack_quantity = $value; } } } if (!JeproshopWarehouseModelWarehouse::getPackWarehouses((int) $this->product->product_id)) { $this->displayWarning($this->l('You must have a common warehouse between this pack and its product.')); } } $this->assignRef('attributes', $attributes); $this->assignRef('available_quantity', $available_quantity); $this->assignRef('pack_quantity', $pack_quantity); $stock_management_active = JeproshopSettingModelSetting::getValue('advanced_stock_management'); $this->assignRef('stock_management_active', $stock_management_active); $this->assignRef('product_designation', $product_designation); $this->assignRef('show_quantities', $show_quantities); $order_out_of_stock = JeproshopSettingModelSetting::getValue('allow_out_of_stock_ordering'); $this->assignRef('order_out_of_stock', $order_out_of_stock); /*'token_preferences' => Tools::getAdminTokenLite('AdminPPreferences'), 'token' => $this->token, 'languages' => $this->_languages, 'id_lang' => $this->context->language->id ));*/ } else { JError::raiseWarning(500, JText::_('You must save the product in this shop before managing quantities.')); } } else { JError::raiseWarning(500, JText::_('You must save this product before managing quantities.')); } }
/** * For a given id_product, synchronizes StockAvailable::quantity with Stock::usable_quantity * * @param int $product_id * @param int $order_shop_id * @return bool */ public static function synchronize($product_id, $order_shop_id = null) { if (!JeproshopTools::isUnsignedInt($product_id)) { return false; } $db = JFactory::getDBO(); // gets warehouse ids grouped by shops $warehouse_ids = JeproshopWarehouseModelWarehouse::getWarehousesGroupedByShops(); if ($order_shop_id !== null) { $order_warehouses = array(); $warehouses = JeproshopWarehouseModelWarehouse::getWarehouses(false, (int) $order_shop_id); foreach ($warehouses as $warehouse) { $order_warehouses[] = $warehouse->warehouse_id; } } // gets all product attributes ids $product_attribute_ids = array(); foreach (JeproshopProductModelProduct::getProductAttributesIds($product_id) as $product_attribute_id) { $product_attribute_ids[] = $product_attribute_id->product_attribute_id; } // Allow to order the product when out of stock? $out_of_stock = JeproshopStockAvailableModelStockAvailable::outOfStock($product_id); $manager = JeproshopStockManagerFactory::getManager(); // loops on $ids_warehouse to synchronize quantities foreach ($warehouse_ids as $shop_id => $warehouses) { // first, checks if the product depends on stock for the given shop $id_shop if (JeproshopStockAvailableModelStockAvailable::dependsOnStock($product_id, $shop_id)) { // init quantity $product_quantity = 0; // if it's a simple product if (empty($product_attribute_ids)) { $allowed_warehouse_for_product = JeproshopWarehouseModelWarehouse::getProductWarehouseList((int) $product_id, 0, (int) $shop_id); $allowed_warehouse_for_product_clean = array(); foreach ($allowed_warehouse_for_product as $warehouse) { $allowed_warehouse_for_product_clean[] = (int) $warehouse->warehouse_id; } $allowed_warehouse_for_product_clean = array_intersect($allowed_warehouse_for_product_clean, $warehouses); if ($order_shop_id != null && !count(array_intersect($allowed_warehouse_for_product_clean, $order_warehouses))) { continue; } $product_quantity = $manager->getProductRealQuantities($product_id, null, $allowed_warehouse_for_product_clean, true); /*Hook::exec('actionUpdateQuantity', array( 'id_product' => $id_product, 'id_product_attribute' => 0, 'quantity' => $product_quantity ) );*/ } else { // else this product has attributes, hence loops on $ids_product_attribute foreach ($product_attribute_ids as $product_attribute_id) { $allowed_warehouse_for_combination = JeproshopWarehouseModelWarehouse::getProductWarehouseList((int) $product_id, (int) $product_attribute_id, (int) $shop_id); $allowed_warehouse_for_combination_clean = array(); foreach ($allowed_warehouse_for_combination as $warehouse) { $allowed_warehouse_for_combination_clean[] = (int) $warehouse->warehouse_id; } $allowed_warehouse_for_combination_clean = array_intersect($allowed_warehouse_for_combination_clean, $warehouses); if ($order_shop_id != null && !count(array_intersect($allowed_warehouse_for_combination_clean, $order_warehouses))) { continue; } $quantity = $manager->getProductRealQuantities($product_id, $product_attribute_id, $allowed_warehouse_for_combination_clean, true); $query = new DbQuery(); $query->select('COUNT(*)'); $query->from('stock_available'); $query->where('id_product = ' . (int) $product_id . ' AND id_product_attribute = ' . (int) $product_attribute_id . StockAvailable::addSqlShopRestriction(null, $shop_id)); if ((int) Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query)) { $query = array('table' => 'stock_available', 'data' => array('quantity' => $quantity), 'where' => 'id_product = ' . (int) $product_id . ' AND id_product_attribute = ' . (int) $product_attribute_id . StockAvailable::addSqlShopRestriction(null, $shop_id)); Db::getInstance()->update($query['table'], $query['data'], $query['where']); } else { $query = array('table' => 'stock_available', 'data' => array('quantity' => $quantity, 'depends_on_stock' => 1, 'out_of_stock' => $out_of_stock, 'id_product' => (int) $id_product, 'id_product_attribute' => (int) $id_product_attribute)); StockAvailable::addSqlShopParams($query['data']); Db::getInstance()->insert($query['table'], $query['data']); } $product_quantity += $quantity; Hook::exec('actionUpdateQuantity', array('id_product' => $id_product, 'id_product_attribute' => $id_product_attribute, 'quantity' => $quantity)); } } // updates // if $id_product has attributes, it also updates the sum for all attributes $query = array('table' => 'stock_available', 'data' => array('quantity' => $product_quantity), 'where' => 'id_product = ' . (int) $id_product . ' AND id_product_attribute = 0' . StockAvailable::addSqlShopRestriction(null, $shop_id)); Db::getInstance()->update($query['table'], $query['data'], $query['where']); } } // In case there are no warehouses, removes product from StockAvailable if (count($warehouse_ids) == 0 && JeproshopStockAvailableModelStockAvailable::dependsOnStock((int) $product_id)) { $query = "UPDATE " . $db->quoteName('#__jeproshop_stock_available') . " SET " . $db->quoteName('quantity') . " = 0 "; $query .= " WHERE " . $db->quoteName('product_id') . " = " . (int) $product_id; $db->setQuery($query); $db->query(); } JeproshopCache::clean('jeproshop_stock_available_get_quantity_available_by_product_' . (int) $product_id . '_*'); }
public function updateProduct() { $db = JFactory::getDBO(); $app = JFactory::getApplication(); $languages = JeproshopLanguageModelLanguage::getLanguages(false); if (!isset($this->context)) { $this->context = JeproshopContext::getContext(); } $this->clearCache(); $this->date_upd = date('Y-m-d H:i:s'); if (JeproshopTools::isLoadedObject($this, 'product_id')) { $this->removeTaxFromEcotax(); $product_type_before = $this->getType(); $this->indexed = 0; $input = JRequest::get('post'); $product_data = isset($input['information']) ? $input['information'] : $input['jform']; $existingProduct = $this; if (JeproshopShopModelShop::isFeaturePublished() && JeproshopShopModelShop::getShopContext() != JeproshopShopModelShop::CONTEXT_SHOP) { $this->setFieldsToUpdate((array) $input['multishop_check']); } if ($this->context->shop->getShopContext() == JeproshopShopModelShop::CONTEXT_ALL && !$this->isAssociatedToShop()) { $isAssociatedToShop = false; $combinations = JeproshopProductModelProduct::getProductAttributesIds($this->product_id); if ($combinations) { foreach ($combinations as $combination_id) { $combination = new JeproshopCombinationModelCombination($combination_id); $default_combination = new JeproshopCombinationModelCombination($combination_id, null, $this->default_shop_id); $combination->product_id = (int) $default_combination->product_id; $combination->location = $db->quote($default_combination->location); $combination->ean13 = $db->quote($default_combination->ean13); $combination->upc = $db->quote($default_combination->upc); $combination->quantity = (int) $default_combination->quantity; $combination->reference = $db->quote($default_combination->reference); $combination->supplier_reference = $db->quote($default_combination->supplier_reference); $combination->wholesale_price = (double) $default_combination->wholesale_price; $combination->price = (double) $default_combination->price; $combination->ecotax = (double) $default_combination->ecotax; $combination->weight = $default_combination->weight; $combination->unit_price_impact = (double) $default_combination->unit_price_impact; $combination->default_on = (int) $default_combination->default_on; $combination->available_date = $default_combination->available_date ? $db->quote($default_combination->available_date) : '0000-00-00'; $combination->save(); } } } else { $isAssociatedToShop = true; } $shop_list_ids = JeproshopShopModelShop::getCompleteListOfShopsId(); if (count($this->shop_list_id) > 0) { $shop_list_ids = $this->shop_list_id; } if (JeproshopShopModelShop::checkDefaultShopId('product') && !$this->default_shop_id) { $this->default_shop_id = min($shop_list_ids); } /*$manufacturer_id = $product_data['manufacturer_id']; $default_category_id = 1; $default_shop_id = JeproshopSettingModelSetting::getValue('default_shop'); */ //$tax_rules_group_id = $product_data['tax_rules_group_id']; $show_price = isset($input_data['show_price']) ? 1 : 0; $on_sale = isset($product_data['on_sale']) ? 1 : 0; $online_only = isset($product_data['online_only']) ? 1 : 0; $available_for_order = isset($product_data['available_for_order']) ? 1 : 0; $ean_13 = JeproshopTools::isEan13($product_data['ean13']) ? $product_data['ean13'] : ''; $upc = JeproshopTools::isUpc($product_data['upc']) ? $product_data['upc'] : ''; $reference = JeproshopTools::isReference($product_data['reference']) ? $product_data['reference'] : ''; //$product_type = $product_data['product_type']; $published = $product_data['published']; $redirect_type = $product_data['redirect_type']; /*$ecotax = $product_data['ecotax']; $unity = $product_data['unity']; $unit_price = (float)$product_data['unit_price']; $wholesale_price = (float)$product_data['wholesale_price']; */ $visibility = $product_data['visibility']; $condition = $product_data['condition']; $result = true; /** data base updating **/ $query = "UPDATE " . $db->quoteName('#__jeproshop_product') . " SET " . $db->quoteName('reference') . " = " . $db->quote($reference) . ", " . $db->quoteName('on_sale') . " = " . (int) $on_sale . ", "; $query .= $db->quoteName('online_only') . " = " . (int) $online_only . ", " . $db->quoteName('ean13') . " = " . $db->quote($ean_13) . ", " . $db->quoteName('upc') . " = " . $db->quote($upc) . ", "; $query .= $db->quoteName('published') . " = " . (int) $published . ", " . $db->quoteName('redirect_type') . "= " . $db->quote($redirect_type) . ", " . $db->quoteName('visibility') . " = " . $db->quote($visibility) . ", "; $query .= $db->quoteName('product_redirected_id') . " = " . $db->quote($product_data['product_redirected_id']) . ", " . $db->quoteName('available_for_order') . " = " . (int) $available_for_order . ", "; $query .= $db->quoteName('show_price') . " = " . (int) $show_price . ", " . $db->quoteName('condition') . " = " . $db->quote($condition) . ", " . $db->quoteName('date_upd') . " = " . $db->quote($this->date_upd); $query .= " WHERE " . $db->quoteName('product_id') . " = " . (int) $this->product_id; $db->setQuery($query); $result &= $db->query(); if ($result) { // Database insertion for multishop fields related to the object if (JeproshopShopModelShop::isTableAssociated('product')) { $default_category_id = 1; /* Shop fields */ foreach ($shop_list_ids as $shop_id) { $query = "UPDATE " . $db->quoteName('#__jeproshop_product_shop') . " SET " . $db->quoteName('default_category_id') . " = " . (int) $default_category_id; $query .= ", " . $db->quoteName('online_only') . " = " . (int) $online_only; $query .= ", " . $db->quoteName('redirect_type') . " = " . $db->quote($redirect_type) . ", " . $db->quoteName('product_redirected_id') . " = " . (int) $product_data['product_redirected_id']; $query .= ", " . $db->quoteName('available_for_order') . " = " . (int) $available_for_order . ", " . $db->quoteName('condition') . " = " . $db->quote($product_data['condition']); $query .= ", " . $db->quoteName('published') . " = " . (int) $product_data['published'] . ", " . $db->quoteName('show_price') . " = " . (int) $show_price; //$query .= ", " . $db->quoteName('additional_shipping_cost') . " = " . (float)$product_data['additional_shipping_cost']; $query .= ", " . $db->quoteName('visibility') . " = " . $db->quote($product_data['visibility']) . ", " . $db->quoteName('date_upd') . " = " . $db->quote($this->date_upd); $query .= " WHERE " . $db->quoteName('product_id') . " = " . $this->product_id . " AND " . $db->quoteName('shop_id') . " = " . $shop_id; $db->setQuery($query); $result &= $db->query(); if ($result) { /* Multilingual fields */ foreach ($languages as $language) { $query = "UPDATE " . $db->quoteName('#__jeproshop_product_lang') . " SET " . $db->quoteName('description') . " = "; $query .= $db->quote($product_data['description_' . $language->lang_id]) . ", " . $db->quoteName('short_description'); $query .= " = " . $db->quote($product_data['short_description_' . $language->lang_id]) . ", " . $db->quoteName('name'); $query .= " = " . $db->quote($product_data['name_' . $language->lang_id]) . " WHERE " . $db->quoteName('product_id') . " = "; $query .= (int) $this->product_id . " AND " . $db->quoteName('shop_id'); $query .= " = " . (int) $shop_id . " AND " . $db->quoteName('lang_id') . " = " . (int) $language->lang_id; $db->setQuery($query); $result &= $db->query(); } } } } } if ($result) { // If the product doesn't exist in the current shop but exists in another shop if (JeproshopShopModelShop::getShopContext() == JeproshopShopModelShop::CONTEXT_SHOP && $existingProduct->isAssociatedToShop($this->context->shop->shop_id)) { $outOfStock = JeproshopStockAvailableModelStockAvailable::outOfStock($existingProduct->product_id, $existingProduct->default_shop_id); $dependsOnStock = JeproshopStockAvailableModelStockAvailable::dependsOnStock($existingProduct->product_id, $existingProduct->default_shop_id); JeproshopStockAvailableModelStockAvailable::setProductOutOfStock((int) $this->product_id, $outOfStock, $this->context->shop->shop_id); JeproshopStockAvailableModelStockAvailable::setProductDependsOnStock((int) $this->product_id, $dependsOnStock, $this->context->shop->shop_id); } if (in_array($this->context->shop->getShopContext(), array(JeproshopShopModelShop::CONTEXT_SHOP, JeproshopShopModelShop::CONTEXT_ALL))) { $this->addCarriers(); $this->updateAccessories(); $this->processSuppliers(); $this->processFeatures(); $this->processProductAttribute(); $this->processProductAttribute(); $this->processPriceAddition(); $this->processSpecificPricePriorities(); $this->processCustomizationConfiguration(); $this->processAttachments(); $this->updatePackItems(); // Disallow advanced stock management if the product become a pack if ($product_type_before == JeproshopProductModelProduct::SIMPLE_PRODUCT && $this->getType() == JeproshopProductModelProduct::PACKAGE_PRODUCT) { JeproshopStockAvailableModelStockAvailable::setProductDependsOnStock($this->product_id, false); } $this->updateDownloadProduct(1); $this->updateTags(JeproshopLanguageModelLanguage::getLanguages(false)); if ($this->isProductFieldUpdated('category_box') && !$this->updateCategories($product_data['category_box'])) { JError::raiseError(500, JText::_('COM_JEPROSHOP_AN_ERROR_OCCURRED_WHILE_LINKING_THE_PRODUCT_TO_CATEGORIES_MESSAGE')); $this->context->controller->has_errors = true; } //TODO correct category update and check php $_POST limit to handle the form } $this->processWarehouses(); $category_link = $app->input->get('category_id') ? '&category_id=' . $app->input->get('category_id') : ''; if (!$this->context->controller->has_errors) { if (in_array($this->visibility, array('both', 'search')) && JeproshopSettingModelSetting::getValue('search_indexation')) { JeproshopSearch::indexation(false, $this->product_id); } //save and preview $message = JText::_('COM_JEPROSHOP_UPDATE_SUCCESSFULLY_MESSAGE'); if ($app->input->get('task') == 'save_preview') { $link = $this->getPreviewUrl(); } else { if ($app->input->get('task') == 'edit') { $link = JRoute::_('index.php?option=com_jeproshop&view=product&task=edit&product_id=' . $this->product_id . $category_link . JeproshopTools::getProductToken()); } else { $link = JRoute::_('index.php?option=com_jeproshop&view=product&' . $category_link); $message = JText::_('COM_JEPROSHOP_UPDATE_SUCCESSFULLY_MESSAGE'); } } $app->redirect($link, $message); } else { $app->input->set('task', 'edit'); $app->redirect('index.php?option=com_jeproshop&view=product&task=edit&product_id=' . $this->product_id . $category_link . JeproshopTools::getProductToken()); } } else { if (!$isAssociatedToShop && $combinations) { foreach ($combinations as $combination_id) { $combination = new JeproshopCombinationModelCombination((int) $combination_id); $combination->delete(); } JError::raiseError(500, JText::_('COM_JEPROSHOP_AN_ERROR_OCCURRED_WHILE_UPDATING_A_PRODUCT_MESSAGE')); } } $this->setGroupReduction(); if ($this->getType() == JeproshopProductModelProduct::VIRTUAL_PRODUCT && $this->published && !JeproshopSettingModelSetting::getValue('virtual_product_feature_active')) { JeproshopSettingModelSetting::updateValue('virtual_product_feature_active', '1'); } return true; } }