diff --git a/app/Mage.php b/app/Mage.php index a298754e90..01f037ceac 100644 --- a/app/Mage.php +++ b/app/Mage.php @@ -82,7 +82,7 @@ final class Mage { public static function getVersion() { - return '1.2.1'; + return '1.2.1.1'; } /** diff --git a/app/code/core/Mage/Adminhtml/Model/Sales/Order/Create.php b/app/code/core/Mage/Adminhtml/Model/Sales/Order/Create.php index 576ee92bb8..648de3dcb3 100644 --- a/app/code/core/Mage/Adminhtml/Model/Sales/Order/Create.php +++ b/app/code/core/Mage/Adminhtml/Model/Sales/Order/Create.php @@ -573,6 +573,9 @@ public function addProduct($product, $qty=1) $product->setSkipCheckRequiredOption(true); $item = $this->getQuote()->addProduct($product, $qty); $product->unsSkipCheckRequiredOption(); + if (is_string($item)) { + Mage::throwException($item); + } $item->checkData(); } diff --git a/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Order/Status/Newprocessing.php b/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Order/Status/Newprocessing.php new file mode 100644 index 0000000000..26e4df9991 --- /dev/null +++ b/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Order/Status/Newprocessing.php @@ -0,0 +1,36 @@ + bundle/product_type + 1 diff --git a/app/code/core/Mage/Catalog/Model/Product.php b/app/code/core/Mage/Catalog/Model/Product.php index 3daa7e5c2f..a841e8d6c9 100644 --- a/app/code/core/Mage/Catalog/Model/Product.php +++ b/app/code/core/Mage/Catalog/Model/Product.php @@ -305,7 +305,11 @@ protected function _beforeSave() $hasOptions = false; $hasRequiredOptions = false; - $this->canAffectOptions($this->_canAffectOptions || $this->getCanSaveCustomOptions()); + /** + * $this->_canAffectOptions - set by type instance only + * $this->getCanSaveCustomOptions() - set either in controller when "Custom Options" ajax tab is loaded, or in type instance as well + */ + $this->canAffectOptions($this->_canAffectOptions && $this->getCanSaveCustomOptions()); if ($this->getCanSaveCustomOptions()) { $options = $this->getProductOptions(); if (is_array($options)) { diff --git a/app/code/core/Mage/Catalog/Model/Product/Type.php b/app/code/core/Mage/Catalog/Model/Product/Type.php index 462b5c5bdc..f25068b115 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Type.php +++ b/app/code/core/Mage/Catalog/Model/Product/Type.php @@ -47,6 +47,7 @@ class Mage_Catalog_Model_Product_Type const DEFAULT_PRICE_MODEL = 'catalog/product_type_price'; static protected $_types; + static protected $_compositeTypes; static protected $_priceModels; /** @@ -67,6 +68,7 @@ public static function factory($product) $typeModel = Mage::getModel($typeModelName); $typeModel->setProduct($product); + $typeModel->setConfig($types[$product->getTypeId()]); return $typeModel; } @@ -150,4 +152,23 @@ static public function getTypes() return self::$_types; } + + /** + * Return composite product type Ids + * + * @return array + */ + static public function getCompositeTypes() + { + if (is_null(self::$_compositeTypes)) { + self::$_compositeTypes = array(); + $types = self::getTypes(); + foreach ($types as $typeId=>$typeInfo) { + if (array_key_exists('composite', $typeInfo) && $typeInfo['composite']) { + self::$_compositeTypes[] = $typeId; + } + } + } + return self::$_compositeTypes; + } } diff --git a/app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php b/app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php index 24d3c26edd..9db830a901 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php +++ b/app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php @@ -451,6 +451,20 @@ public function isComposite() return $this->_isComposite; } + /** + * Setting specified product type variables + * + * @param array $config + * @return Mage_Catalog_Model_Product_Type_Abstract + */ + public function setConfig($config) + { + if (isset($config['composite'])) { + $this->_isComposite = (bool) $config['composite']; + } + return $this; + } + /** * Default action to get sku of product * diff --git a/app/code/core/Mage/Catalog/Model/Product/Type/Configurable.php b/app/code/core/Mage/Catalog/Model/Product/Type/Configurable.php index 4a17d84a4e..ef426a860f 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Type/Configurable.php +++ b/app/code/core/Mage/Catalog/Model/Product/Type/Configurable.php @@ -1,564 +1,577 @@ - - */ -class Mage_Catalog_Model_Product_Type_Configurable extends Mage_Catalog_Model_Product_Type_Abstract -{ - const TYPE_CODE = 'configurable'; - /** - * Attributes which used for configurable product - * - * @var array - */ - protected $_usedProductAttributeIds = null; - protected $_usedProductAttributes = null; - protected $_usedAttributes = null; - protected $_configurableAttributes = null; - protected $_usedProductIds = null; - protected $_usedProducts = null; - - protected $_isComposite = true; - - /** - * Return relation info about used products - * - * @return Varien_Object Object with information data - */ - public function getRelationInfo() - { - $info = new Varien_Object(); - $info->setTable('catalog/product_super_link') - ->setParentFieldName('parent_id') - ->setChildFieldName('product_id'); - return $info; - } - - /** - * Retrieve Required children ids - * Return grouped array, ex array( - * group => array(ids) - * ) - * - * @param int $parentId - * @param bool $required - * @return array - */ - public function getChildrenIds($parentId, $required = true) - { - return Mage::getResourceSingleton('catalog/product_type_configurable') - ->getChildrenIds($parentId, $required); - } - - /** - * Retrieve parent ids array by requered child - * - * @param int $childId - * @return array - */ - public function getParentIdsByChild($childId) - { - return Mage::getResourceSingleton('catalog/product_type_configurable') - ->getParentIdsByChild($childId); - } - - /** - * Retrieve product type attributes - * - * @return array - */ - public function getEditableAttributes() - { - if (is_null($this->_editableAttributes)) { - $this->_editableAttributes = parent::getEditableAttributes(); - foreach ($this->_editableAttributes as $index => $attribute) { - if ($this->getUsedProductAttributeIds() - && in_array($attribute->getAttributeId(), $this->getUsedProductAttributeIds())) { - unset($this->_editableAttributes[$index]); - } - } - } - return $this->_editableAttributes; - } - - /** - * Checkin attribute availability for create superproduct - * - * @param Mage_Eav_Model_Entity_Attribute $attribute - * @return bool - */ - public function canUseAttribute(Mage_Eav_Model_Entity_Attribute $attribute) - { - $allow = $attribute->getIsGlobal() == Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL - && $attribute->getIsVisible() - && $attribute->getIsConfigurable() - && $attribute->usesSource(); - - return $allow; - } - - /** - * Declare attribute identifiers used for asign subproducts - * - * @param array $ids - * @return Mage_Catalog_Model_Product_Type_Configurable - */ - public function setUsedProductAttributeIds($ids) - { - $this->_usedProductAttributes = array(); - $this->_configurableAttributes= array(); - - foreach ($ids as $attributeId) { - $this->_usedProductAttributes[] = $this->getAttributeById($attributeId); - $this->_configurableAttributes[]= Mage::getModel('catalog/product_type_configurable_attribute') - ->setProductAttribute($this->getAttributeById($attributeId)); - } - $this->_usedProductAttributeIds = $ids; - return $this; - } - - /** - * Retrieve identifiers of used product attributes - * - * @return array - */ - public function getUsedProductAttributeIds() - { - if (is_null($this->_usedProductAttributeIds)) { - $this->_usedProductAttributeIds = array(); - foreach ($this->getUsedProductAttributes() as $attribute) { - $this->_usedProductAttributeIds[] = $attribute->getId(); - } - } - return $this->_usedProductAttributeIds; - } - - /** - * Retrieve used product attributes - * - * @return array - */ - public function getUsedProductAttributes() - { - if (is_null($this->_usedProductAttributes)) { - $this->_usedProductAttributes = array(); - $this->_usedAttributes = array(); - foreach ($this->getConfigurableAttributes() as $attribute) { - $id = $attribute->getProductAttribute()->getId(); - $this->_usedProductAttributes[$id] = $attribute->getProductAttribute(); - $this->_usedAttributes[$id] = $attribute; - } - } - return $this->_usedProductAttributes; - } - - /** - * Retrieve configurable attrbutes data - * - * @return array - */ - public function getConfigurableAttributes() - { - Varien_Profiler::start('CONFIGURABLE:'.__METHOD__); - if (is_null($this->_configurableAttributes)) { - $this->_configurableAttributes = $this->getConfigurableAttributeCollection() - ->orderByPosition() - ->load(); - - } - Varien_Profiler::stop('CONFIGURABLE:'.__METHOD__); - return $this->_configurableAttributes; - } - - public function getConfigurableAttributesAsArray() - { - $res = array(); - foreach ($this->getConfigurableAttributes() as $attribute) { - $label = $attribute->getLabel() ? $attribute->getLabel() : $attribute->getProductAttribute()->getFrontend()->getLabel(); - $res[] = array( - 'id' => $attribute->getId(), - 'label' => $label, - 'position' => $attribute->getPosition(), - 'values' => $attribute->getPrices() ? $attribute->getPrices() : array(), - 'attribute_id' => $attribute->getProductAttribute()->getId(), - 'attribute_code'=> $attribute->getProductAttribute()->getAttributeCode(), - 'frontend_label'=> $attribute->getProductAttribute()->getFrontend()->getLabel(), - ); - } - return $res; - } - - public function getConfigurableAttributeCollection() - { - return Mage::getResourceModel('catalog/product_type_configurable_attribute_collection') - ->setProductFilter($this->getProduct()); - } - - - /** - * Retrieve subproducts identifiers - * - * @return array - */ - public function getUsedProductIds() - { - if (is_null($this->_usedProductIds)) { - $this->_usedProductIds = array(); - foreach ($this->getUsedProducts() as $product) { - $this->_usedProductIds[] = $product->getId(); - } - } - return $this->_usedProductIds; - } - - /** - * Retrieve array of "subproducts" - * - * @return array - */ - public function getUsedProducts($requiredAttributeIds=null) - { - Varien_Profiler::start('CONFIGURABLE:'.__METHOD__); - if (is_null($this->_usedProducts)) { - if (is_null($requiredAttributeIds) && is_null($this->_configurableAttributes)) { - // If used products load before attributes, we will load attributes. - $this->getConfigurableAttributes(); - // After attributes loading products loaded too. - return $this->_usedProducts; - } - - $this->_usedProducts = array(); - $collection = $this->getUsedProductCollection() - ->addAttributeToSelect('*') - ->addFilterByRequiredOptions(); - - if (is_array($requiredAttributeIds)) { - foreach ($requiredAttributeIds as $attributeId) { - $attribute = $this->getAttributeById($attributeId); - if (!is_null($attribute)) - $collection->addAttributeToFilter($attribute->getAttributeCode(), array('notnull'=>1)); - } - } - - foreach ($collection as $product) { - $this->_usedProducts[] = $product; - } - } - Varien_Profiler::stop('CONFIGURABLE:'.__METHOD__); - return $this->_usedProducts; - } - - /** - * Retrieve related products collection - * - * @return unknown - */ - public function getUsedProductCollection() - { - $collection = Mage::getResourceModel('catalog/product_type_configurable_product_collection') - ->setProductFilter($this->getProduct()); - if (!is_null($this->getStoreFilter())) { - $collection->addStoreFilter($this->getStoreFilter()); - } - return $collection; - } - - public function beforeSave() - { - parent::beforeSave(); - - $this->getProduct()->canAffectOptions(false); - - if ($this->getProduct()->getCanSaveConfigurableAttributes()) { - $this->getProduct()->canAffectOptions(true); - if ($data = $this->getProduct()->getConfigurableAttributesData()) { - if (!empty($data)) { - foreach ($data as $attribute) { - if (!empty($attribute['values'])) { - $this->getProduct()->setTypeHasOptions(true); - $this->getProduct()->setTypeHasRequiredOptions(true); - break; - } - } - } - } - } - } - - /** - * Save configurable product depended data - * - * @return Mage_Catalog_Model_Product_Type_Configurable - */ - public function save() - { - parent::save(); - /** - * Save Attributes Information - */ - if ($data = $this->getProduct()->getConfigurableAttributesData()) { - foreach ($data as $attributeData) { - $id = isset($attributeData['id']) ? $attributeData['id'] : null; - $attribute = Mage::getModel('catalog/product_type_configurable_attribute') - ->setData($attributeData) - ->setId($id) - ->setStoreId($this->getProduct()->getStoreId()) - ->setProductId($this->getProduct()->getId()) - ->save(); - } - } - - /** - * Save product relations - */ - $data = $this->getProduct()->getConfigurableProductsData(); - if (is_array($data)) { - $productIds = array_keys($data); - Mage::getResourceModel('catalog/product_type_configurable') - ->saveProducts($this->getProduct()->getId(), $productIds); - } - return $this; - } - - /** - * Check is product available for sale - * - * @return bool - */ - public function isSalable() - { - $salable = parent::isSalable(); - if (!is_null($salable)) { - return $salable; - } - - $salable = false; - foreach ($this->getUsedProducts() as $product) { - $salable = $salable || $product->isSalable(); - } - return $salable; - } - - /** - * Retrieve used product by attribute values - * $attrbutesInfo = array( - * $attributeId => $attributeValue - * ) - * @param array $attrbutesInfo - * @return - */ - public function getProductByAttributes($attributesInfo) - { - foreach ($this->getUsedProducts() as $product) { - $checkRes = true; - foreach ($attributesInfo as $attributeId => $attributeValue) { - $code = $this->getAttributeById($attributeId)->getAttributeCode(); - if ($product->getData($code) != $attributeValue) { - $checkRes = false; - } - } - if ($checkRes) { - return $product; - } - } - return null; - } - - public function getSelectedAttributesInfo() - { - $attributes = array(); - Varien_Profiler::start('CONFIGURABLE:'.__METHOD__); - if ($attributesOption = $this->getProduct()->getCustomOption('attributes')) { - $data = unserialize($attributesOption->getValue()); - $this->getUsedProductAttributeIds(); - - foreach ($data as $attributeId => $attributeValue) { - if (isset($this->_usedAttributes[$attributeId])) { - $attribute = $this->_usedAttributes[$attributeId]; - $label = $attribute->getLabel(); - $value = $attribute->getProductAttribute(); - if ($value->getSourceModel()) { - $value = $value->getSource()->getOptionText($attributeValue); - } - else { - $value = ''; - } - - $attributes[] = array('label'=>$label, 'value'=>$value); - } - } - } - Varien_Profiler::stop('CONFIGURABLE:'.__METHOD__); - return $attributes; - } - - /** - * Initialize product(s) for add to cart process - * - * @param Varien_Object $buyRequest - * @return unknown - */ - public function prepareForCart(Varien_Object $buyRequest) - { - if ($attributes = $buyRequest->getSuperAttribute()) { - $result = parent::prepareForCart($buyRequest); - if (is_array($result)) { - $product = $this->getProduct(); - /** - * $attributes = array($attributeId=>$attributeValue) - */ - if ($subProduct = $this->getProductByAttributes($attributes)) { - $product->addCustomOption('attributes', serialize($attributes)); - $product->addCustomOption('product_qty_'.$subProduct->getId(), 1, $subProduct); - $product->addCustomOption('simple_product', $subProduct->getId(), $subProduct); - - $_result = $subProduct->getTypeInstance()->prepareForCart($buyRequest); - if (is_string($_result) && !is_array($_result)) { - return $_result; - } - - if (!isset($_result[0])) { - return Mage::helper('checkout')->__('Can not add item to shopping cart'); - } - - $_result[0]->setParentProductId($product->getId()) - ->setCartQty(1); - - $result[] = $_result[0]; - - return $result; - } - } - } - return Mage::helper('catalog')->__('Please specify the product option(s)'); - } - - /** - * Prepare additional options/information for order item which will be - * created from this product - * - * @return attay - */ - public function getOrderOptions() - { - $options = parent::getOrderOptions(); - $options['attributes_info'] = $this->getSelectedAttributesInfo(); - if ($simpleOption = $this->getProduct()->getCustomOption('simple_product')) { - $options['simple_name'] = $simpleOption->getProduct()->getName(); - $options['simple_sku'] = $simpleOption->getProduct()->getSku(); - } - - $options['product_calculations'] = self::CALCULATE_PARENT; - $options['shipment_type'] = self::SHIPMENT_TOGETHER; - - return $options; - } - - /** - * Check is virtual product - * - * @return bool - */ - public function isVirtual() - { - if ($productOption = $this->getProduct()->getCustomOption('simple_product')) { - if ($product = $productOption->getProduct()) { - /* @var $product Mage_Catalog_Model_Product */ - return $product->getTypeInstance()->isVirtual(); - } - } - return parent::isVirtual(); - } - - /** - * Return true if product has options - * - * @return bool - */ - public function hasOptions() - { - if ($this->getProduct()->getOptions()) { - return true; - } - - $attributes = $this->getConfigurableAttributes(); - if (count($attributes)) { - foreach ($attributes as $key => $attribute) { - /** @var Mage_Catalog_Model_Product_Type_Configurable_Attribute $attribute */ - if ($attribute->getData('prices')) { - return true; - } - } - } - - return false; - } - - /** - * Return product weight based on simple product - * weight or configurable product weight - * - * @return decimal - */ - public function getWeight() - { - if ($this->getProduct()->hasCustomOptions() && ($simpleProductOption = $this->getProduct()->getCustomOption('simple_product'))) { - $simpleProduct = $simpleProductOption->getProduct(); - if ($simpleProduct) { - return $simpleProduct->getWeight(); - } - } - - return $this->getProduct()->getData('weight'); - } - - /** - * Implementation of product specify logic of which product needs to be assigned to option. - * For example if product which was added to option already removed from catalog. - * - * @param Mage_Catalog_Model_Product $optionProduct - * @param Mage_Sales_Model_Quote_Item_Option $option - * @return Mage_Catalog_Model_Product_Type_Abstract - */ - public function assignProductToOption($optionProduct, $option) - { - if ($optionProduct) { - $option->setProduct($optionProduct); - } else { - $option->getItem()->setHasError('error'); - $option->getItem()->addMessage(Mage::helper('catalog')->__('Selected configuration is not available.', $this->getProduct()->getName())); - } - - return $this; - } -} + + */ +class Mage_Catalog_Model_Product_Type_Configurable extends Mage_Catalog_Model_Product_Type_Abstract +{ + const TYPE_CODE = 'configurable'; + /** + * Attributes which used for configurable product + * + * @var array + */ + protected $_usedProductAttributeIds = null; + protected $_usedProductAttributes = null; + protected $_usedAttributes = null; + protected $_configurableAttributes = null; + protected $_usedProductIds = null; + protected $_usedProducts = null; + + protected $_isComposite = true; + + /** + * Return relation info about used products + * + * @return Varien_Object Object with information data + */ + public function getRelationInfo() + { + $info = new Varien_Object(); + $info->setTable('catalog/product_super_link') + ->setParentFieldName('parent_id') + ->setChildFieldName('product_id'); + return $info; + } + + /** + * Retrieve Required children ids + * Return grouped array, ex array( + * group => array(ids) + * ) + * + * @param int $parentId + * @param bool $required + * @return array + */ + public function getChildrenIds($parentId, $required = true) + { + return Mage::getResourceSingleton('catalog/product_type_configurable') + ->getChildrenIds($parentId, $required); + } + + /** + * Retrieve parent ids array by requered child + * + * @param int $childId + * @return array + */ + public function getParentIdsByChild($childId) + { + return Mage::getResourceSingleton('catalog/product_type_configurable') + ->getParentIdsByChild($childId); + } + + /** + * Retrieve product type attributes + * + * @return array + */ + public function getEditableAttributes() + { + if (is_null($this->_editableAttributes)) { + $this->_editableAttributes = parent::getEditableAttributes(); + foreach ($this->_editableAttributes as $index => $attribute) { + if ($this->getUsedProductAttributeIds() + && in_array($attribute->getAttributeId(), $this->getUsedProductAttributeIds())) { + unset($this->_editableAttributes[$index]); + } + } + } + return $this->_editableAttributes; + } + + /** + * Checkin attribute availability for create superproduct + * + * @param Mage_Eav_Model_Entity_Attribute $attribute + * @return bool + */ + public function canUseAttribute(Mage_Eav_Model_Entity_Attribute $attribute) + { + $allow = $attribute->getIsGlobal() == Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL + && $attribute->getIsVisible() + && $attribute->getIsConfigurable() + && $attribute->usesSource(); + + return $allow; + } + + /** + * Declare attribute identifiers used for asign subproducts + * + * @param array $ids + * @return Mage_Catalog_Model_Product_Type_Configurable + */ + public function setUsedProductAttributeIds($ids) + { + $this->_usedProductAttributes = array(); + $this->_configurableAttributes= array(); + + foreach ($ids as $attributeId) { + $this->_usedProductAttributes[] = $this->getAttributeById($attributeId); + $this->_configurableAttributes[]= Mage::getModel('catalog/product_type_configurable_attribute') + ->setProductAttribute($this->getAttributeById($attributeId)); + } + $this->_usedProductAttributeIds = $ids; + return $this; + } + + /** + * Retrieve identifiers of used product attributes + * + * @return array + */ + public function getUsedProductAttributeIds() + { + if (is_null($this->_usedProductAttributeIds)) { + $this->_usedProductAttributeIds = array(); + foreach ($this->getUsedProductAttributes() as $attribute) { + $this->_usedProductAttributeIds[] = $attribute->getId(); + } + } + return $this->_usedProductAttributeIds; + } + + /** + * Retrieve used product attributes + * + * @return array + */ + public function getUsedProductAttributes() + { + if (is_null($this->_usedProductAttributes)) { + $this->_usedProductAttributes = array(); + $this->_usedAttributes = array(); + foreach ($this->getConfigurableAttributes() as $attribute) { + $id = $attribute->getProductAttribute()->getId(); + $this->_usedProductAttributes[$id] = $attribute->getProductAttribute(); + $this->_usedAttributes[$id] = $attribute; + } + } + return $this->_usedProductAttributes; + } + + /** + * Retrieve configurable attrbutes data + * + * @return array + */ + public function getConfigurableAttributes() + { + Varien_Profiler::start('CONFIGURABLE:'.__METHOD__); + if (is_null($this->_configurableAttributes)) { + $this->_configurableAttributes = $this->getConfigurableAttributeCollection() + ->orderByPosition() + ->load(); + + } + Varien_Profiler::stop('CONFIGURABLE:'.__METHOD__); + return $this->_configurableAttributes; + } + + public function getConfigurableAttributesAsArray() + { + $res = array(); + foreach ($this->getConfigurableAttributes() as $attribute) { + $label = $attribute->getLabel() ? $attribute->getLabel() : $attribute->getProductAttribute()->getFrontend()->getLabel(); + $res[] = array( + 'id' => $attribute->getId(), + 'label' => $label, + 'position' => $attribute->getPosition(), + 'values' => $attribute->getPrices() ? $attribute->getPrices() : array(), + 'attribute_id' => $attribute->getProductAttribute()->getId(), + 'attribute_code'=> $attribute->getProductAttribute()->getAttributeCode(), + 'frontend_label'=> $attribute->getProductAttribute()->getFrontend()->getLabel(), + ); + } + return $res; + } + + public function getConfigurableAttributeCollection() + { + return Mage::getResourceModel('catalog/product_type_configurable_attribute_collection') + ->setProductFilter($this->getProduct()); + } + + + /** + * Retrieve subproducts identifiers + * + * @return array + */ + public function getUsedProductIds() + { + if (is_null($this->_usedProductIds)) { + $this->_usedProductIds = array(); + foreach ($this->getUsedProducts() as $product) { + $this->_usedProductIds[] = $product->getId(); + } + } + return $this->_usedProductIds; + } + + /** + * Retrieve array of "subproducts" + * + * @return array + */ + public function getUsedProducts($requiredAttributeIds=null) + { + Varien_Profiler::start('CONFIGURABLE:'.__METHOD__); + if (is_null($this->_usedProducts)) { + if (is_null($requiredAttributeIds) && is_null($this->_configurableAttributes)) { + // If used products load before attributes, we will load attributes. + $this->getConfigurableAttributes(); + // After attributes loading products loaded too. + return $this->_usedProducts; + } + + $this->_usedProducts = array(); + $collection = $this->getUsedProductCollection() + ->addAttributeToSelect('*') + ->addFilterByRequiredOptions(); + + if (is_array($requiredAttributeIds)) { + foreach ($requiredAttributeIds as $attributeId) { + $attribute = $this->getAttributeById($attributeId); + if (!is_null($attribute)) + $collection->addAttributeToFilter($attribute->getAttributeCode(), array('notnull'=>1)); + } + } + + foreach ($collection as $product) { + $this->_usedProducts[] = $product; + } + } + Varien_Profiler::stop('CONFIGURABLE:'.__METHOD__); + return $this->_usedProducts; + } + + /** + * Retrieve related products collection + * + * @return unknown + */ + public function getUsedProductCollection() + { + $collection = Mage::getResourceModel('catalog/product_type_configurable_product_collection') + ->setProductFilter($this->getProduct()); + if (!is_null($this->getStoreFilter())) { + $collection->addStoreFilter($this->getStoreFilter()); + } + return $collection; + } + + public function beforeSave() + { + parent::beforeSave(); + + $this->getProduct()->canAffectOptions(false); + + if ($this->getProduct()->getCanSaveConfigurableAttributes()) { + $this->getProduct()->canAffectOptions(true); + if ($data = $this->getProduct()->getConfigurableAttributesData()) { + if (!empty($data)) { + foreach ($data as $attribute) { + if (!empty($attribute['values'])) { + $this->getProduct()->setTypeHasOptions(true); + $this->getProduct()->setTypeHasRequiredOptions(true); + break; + } + } + } + } + } + } + + /** + * Save configurable product depended data + * + * @return Mage_Catalog_Model_Product_Type_Configurable + */ + public function save() + { + parent::save(); + /** + * Save Attributes Information + */ + if ($data = $this->getProduct()->getConfigurableAttributesData()) { + foreach ($data as $attributeData) { + $id = isset($attributeData['id']) ? $attributeData['id'] : null; + $attribute = Mage::getModel('catalog/product_type_configurable_attribute') + ->setData($attributeData) + ->setId($id) + ->setStoreId($this->getProduct()->getStoreId()) + ->setProductId($this->getProduct()->getId()) + ->save(); + } + } + + /** + * Save product relations + */ + $data = $this->getProduct()->getConfigurableProductsData(); + if (is_array($data)) { + $productIds = array_keys($data); + Mage::getResourceModel('catalog/product_type_configurable') + ->saveProducts($this->getProduct()->getId(), $productIds); + } + return $this; + } + + /** + * Check is product available for sale + * + * @return bool + */ + public function isSalable() + { + $salable = parent::isSalable(); + if (!is_null($salable)) { + return $salable; + } + + $salable = false; + foreach ($this->getUsedProducts() as $product) { + $salable = $salable || $product->isSalable(); + } + return $salable; + } + + /** + * Retrieve used product by attribute values + * $attrbutesInfo = array( + * $attributeId => $attributeValue + * ) + * @param array $attrbutesInfo + * @return + */ + public function getProductByAttributes($attributesInfo) + { + foreach ($this->getUsedProducts() as $product) { + $checkRes = true; + foreach ($attributesInfo as $attributeId => $attributeValue) { + $code = $this->getAttributeById($attributeId)->getAttributeCode(); + if ($product->getData($code) != $attributeValue) { + $checkRes = false; + } + } + if ($checkRes) { + return $product; + } + } + return null; + } + + public function getSelectedAttributesInfo() + { + $attributes = array(); + Varien_Profiler::start('CONFIGURABLE:'.__METHOD__); + if ($attributesOption = $this->getProduct()->getCustomOption('attributes')) { + $data = unserialize($attributesOption->getValue()); + $this->getUsedProductAttributeIds(); + + foreach ($data as $attributeId => $attributeValue) { + if (isset($this->_usedAttributes[$attributeId])) { + $attribute = $this->_usedAttributes[$attributeId]; + $label = $attribute->getLabel(); + $value = $attribute->getProductAttribute(); + if ($value->getSourceModel()) { + $value = $value->getSource()->getOptionText($attributeValue); + } + else { + $value = ''; + } + + $attributes[] = array('label'=>$label, 'value'=>$value); + } + } + } + Varien_Profiler::stop('CONFIGURABLE:'.__METHOD__); + return $attributes; + } + + /** + * Initialize product(s) for add to cart process + * + * @param Varien_Object $buyRequest + * @return unknown + */ + public function prepareForCart(Varien_Object $buyRequest) + { + if ($attributes = $buyRequest->getSuperAttribute()) { + $result = parent::prepareForCart($buyRequest); + if (is_array($result)) { + $product = $this->getProduct(); + /** + * $attributes = array($attributeId=>$attributeValue) + */ + if ($subProduct = $this->getProductByAttributes($attributes)) { + $product->addCustomOption('attributes', serialize($attributes)); + $product->addCustomOption('product_qty_'.$subProduct->getId(), 1, $subProduct); + $product->addCustomOption('simple_product', $subProduct->getId(), $subProduct); + + $_result = $subProduct->getTypeInstance()->prepareForCart($buyRequest); + if (is_string($_result) && !is_array($_result)) { + return $_result; + } + + if (!isset($_result[0])) { + return Mage::helper('checkout')->__('Can not add item to shopping cart'); + } + + /** + * Adding parent product custom options to child product + * to be sure that it will be unique as its parent + */ + if ($optionIds = $product->getCustomOption('option_ids')) { + $optionIds = explode(',', $optionIds->getValue()); + foreach ($optionIds as $optionId) { + if ($option = $product->getCustomOption('option_' . $optionId)) { + $_result[0]->addCustomOption('option_' . $optionId, $option->getValue()); + } + } + } + + $_result[0]->setParentProductId($product->getId()) + ->setCartQty(1); + + $result[] = $_result[0]; + + return $result; + } + } + } + return Mage::helper('catalog')->__('Please specify the product option(s)'); + } + + /** + * Prepare additional options/information for order item which will be + * created from this product + * + * @return attay + */ + public function getOrderOptions() + { + $options = parent::getOrderOptions(); + $options['attributes_info'] = $this->getSelectedAttributesInfo(); + if ($simpleOption = $this->getProduct()->getCustomOption('simple_product')) { + $options['simple_name'] = $simpleOption->getProduct()->getName(); + $options['simple_sku'] = $simpleOption->getProduct()->getSku(); + } + + $options['product_calculations'] = self::CALCULATE_PARENT; + $options['shipment_type'] = self::SHIPMENT_TOGETHER; + + return $options; + } + + /** + * Check is virtual product + * + * @return bool + */ + public function isVirtual() + { + if ($productOption = $this->getProduct()->getCustomOption('simple_product')) { + if ($product = $productOption->getProduct()) { + /* @var $product Mage_Catalog_Model_Product */ + return $product->getTypeInstance()->isVirtual(); + } + } + return parent::isVirtual(); + } + + /** + * Return true if product has options + * + * @return bool + */ + public function hasOptions() + { + if ($this->getProduct()->getOptions()) { + return true; + } + + $attributes = $this->getConfigurableAttributes(); + if (count($attributes)) { + foreach ($attributes as $key => $attribute) { + /** @var Mage_Catalog_Model_Product_Type_Configurable_Attribute $attribute */ + if ($attribute->getData('prices')) { + return true; + } + } + } + + return false; + } + + /** + * Return product weight based on simple product + * weight or configurable product weight + * + * @return decimal + */ + public function getWeight() + { + if ($this->getProduct()->hasCustomOptions() && ($simpleProductOption = $this->getProduct()->getCustomOption('simple_product'))) { + $simpleProduct = $simpleProductOption->getProduct(); + if ($simpleProduct) { + return $simpleProduct->getWeight(); + } + } + + return $this->getProduct()->getData('weight'); + } + + /** + * Implementation of product specify logic of which product needs to be assigned to option. + * For example if product which was added to option already removed from catalog. + * + * @param Mage_Catalog_Model_Product $optionProduct + * @param Mage_Sales_Model_Quote_Item_Option $option + * @return Mage_Catalog_Model_Product_Type_Abstract + */ + public function assignProductToOption($optionProduct, $option) + { + if ($optionProduct) { + $option->setProduct($optionProduct); + } else { + $option->getItem()->setHasError('error'); + $option->getItem()->addMessage(Mage::helper('catalog')->__('Selected configuration is not available.', $this->getProduct()->getName())); + } + + return $this; + } +} diff --git a/app/code/core/Mage/Catalog/etc/config.xml b/app/code/core/Mage/Catalog/etc/config.xml index 653e981708..b643d5cd15 100644 --- a/app/code/core/Mage/Catalog/etc/config.xml +++ b/app/code/core/Mage/Catalog/etc/config.xml @@ -218,10 +218,12 @@ catalog/product_type_simple 10 + 0 catalog/product_type_grouped + 1 @@ -232,6 +234,7 @@ catalog/product_type_configurable catalog/product_type_configurable_price + 1 @@ -242,12 +245,8 @@ catalog/product_type_virtual 20 + 0 - - - downloadable/catalog_product_type - downloadable/catalog_product_price - diff --git a/app/code/core/Mage/Checkout/Helper/Data.php b/app/code/core/Mage/Checkout/Helper/Data.php index 20fbe99e12..842b446556 100644 --- a/app/code/core/Mage/Checkout/Helper/Data.php +++ b/app/code/core/Mage/Checkout/Helper/Data.php @@ -105,8 +105,23 @@ public function getPriceInclTax($item) public function getSubtotalInclTax($item) { - $tax = ($item->getTaxBeforeDiscount() ? $item->getTaxBeforeDiscount() : $item->getTaxAmount()); - return $item->getRowTotal()+$tax; + if ($item instanceof Mage_Sales_Model_Order_Item) { + $store = $item->getOrder()->getStore(); + } elseif($item instanceof Mage_Sales_Model_Order_Invoice_Item) { + $store = $item->getInvoice()->getOrder()->getStore(); + } elseif($item instanceof Mage_Sales_Model_Order_Shipment_Item) { + $store = $item->getShipment()->getOrder()->getStore(); + } elseif($item instanceof Mage_Sales_Model_Order_Creditmemo_Item) { + $store = $item->getCreditmemo()->getOrder()->getStore(); + } else { + $store = $item->getQuote()->getStore(); + } + if (!Mage::helper('tax')->applyTaxAfterDiscount($store) and $item->getTaxBeforeDiscount()) { + $tax = $item->getTaxBeforeDiscount(); + } else { + $tax = $item->getTaxAmount(); + } + return $item->getRowTotal() + $tax; } public function getBasePriceInclTax($item) diff --git a/app/code/core/Mage/Downloadable/Model/Product/Type.php b/app/code/core/Mage/Downloadable/Model/Product/Type.php index 8365170df3..dfcb8477c5 100644 --- a/app/code/core/Mage/Downloadable/Model/Product/Type.php +++ b/app/code/core/Mage/Downloadable/Model/Product/Type.php @@ -224,6 +224,9 @@ public function save() ->setProductId($product->getId()) ->setStoreId($product->getStoreId()) ->setWebsiteId($product->getStore()->getWebsiteId()); + if (null === $linkModel->getPrice()) { + $linkModel->setPrice(0); + } if ($linkModel->getIsUnlimited()) { $linkModel->setNumberOfDownloads(0); } @@ -296,6 +299,10 @@ public function prepareForCart(Varien_Object $buyRequest) if (is_string($result)) { return $result; } + // if adding product from admin area we add all links to product + if ($this->getProduct()->getSkipCheckRequiredOption()) { + $this->getProduct()->setLinksPurchasedSeparately(false); + } $preparedLinks = array(); if ($this->getProduct()->getLinksPurchasedSeparately()) { if ($links = $buyRequest->getLinks()) { @@ -351,7 +358,6 @@ public function beforeSave() { parent::beforeSave(); - $this->getProduct()->canAffectOptions(true); if ($this->getLinkSelectionRequired()) { $this->getProduct()->setTypeHasOptions(true); diff --git a/app/code/core/Mage/Downloadable/etc/config.xml b/app/code/core/Mage/Downloadable/etc/config.xml index 4df3641f80..27234781b0 100644 --- a/app/code/core/Mage/Downloadable/etc/config.xml +++ b/app/code/core/Mage/Downloadable/etc/config.xml @@ -132,6 +132,7 @@ 1 downloadable/product_price downloadable/catalogIndex_data_downloadable + 0 @@ -788,6 +789,15 @@ + + + + + + + + + diff --git a/app/code/core/Mage/GoogleBase/Model/Attribute.php b/app/code/core/Mage/GoogleBase/Model/Attribute.php index 78118241e8..e6c56090b7 100644 --- a/app/code/core/Mage/GoogleBase/Model/Attribute.php +++ b/app/code/core/Mage/GoogleBase/Model/Attribute.php @@ -41,7 +41,7 @@ class Mage_GoogleBase_Model_Attribute extends Mage_Core_Model_Abstract protected $_ignoredAttributeCodes = array( 'custom_design','custom_design_from','custom_design_to','custom_layout_update', 'gift_message_available','news_from_date','news_to_date','options_container', - 'price_view','sku_type' + 'price','price_view','sku_type' ); /** diff --git a/app/code/core/Mage/GoogleBase/Model/Config.php b/app/code/core/Mage/GoogleBase/Model/Config.php index 11e698aa46..2328c50b32 100644 --- a/app/code/core/Mage/GoogleBase/Model/Config.php +++ b/app/code/core/Mage/GoogleBase/Model/Config.php @@ -71,6 +71,17 @@ public function getAccountPassword($storeId = null) return $this->getConfigData('password', $storeId); } + /** + * Google Account target country info + * + * @param int $storeId + * @return array + */ + public function getTargetCountryInfo($storeId = null) + { + return $this->getCountryInfo($this->getTargetCountry($storeId), null, $storeId); + } + /** * Google Account target country * @@ -82,6 +93,29 @@ public function getTargetCountry($storeId = null) return $this->getConfigData('target_country', $storeId); } + /** + * Google Account target currency (for target country) + * + * @param int $storeId + * @return string Three-letters currency ISO code + */ + public function getTargetCurrency($storeId = null) + { + $country = $this->getTargetCountry($storeId); + return $this->getCountryInfo($country, 'currency'); + } + + /** + * Check whether System Base currency equals Google Base target currency or not + * + * @param int $storeId + * @return boolean + */ + public function isValidBaseCurrencyCode($storeId = null) + { + return Mage::app()->getBaseCurrencyCode() == $this->getTargetCurrency($storeId); + } + /** * Default Item Type for country * diff --git a/app/code/core/Mage/GoogleBase/Model/Service/Item.php b/app/code/core/Mage/GoogleBase/Model/Service/Item.php index 303363c912..ea4decefa6 100644 --- a/app/code/core/Mage/GoogleBase/Model/Service/Item.php +++ b/app/code/core/Mage/GoogleBase/Model/Service/Item.php @@ -271,16 +271,23 @@ protected function _setUniversalData() $entry->setContent($content); } - if ($this->_getItemType() == 'products') { - $quantity = $object->getQuantity() ? max(1, (int)$object->getQuantity()) : 1; - $this->_setAttribute('quantity', $quantity, 'int'); + $targetCountry = $this->getConfig()->getTargetCountry($this->getStoreId()); + + if ($this->_getItemType() == $this->getConfig()->getDefaultItemType($this->getStoreId())) { + $this->_setAttribute( + $this->getConfig()->getCountryInfo($targetCountry, 'price_attribute_name', $this->getStoreId()), + sprintf('%.2f', $object->getPrice()), + 'floatUnit' + ); + + $quantity = $object->getQuantity() ? max(1, (int)$object->getQuantity()) : 1; + $this->_setAttribute('quantity', $quantity, 'int'); } if ($object->getImageUrl()) { $this->_setAttribute('image_link', $object->getImageUrl(), 'url'); } - $targetCountry = $this->getConfig()->getTargetCountry($this->getStoreId()); $this->_setAttribute('target_country', $targetCountry, 'text'); $this->_setAttribute('item_language', $this->getConfig()->getCountryInfo($targetCountry, 'language'), 'text'); diff --git a/app/code/core/Mage/GoogleBase/controllers/ItemsController.php b/app/code/core/Mage/GoogleBase/controllers/ItemsController.php index fd7187f277..00f46cb46b 100644 --- a/app/code/core/Mage/GoogleBase/controllers/ItemsController.php +++ b/app/code/core/Mage/GoogleBase/controllers/ItemsController.php @@ -56,6 +56,17 @@ public function indexAction() ); } + if (!$this->_getConfig()->isValidBaseCurrencyCode($this->_getStore()->getId())) { + $_countryInfo = $this->_getConfig()->getTargetCountryInfo($this->_getStore()->getId()); + $this->_getSession()->addNotice( + $this->__( + "Base Currency should be set to %s for %s in system configuration. Otherwise item prices won't be correct in Google Base.", + $_countryInfo['currency_name'], + $_countryInfo['name'] + ) + ); + } + $this->_initAction() ->_addBreadcrumb(Mage::helper('googlebase')->__('Items'), Mage::helper('googlebase')->__('Items')) ->_addContent($contentBlock) @@ -318,8 +329,13 @@ public function _getStore() return Mage::app()->getStore($storeId); } + protected function _getConfig() + { + return Mage::getSingleton('googlebase/config'); + } + protected function _isAllowed() { return Mage::getSingleton('admin/session')->isAllowed('catalog/googlebase/items'); } -} \ No newline at end of file +} diff --git a/app/code/core/Mage/GoogleBase/etc/config.xml b/app/code/core/Mage/GoogleBase/etc/config.xml index b68be3e5c7..48b47b9d06 100644 --- a/app/code/core/Mage/GoogleBase/etc/config.xml +++ b/app/code/core/Mage/GoogleBase/etc/config.xml @@ -194,23 +194,32 @@ US - + United States EN en_US + USD + US Dollar products + price - + United Kingdom EN en_GB + GBP + British Pound Sterling products + price - + Germany DE de_DE + EUR + Euro produkte + preis diff --git a/app/code/core/Mage/GoogleCheckout/Block/Link.php b/app/code/core/Mage/GoogleCheckout/Block/Link.php index 75c6668acf..161bcb4afb 100644 --- a/app/code/core/Mage/GoogleCheckout/Block/Link.php +++ b/app/code/core/Mage/GoogleCheckout/Block/Link.php @@ -93,7 +93,7 @@ public function getIsDisabled() /* @var $quote Mage_Sales_Model_Quote */ foreach ($quote->getAllVisibleItems() as $item) { /* @var $item Mage_Sales_Model_Quote_Item */ - if ($item->getProduct()->getDisableGooglecheckout()) { + if (!$item->getProduct()->getEnableGooglecheckout()) { return true; } } diff --git a/app/code/core/Mage/GoogleCheckout/etc/config.xml b/app/code/core/Mage/GoogleCheckout/etc/config.xml index a719f4cc42..e1c8c802c3 100644 --- a/app/code/core/Mage/GoogleCheckout/etc/config.xml +++ b/app/code/core/Mage/GoogleCheckout/etc/config.xml @@ -28,16 +28,16 @@ - 0.7.1 + 0.7.3 - - - + + + diff --git a/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-install-0.7.0.php b/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-install-0.7.0.php index 413c72585e..5f74c032c9 100644 --- a/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-install-0.7.0.php +++ b/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-install-0.7.0.php @@ -25,7 +25,7 @@ */ $installer = $this; -/* @var $installer Mage_Core_Model_Resource_Setup */ +/* @var $installer Mage_GoogleCheckout_Model_Mysql4_Setup */ $installer->startSetup(); diff --git a/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-upgrade-0.7.0-0.7.1.php b/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-upgrade-0.7.0-0.7.1.php index 8bb8a07d3f..427254a71f 100644 --- a/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-upgrade-0.7.0-0.7.1.php +++ b/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-upgrade-0.7.0-0.7.1.php @@ -19,13 +19,13 @@ * needs please refer to http://www.magentocommerce.com for more information. * * @category Mage - * @package Mage_Catalog + * @package Mage_GoogleCheckout * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ $installer = $this; -/* @var $installer Mage_Eav_Model_Entity_Setup */ +/* @var $installer Mage_GoogleCheckout_Model_Mysql4_Setup */ $installer->startSetup(); diff --git a/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-upgrade-0.7.1-0.7.2.php b/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-upgrade-0.7.1-0.7.2.php new file mode 100644 index 0000000000..8dfdceedee --- /dev/null +++ b/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-upgrade-0.7.1-0.7.2.php @@ -0,0 +1,46 @@ +startSetup(); + +$installer->updateAttribute('catalog_product', 'disable_googlecheckout', array( + 'attribute_code' => 'enable_googlecheckout', + 'frontend_label' => 'Is product available for purchase with Google Checkout', +)); + +$attribute = $installer->getAttribute('catalog_product', 'enable_googlecheckout'); +if (!empty($attribute['attribute_id'])) { + $installer->run(" + UPDATE `{$installer->getAttributeTable('catalog_product', 'enable_googlecheckout')}` + SET `value` = ! `value` + WHERE `attribute_id` = {$attribute['attribute_id']} + "); +} + +$installer->endSetup(); diff --git a/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-upgrade-0.7.2-0.7.3.php b/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-upgrade-0.7.2-0.7.3.php new file mode 100644 index 0000000000..9e71ca3e9d --- /dev/null +++ b/app/code/core/Mage/GoogleCheckout/sql/googlecheckout_setup/mysql4-upgrade-0.7.2-0.7.3.php @@ -0,0 +1,36 @@ +startSetup(); + +$installer->updateAttribute('catalog_product', 'enable_googlecheckout', array( + 'default_value' => '1', +)); + +$installer->endSetup(); diff --git a/app/code/core/Mage/Payment/Model/Source/Invoice.php b/app/code/core/Mage/Payment/Model/Source/Invoice.php new file mode 100644 index 0000000000..24a6eee73f --- /dev/null +++ b/app/code/core/Mage/Payment/Model/Source/Invoice.php @@ -0,0 +1,47 @@ + + */ +class Mage_Payment_Model_Source_Invoice +{ + public function toOptionArray() + { + return array( + array( + 'value' => Mage_Payment_Model_Method_Abstract::ACTION_AUTHORIZE_CAPTURE, + 'label' => Mage::helper('core')->__('Yes') + ), + array( + 'value' => '', + 'label' => Mage::helper('core')->__('No') + ), + ); + } +} \ No newline at end of file diff --git a/app/code/core/Mage/Payment/etc/system.xml b/app/code/core/Mage/Payment/etc/system.xml index d7ef60781c..2274f1aa21 100644 --- a/app/code/core/Mage/Payment/etc/system.xml +++ b/app/code/core/Mage/Payment/etc/system.xml @@ -249,12 +249,21 @@ select - adminhtml/system_config_source_order_status_new + adminhtml/system_config_source_order_status_newprocessing 2 1 1 0 + + + select + payment/source_invoice + 3 + 1 + 1 + 0 + text diff --git a/app/code/core/Mage/Reports/Model/Mysql4/Product/Collection.php b/app/code/core/Mage/Reports/Model/Mysql4/Product/Collection.php index 2307a6f6d8..bc79a41c6d 100644 --- a/app/code/core/Mage/Reports/Model/Mysql4/Product/Collection.php +++ b/app/code/core/Mage/Reports/Model/Mysql4/Product/Collection.php @@ -187,9 +187,8 @@ public function addOrderedQty($from = '', $to = '') $productIdTableName = $this->getTable('sales/order_item'); $productIdFieldName = 'product_id'; - $productTypes = " AND (e.type_id = '" . - Mage_Catalog_Model_Product_Type::TYPE_SIMPLE . - "' OR e.type_id = '" . Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL . "')"; + $compositeTypeIds = Mage::getSingleton('catalog/product_type')->getCompositeTypes(); + $productTypes = $this->getConnection()->quoteInto(' AND (e.type_id NOT IN (?))', $compositeTypeIds); if ($from != '' && $to != '') { $dateFilter = " AND `order`.created_at BETWEEN '{$from}' AND '{$to}'"; diff --git a/app/code/core/Mage/Sales/Model/Order/Payment.php b/app/code/core/Mage/Sales/Model/Order/Payment.php index 4a008919aa..338a35406a 100644 --- a/app/code/core/Mage/Sales/Model/Order/Payment.php +++ b/app/code/core/Mage/Sales/Model/Order/Payment.php @@ -253,7 +253,10 @@ protected function _invoice() { $invoice = $this->getOrder()->prepareInvoice(); - $invoice->register()->capture(); + $invoice->register(); + if ($this->getMethodInstance()->canCapture()) { + $invoice->capture(); + } $this->getOrder()->addRelatedObject($invoice); return $invoice; diff --git a/app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups.php b/app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups.php index fed3b4d576..c25ef0cdfb 100644 --- a/app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups.php +++ b/app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups.php @@ -625,12 +625,26 @@ protected function _parseXmlResponse($xmlResponse) if($success===1){ $arr = $xml->getXpath("//RatingServiceSelectionResponse/RatedShipment"); $allowedMethods = explode(",", $this->getConfigData('allowed_methods')); + + // Negotiated rates + $negotiatedArr = $xml->getXpath("//RatingServiceSelectionResponse/RatedShipment/NegotiatedRates"); + $negotiatedActive = $this->getConfigFlag('negotiated_active') + && $this->getConfigData('shipper_number') + && !empty($negotiatedArr); + foreach ($arr as $shipElement){ $code = (string)$shipElement->Service->Code; #$shipment = $this->getShipmentByCode($code); if (in_array($code, $allowedMethods)) { - $costArr[$code] = $shipElement->TotalCharges->MonetaryValue; - $priceArr[$code] = $this->getMethodPrice(floatval($shipElement->TotalCharges->MonetaryValue),$code); + + if ($negotiatedActive) { + $cost = $shipElement->NegotiatedRates->NetSummaryCharges->GrandTotal->MonetaryValue; + } else { + $cost = $shipElement->TotalCharges->MonetaryValue; + } + + $costArr[$code] = $cost; + $priceArr[$code] = $this->getMethodPrice(floatval($cost),$code); } } } else { diff --git a/app/design/adminhtml/default/default/layout/downloadable.xml b/app/design/adminhtml/default/default/layout/downloadable.xml index 1bca5838ad..1b21994325 100644 --- a/app/design/adminhtml/default/default/layout/downloadable.xml +++ b/app/design/adminhtml/default/default/layout/downloadable.xml @@ -31,6 +31,7 @@ downloadable_itemsdownloadable/adminhtml_catalog_product_edit_tab_downloadable + downloadable_itemscustomer_options