1

UPDATED:

Ok, I just found out my first if in my method isn't working. This one:

if ($codigo == null) {
    # Stuff 
} else {
    #other stuff
} 

But I also don't know whats wrong.

PREVIOUS:

I have an observer watching the event sales_quote_item_qty_set_after. But when I try to call a method from my helper Data.php, it returns null.

This is my observer:

public function stockUpdate(Varien_Event_Observer $observer)
{
    # Produto
    $event = $observer->getEvent()->getItem()->getProduct();

    if ($event->getAllnationsSync() == 1) {
        $control = Mage::getStoreConfig('allnations/general/id_allnations', Mage::app()->getStore());

        $id = $event->getData($control);
        Mage::helper('novapc_allnations')->updateStock($id);
    }
}

And this is my method:

public static function updateStock($codigo = null)
{
    try {
        # Força o load da página em modo ADMIN
        Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

        # Pega usuario e senha colocados na config
        $apiUser = Mage::getStoreConfig('allnations/general/api_user', Mage::app()->getStore());
        $apiPassword = Mage::getStoreConfig('allnations/general/api_password', Mage::app()->getStore());

        # Model da integração, para pegar a data da ultima atualização
        $integration = Mage::getModel('novapc_allnations/integration');

        $productIntegration = $integration->load(2);
        $integration = $integration->load(3);

        # Checa qual é maior, se é a data da integração dos produtos ou da atualização
        if ($integration->getUpdatedAt() < $productIntegration->getUpdatedAt()) {
            $updatedAt = substr($integration->getUpdatedAt(), 0, 9);
        } else {
            $updatedAt = substr($productIntegration->getUpdatedAt(), 0, 9);
        }

        # Verifica qual o atributo que representa o ID da All Nations
        $control = Mage::getStoreConfig('allnations/general/id_allnations', Mage::app()->getStore());

        # Instancia o model de estoque
        $stockItem = Mage::getModel('cataloginventory/stock_item');

        # Variavel de controle
        $success = 0;

        # Se for chamado sem o parametro $codigo, atualiza todos os produtos
        if ($codigo == null) {
            $ANProducts = Mage::getModel('catalog/product')
                ->getCollection()
                ->addAttributeToSelect('*')
                ->addAttributeToFilter('allnations_sync', ['eq' => 1]);

            foreach ($ANProducts as $single) {
                $id = $single->getData($control); // Pega o ID da All Nations
                $url = 'url' .
                    '?CodigoCliente=' . $apiUser .
                    '&Senha=' . $apiPassword .
                    '&CodigoProduto=' . $id .
                    '&Data=' . $updatedAt;

                $return = Mage::helper('novapc_allnations')->callCurl('GET', $url);
                $httpCode = $return['httpCode']['httpCode'];

                $return = $return['response']['diffgrdiffgram']['NewDataSet']['Estoques'];

                if ($httpCode == '200') {

                    if ($return['CODIGO'] == $single->getData($control)) {

                        if ($single->getData('allnations_promo') == 0) {
                            $single->setPrice
                            ($return['PRECOREVENDA']);
                        } else {
                            $single->setSpecialPrice
                            ($return['PRECOREVENDA']);
                        }

                        $single->save();

                        $stock = $stockItem->loadByProduct($single->getId());
                        $stock->setQty($return['ESTOQUEDISPONIVEL']);
                        $stock->setIsInStock($return['DISPONIVEL']);

                        $stock->save();

                        if ($success != 1) {
                            $success = 1;
                        };
                    }
                } else {
                    return $httpCode;
                }
            }

            if ($success == 1) {
                $firstUpdate = $integration->getData('first_update');

                # Checa se ja foi atualizado antes
                if (!$firstUpdate) {
                    $integration->setFirstUpdate(Mage::getModel('core/date')->gmtDate('Y-m-d H:i:s'));
                    $integration->setUpdatedAt(Mage::getModel('core/date')->gmtDate('Y-m-d H:i:s'));
                    $integration->save();
                } else {
                    $integration->setUpdatedAt(Mage::getModel('core/date')->gmtDate('Y-m-d H:i:s'));
                    $integration->save();
                }

                return $httpCode;
            }
        } else {

            $url = 'url' .
                '?CodigoCliente=' . $apiUser .
                '&Senha=' . $apiPassword .
                '&CodigoProduto=' . $codigo .
                '&Data=' . $updatedAt;

            $return = Mage::helper('novapc_allnations')->callCurl('GET', $url);
            $httpCode = $return['httpCode']['httpCode'];

            if ($httpCode == '200') {

                $product = Mage::getModel('catalog/product')
                    ->loadByAttribute($control, $codigo);


                if ($return['CODIGO'] == $product->getData($control)) {

                    if ($product->getData('allnations_promo') == 0) {
                        $product->setPrice
                        ($return['PRECOREVENDA']);
                    } else {
                        $product->setSpecialPrice
                        ($return['PRECOREVENDA']);
                    }

                    $product->save();

                    $stock = $stockItem->loadByProduct($product->getId());
                    $stock->setQty($return['ESTOQUEDISPONIVEL']);
                    $stock->setIsInStock($return['DISPONIVEL']);

                    $stock->save();

                    return $httpCode;
                }
            }
        }
    } catch (Exception $e) {
        return $e->getMessage();
    }
}

My config.xml:

<?xml version="1.0"?>

<config>
    <modules>
        <Novapc_Allnations>
            <version>0.1.0</version>
        </Novapc_Allnations>
    </modules>
    <global>
        <events>
            <sales_order_save_after>
                <observers>
                    <novapc_allnations>
                        <class>Novapc_Allnations_Model_Observer</class>
                        <method>confirmReserve</method>
                        <type>singleton</type>
                    </novapc_allnations>
                </observers>
            </sales_order_save_after>
            <sales_quote_item_qty_set_after>
                <observers>
                    <novapc_allnations>
                        <class>Novapc_Allnations_Model_Observer</class>
                        <method>stockUpdate</method>
                        <type>singleton</type>
                    </novapc_allnations>
                </observers>
            </sales_quote_item_qty_set_after>
            <admin_system_config_section_save_after>
                <observers>
                    <novapc_allnations>
                        <class>Novapc_Allnations_Model_Observer</class>
                        <method>setAttributes</method>
                        <type>singleton</type>
                    </novapc_allnations>
                </observers>
            </admin_system_config_section_save_after>
            <adminhtml_block_html_before>
                <observers>
                    <novapc_allnations>
                        <class>Novapc_Allnations_Model_Observer</class>
                        <method>updatePromotions</method>
                        <type>singleton</type>
                    </novapc_allnations>
                </observers>
            </adminhtml_block_html_before>
            <adminhtml_block_html_before>
                <observers>
                    <novapc_allnations_order>
                        <class>Novapc_Allnations_Model_Observer</class>
                        <method>updateOrderStatus</method>
                        <type>singleton</type>
                    </novapc_allnations_order>
                </observers>
            </adminhtml_block_html_before>
            <sales_order_place_after>
                <observers>
                    <novapc_allnations>
                        <class>Novapc_Allnations_Model_Observer</class>
                        <method>checkOrder</method>
                        <type>singleton</type>
                    </novapc_allnations>
                </observers>
            </sales_order_place_after>
        </events>
        <resources>
            <novapc_allnations_setup>
                <setup>
                    <module>Novapc_Allnations</module>
                    <class>Novapc_Allnations_Model_Resource_Setup</class>
                </setup>
            </novapc_allnations_setup>
        </resources>
        <blocks>
            <novapc_allnations>
                <class>Novapc_Allnations_Block</class>
            </novapc_allnations>
        </blocks>
        <helpers>
            <novapc_allnations>
                <class>Novapc_Allnations_Helper</class>
            </novapc_allnations>
        </helpers>
        <models>
            <novapc_allnations>
                <class>Novapc_Allnations_Model</class>
                <resourceModel>novapc_allnations_resource</resourceModel>
            </novapc_allnations>
            <novapc_allnations_resource>
                <class>Novapc_Allnations_Model_Resource</class>
                <entities>
                    <order>
                        <table>npcallnations_orders</table>
                    </order>
                    <integration>
                        <table>npcallnations_integrations</table>
                    </integration>
                    <promotion>
                        <table>npcallnations_promotions</table>
                    </promotion>
                    <attr>
                        <table>npcallnations_attributes</table>
                    </attr>
                </entities>
            </novapc_allnations_resource>
        </models>
    </global>
    <default>
        <novapc_allnations>
            <general>
                <status>1</status>
            </general>
        </novapc_allnations>
    </default>
    <adminhtml>
        <layout>
            <updates>
                <novapc_allnations>
                    <file>novapc_allnations.xml</file>
                </novapc_allnations>
            </updates>
        </layout>
        <translate>
            <modules>
                <Novapc_Allnations>
                    <files>
                        <default>Novapc_Allnations.csv</default>
                    </files>
                </Novapc_Allnations>
            </modules>
        </translate>
        <global_search>
            <promotion>
                <class>novapc_allnations/adminhtml_search_promotion</class>
                <acl>novapc_allnations</acl>
            </promotion>
        </global_search>
        <acl>
            <resources>
                <all>
                    <title>Allow Everything</title>
                </all>
                <admin>
                    <children>
                        <system>
                            <children>
                                <config>
                                    <children>
                                        <allnations>
                                            <title>Allnations - All</title>
                                        </allnations>
                                    </children>
                                </config>
                            </children>
                        </system>
                    </children>
                </admin>
            </resources>
        </acl>
    </adminhtml>
    <admin>
        <routers>
            <adminhtml>
                <args>
                    <modules>
                        <Novapc_Allnations before="Mage_Adminhtml">Novapc_Allnations_Adminhtml</Novapc_Allnations>
                    </modules>
                </args>
            </adminhtml>
        </routers>
    </admin>
    <crontab>
        <jobs>
            <allnations_promot>
                <schedule>
                    <cron_expr>0 */4 * * *</cron_expr>
                </schedule>
                <run>
                    <model>novapc_allnations/observer::deletePromotions</model>
                </run>
            </allnations_promot>
            <allnations_stockupdate>
                <schedule>
                    <cron_expr></cron_expr>
                </schedule>
                <run>
                    <model>novapc_allnations/observer::updateStock</model>
                </run>
            </allnations_stockupdate>
        </jobs>
    </crontab>
</config>
  • is your helper function calling properly? – Abhishek Panchal Sep 28 '17 at 18:57
  • I think so. This function works fine when I call from other places. I call it from a grid and it works. It just doesn't work in this observer – Stordon Sep 28 '17 at 18:58
  • if your function works fine then, $id = $event->getData($control); did you check ID? – Abhishek Panchal Sep 28 '17 at 19:01
  • 1
    What returns the var_dump($id); in observer? – Siarhey Uchukhlebau Oct 2 '17 at 13:48
  • 1
    what value give by $control and $id? – Amit Bera Oct 2 '17 at 16:52
0
+50

Solution:

1b. If you need to add attribute which name you know in advance, add it in your config.xml under global/sales/quote/item/product_attributes add your attribute like this (see Mage\Sales\etc\config.xml for an example):

<ext_id/>

1b. Or add programmatically, subscribe to event sales_quote_config_get_product_attributes and add your attribute to attributes object. Check out Mage_SalesRule_Model_Observer::addProductAttributes for an example.

2. Ensure your attribute is included in product listing, so that it's present in flat tables. Edit attribute in admin panel and check Used in Product Listing: Yes.

Background:

Reason for this is that your custom attribute is not loaded on product.

Stock items are loaded as part or quote, like this:

  • $quote->getAllVisibleItems()
  • Mage_Sales_Model_Resource_Quote_Item_Collection::_afterLoad - _assignProducts
  • Quote_Item_Abstract->checkData()
  • Quote_Item->setQty()

Normally we would only have raw quote items without actual products, only product_id. But Magento cares for us and loads all referenced products in _assignProducts. With a view to optimization, only important attributes are loaded:

\Mage_Sales_Model_Resource_Quote_Item_Collection::_assignProducts

    $productCollection = Mage::getModel('catalog/product')->getCollection()
        ->setStoreId($this->getStoreId())
        ->addIdFilter($this->_productIds)
        ->addAttributeToSelect(Mage::getSingleton('sales/quote_config')->getProductAttributes())
        ->addOptionsToResult()
        ->addStoreFilter()
        ->addUrlRewrite()
        ->addTierPriceData();

A place of interest here is getProductAttributes():

const XML_PATH_QUOTE_PRODUCT_ATTRIBUTES = 'global/sales/quote/item/product_attributes';

public function getProductAttributes()
{
    $attributes = Mage::getConfig()->getNode(self::XML_PATH_QUOTE_PRODUCT_ATTRIBUTES)->asArray();
    $transfer = new Varien_Object($attributes);
    Mage::dispatchEvent('sales_quote_config_get_product_attributes', array('attributes' => $transfer));
    $attributes = $transfer->getData();
    return array_keys($attributes);
}

So it loads only attributes, that are defined in everywhere in config.xml at path 'global/sales/quote/item/product_attributes'. Additionally you can add custom ones in event sales_quote_config_get_product_attributes. Mage\Sales\etc\config.xml for example containes these:

                <product_attributes>
                    <sku/>
                    <type_id/>
                    <name/>
                    <status/>
                    <visibility/>
                    <price/>
                    <weight/>
                    <url_path/>
                    <url_key/>
                    <thumbnail/>
                    <small_image/>
                    <tax_class_id/>
                    <special_from_date/>
                    <special_to_date/>
                    <special_price/>
                    <cost/>
                    <is_recurring/>
                    <recurring_profile/>
                    <gift_message_available/>
                    <msrp_enabled/>
                    <msrp/>
                    <msrp_display_actual_price_type/>
                </product_attributes>

Additional considerations

I'm a bit worried that your observer will fire too often even when qty is not actually changed - quoteItem->setQty() is called on every quote load.

This includes plainly browsing website when you have something in your cart - main page, categories, checkout etc. E.g. open main page:

  • quote.getAllVisibleItems
  • Mage_Sales_Model_Resource_Quote_Item_Collection::_afterLoad - _assignProducts
  • Quote_Item_Abstract.checkData
  • Quote_Item.setQty
0

config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Novapc_Allnations>
            <version>0.1.0</version>
        </Novapc_Allnations>
    </modules>
    <global>
        <blocks>
            <novapc_allnations>
                <class>Novapc_Allnations_Block</class>
            </novapc_allnations>
        </blocks>
        <helpers>
            <novapc_allnations>
                <class>Novapc_Allnations_Helper</class>
            </novapc_allnations>
        </helpers>
        <models>
            <novapc_allnations>
                <class>Novapc_Allnations_Model</class>
                <resourceModel>novapc_allnations_resource</resourceModel>
            </novapc_allnations>
            <novapc_allnations_resource>
                <class>Novapc_Allnations_Model_Resource</class>
                <entities>
                    <order>
                        <table>npcallnations_orders</table>
                    </order>
                    <integration>
                        <table>npcallnations_integrations</table>
                    </integration>
                    <promotion>
                        <table>npcallnations_promotions</table>
                    </promotion>
                    <attr>
                        <table>npcallnations_attributes</table>
                    </attr>
                </entities>
            </novapc_allnations_resource>
        </models>
        <resources>
            <novapc_allnations_setup>
                <setup>
                    <module>Novapc_Allnations</module>
                    <class>Novapc_Allnations_Model_Resource_Setup</class>
                </setup>
            </novapc_allnations_setup>
        </resources>
    </global>
    <frontend>
        <events>
            <sales_order_save_after>
                <observers>
                    <novapc_allnations_reserve>
                        <class>novapc_allnations/observer</class>
                        <method>confirmReserve</method>
                        <type>singleton</type>
                    </novapc_allnations_reserve>
                </observers>
            </sales_order_save_after>
            <sales_quote_item_qty_set_after>
                <observers>
                    <novapc_allnations_update>
                        <class>novapc_allnations/observer</class>
                        <method>stockUpdate</method>
                        <type>singleton</type>
                    </novapc_allnations_update>
                </observers>
            </sales_quote_item_qty_set_after>
            <sales_order_place_after>
                <observers>
                    <novapc_allnations_order>
                        <class>novapc_allnations/observer</class>
                        <method>checkOrder</method>
                        <type>singleton</type>
                    </novapc_allnations_order>
                </observers>
            </sales_order_place_after>
        </events>
    </frontend>
    <adminhtml>
            <admin_system_config_section_save_after>
                <observers>
                    <novapc_allnations_attribute>
                        <class>novapc_allnations/observer</class>
                        <method>setAttributes</method>
                        <type>singleton</type>
                    </novapc_allnations_attribute>
                </observers>
            </admin_system_config_section_save_after>
            <adminhtml_block_html_before>
                <observers>
                    <novapc_allnations_promotion>
                        <class>novapc_allnations/observer</class>
                        <method>updatePromotions</method>
                        <type>singleton</type>
                    </novapc_allnations_promotion>
                </observers>
            </adminhtml_block_html_before>
            <adminhtml_block_html_before>
                <observers>
                    <novapc_allnations_orderstatus>
                        <class>novapc_allnations/observer</class>
                        <method>updateOrderStatus</method>
                        <type>singleton</type>
                    </novapc_allnations_orderstatus>
                </observers>
            </adminhtml_block_html_before>
    </adminhtml>
    <default>
        <novapc_allnations>
            <general>
                <status>1</status>
            </general>
        </novapc_allnations>
    </default>
    <adminhtml>
        <layout>
            <updates>
                <novapc_allnations>
                    <file>novapc_allnations.xml</file>
                </novapc_allnations>
            </updates>
        </layout>
        <translate>
            <modules>
                <Novapc_Allnations>
                    <files>
                        <default>Novapc_Allnations.csv</default>
                    </files>
                </Novapc_Allnations>
            </modules>
        </translate>
        <global_search>
            <promotion>
                <class>novapc_allnations/adminhtml_search_promotion</class>
                <acl>novapc_allnations</acl>
            </promotion>
        </global_search>
        <acl>
            <resources>
                <all>
                    <title>Allow Everything</title>
                </all>
                <admin>
                    <children>
                        <system>
                            <children>
                                <config>
                                    <children>
                                        <allnations>
                                            <title>Allnations - All</title>
                                        </allnations>
                                    </children>
                                </config>
                            </children>
                        </system>
                    </children>
                </admin>
            </resources>
        </acl>
    </adminhtml>
    <admin>
        <routers>
            <adminhtml>
                <args>
                    <modules>
                        <Novapc_Allnations before="Mage_Adminhtml">Novapc_Allnations_Adminhtml</Novapc_Allnations>
                    </modules>
                </args>
            </adminhtml>
        </routers>
    </admin>
    <crontab>
        <jobs>
            <allnations_promot>
                <schedule>
                    <cron_expr>0 */4 * * *</cron_expr>
                </schedule>
                <run>
                    <model>novapc_allnations/observer::deletePromotions</model>
                </run>
            </allnations_promot>
            <allnations_stockupdate>
                <schedule>
                    <cron_expr></cron_expr>
                </schedule>
                <run>
                    <model>novapc_allnations/observer::updateStock</model>
                </run>
            </allnations_stockupdate>
        </jobs>
    </crontab>
</config>
  • not working.... – Stordon Oct 2 '17 at 12:41
  • in your observer, are you sure that you get something from the id ? try this Mage::log($event->getData($control)); – PЯINCƏ Oct 2 '17 at 13:21
  • Yes, I'm sure. I tried adding the $id value to a random table I have and it worked fine. Here i.imgur.com/IkopQo8.png I updated my question, the issue is my IF statement in helper – Stordon Oct 2 '17 at 13:27
  • replace public static function updateStock($codigo = null) with public function updateStock($codigo = 0) – PЯINCƏ Oct 2 '17 at 13:35
  • with $codigo = 0 it wouldn't work, so I tried with an empty string '' and it also doesn't work – Stordon Oct 2 '17 at 13:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.