4

I would like to display the terms and conditions (agreements.phtml) only if the customer purchases certain products. For example, some of our products require a prescription. It a customer purchases one of these, we would like the terms to appear.

I have created an attribute in the backend: prescription_required

psuedo code is the following:

Loop through products in the basket
    if prescription_required == yes
        set flag to yes
    end if
end loop

if flag is set to yes, go through code in agreements.phtml

I think the main problem I am having is getting the product information in agreements.phmtl and looping through the basket.

I have tried

<?php 
    $_product = Mage::getModel('catalog/product')->load($this->getData('product_id'));
    echo $_product->getName();
?> 

but nothing is returned.

user1694820
  • 43
  • 1
  • 3

2 Answers2

7

EDIT:

I made an extension that is doing exactly what yo are trying to achieve and published it via Magento Connect. Here is the link: http://www.magentocommerce.com/magento-connect/catalog/product/view/id/14603. You may download it, or follow the steps below. Link to the extension source code is on the bottom of the answer.

END OF EDIT

These are steps you have to make:

  1. Create new product attribute responsible for displaying (or not) terms and conditions
  2. Rewrite the block responsible for showing those terms and conditions on the checkout page
  3. Rewrite the helper responsible for checking if all the required terms and conditions checkboxes are clicked by users

Assumptions and goal:

I assume that you don't want to create something more complicated than you actually need. I'll explain to you how to make an extension that will make ALL enabled terms and conditions appear if there is at least one product in the cart that requires terms/conditions, or NONE of them - if there is no product in the cart that would require this.

I also assume that we want to make things right and leave the core files alone. Of course, it might be easier to just modify core functionalities, but this approach will really cause troubles in the future. That's why we're make a new module.

Next thing I assume that this functionality is needed in all of the stores, if there is more than one.

And one last thing - I tested my approach on Magento Community Edition 1.7. It's not guaranteed to work on other versions, but I think it should work on 1.6 and 1.5. You can try, if you work on one of those versions. I'm not sure if it would work on older versions.

Creating new attribute:

It's out of the scope of the question, but it would be best if:

  • the attribute was a Yes/No option, because we don't need anything more
  • the attribute was a system attribute, so we don't have to add it to every attribute group

Of course, depending on your needs, you may create the attribute some other way.

In my case, the product attribute was given a code conditional_agreements. This code is used in the code snippets below.

Rewriting the block

The block we have to rewrite is Mage_Checkout_Block_Agreements. It has only one function - getAgreements().

First thing is to make a rewrite. My package is called bartoszgorski and my module is conditionalagreements, so my code in config.xml is:

<config>
    <!-- other code -->
    <global>
        <!-- other code -->
        <blocks>
            <checkout>
                <rewrite>
                    <agreements>Bartoszgorski_Conditionalagreements_Block_Agreements</agreements>
                </rewrite>
            </checkout>
        </blocks>
        <!-- other code -->
    </global>
</config>

In the file itself, I just used a helper (explained later) to check, if we want to display any terms and conditions. My code looks like this:

public function getAgreements() {
    if(Mage::helper('conditionalagreements')->checkIfQuoteRequiresAgreements() == true) {
        return parent::getAgreements();
    } else {
        return array();
    }
}

So, if there is something to display, we can display it. Otherwise, the function return an empty array of agreements.

Rewriting the helper:

The helper we have to rewrite is Mage_Checkout_Helper_Data. If the helper wasn't rewritten, Magento would display no terms/conditions, but would still require users to check their checkboxes - and that would of course be impossible. So, my code in the config.xml is:

<config>
    <!-- other code -->
    <global>
        <!-- other code -->
        <helpers>
            <conditionalagreements>
                <class>Bartoszgorski_Conditionalagreements_Helper</class>
            </conditionalagreements>
            <checkout>
                <rewrite>
                    <data>Bartoszgorski_Conditionalagreements_Helper_Data</data>
                </rewrite>
            </checkout>
        </helpers>
        <!-- other code -->
    </global>
</config>

In the helper, there is function getRequiredAgreementIds() that is responsible for getting every terms and conditions that have to be agreed to. We want to do exactly the same, but only if there is at least one product in the cart that requires it. That's why I suggest creating another helper function (checkIfQuoteRequiresAgreements() in my case) that checks for such products and use it in getRequiredAgreementIds() (and in the block as well, as shown earlier). So, the rewriting helper should have those functions:

public function getRequiredAgreementIds()
{
    if($this->checkIfQuoteRequiresAgreements() == true) {
        if (is_null($this->_agreements)) {
            if (!Mage::getStoreConfigFlag('checkout/options/enable_agreements')) {
                $this->_agreements = array();
            } else {
                $this->_agreements = Mage::getModel('checkout/agreement')->getCollection()
                    ->addStoreFilter(Mage::app()->getStore()->getId())
                    ->addFieldToFilter('is_active', 1)
                    ->getAllIds();
            }
        }
        return $this->_agreements;
    } else {
        return array();
    }
}

public function checkIfQuoteRequiresAgreements() {
    $showAgreements = false;
    $quote = Mage::getSingleton('checkout/session')->getQuote();
    foreach ($quote->getAllVisibleItems() as $quoteItem) {
        $product = Mage::getModel('catalog/product')->load($quoteItem->getProductId()); 
        if($product->getConditionalAgreements() == 1) {
            $showAgreements = true;
            break;
        }
    }
    return $showAgreements;
}

And that's it. After doing this, you should have what you want. Just remember that if you have more than one item in terms and conditions, you can only display all of them or none. Of course, you can develop something more based on my code snippets - it's up to you.

Here is my fully-working module:

https://github.com/bgorski/conditionalagreements

You can preview what I did there or just download it and use on your website.

Hope that helps. Any feedback would be most appreciated.

Bartosz Górski
  • 1,140
  • 13
  • 30
  • Sorry I am just now getting back into this. Had a major surgery to deal with and it fell off my radar. I tried downloading the extension and it caused my site to crash, so I copied the code bit by bit from your site. I am running enterprise 1.12. It didn't cause my site to crash, but it also doesn't seem to do anything. When I set "Enable Terms and Conditions" to yes, it shows it. When I set it to no it doesn't show it. It doesn't matter what the attribute "conditional_agreements" is set to. Thanks for the long response and sorry again about just now getting back to you. – user1694820 May 24 '13 at 15:28
  • I got it working...it was my mistake. The code worked great and the explanation was very helpful and thorough. – user1694820 May 27 '13 at 01:57
  • GitHub copy tested & Confirmed to work in Magento 1.9.2.4 - Only modification necessary was due to conflict in class rewrites (because of other extensions already installed on the site) – Darren Felton Sep 01 '16 at 18:50
0

Assuming that the option is a text field, you can do it like this:

// get your cart object
$quote = Mage::getSingleton('checkout/session')->getQuote();

foreach ($quote->getItems() as $item) {
    $productId = $item->getProductId();
    $product = Mage::getModel('catalog/product')->load($productId); 
    $prescriptionRequired = $product->getAttributeText('prescription_required');

    // code for subscription handling goes here

}

Let me know if it worked ...

Regards

user1638055
  • 482
  • 2
  • 8
  • 24
  • He said that $_product->getName() returned nothing. It means he didn't know how to get the product's object and it is definitely the main problem – ivantedja Sep 24 '12 at 15:29