Regarding OpenCart store selling digital downloads.
I am trying to add a script to the product page to warn the customer if that specific product (download) is already purchased and exists in Account>Downloads.
The reason is to avoid customers purchasing the same product twice.
Appreciate your help.
Edit:
I have tried getting the product IDs of all orders by a customer using a SQL query and that works fine externally but inside OpenCart I am facing issues.
A query such as:
SELECT product_id
FROM ocuk_order_product
WHERE order_id IN (
SELECT order_id
FROM ocuk_order
WHERE customer_id = 'xxxx'
)
My main problem is not being sure how to get similar results in OpenCart Product page. (Which pages and path exactly and where inside the files)
Tried this post as well: Opencart get product downloads
But it is not exactly working on product page (product.php)
Opencart Version 3.0.2.0
Ok I'll take a stab at this but let's clarify a few things:
1) DB_PREFIX is simply a php constant that's declared in your config.php file. Based on the query you provided it's probably equal to ocuk. The point is, you write queries using this constant and they become portable across installations regardless of the users' chosen database prefix.
2) Opencart is based on the MCVL (an extension of MVC which includes language files) structure. The place to execute queries is in the model. The place to call model methods is in the controller. The controller passes output to the view and often uses language variables from language files.
So what I would do is write function and put it in your product model – in this case that's catalog/model/catalog/product.php. This function is called a method since it's now part of your model class. The function will output the rows in your table that a logged in customer has purchased the given product. It's also important to check (a) that the customer is logged in and (b) that the orders you are querying against are real orders - with an order_status_id > 0. We can go into that but suffice to say that you always need to check the order_status_id if you want to know about actual completed orders. Such a method could look something like this:
public function getOrderProductHistory($product_id) {
$result = [];
if ($customer_id = $this->customer->getId()) {
$sql = "
SELECT *
FROM " . DB_PREFIX . "order o
JOIN " . DB_PREFIX . "order_product op USING (order_id)
WHERE o.order_status_id > 0
AND o.customer_id = '" . (int)$customer_id . "'
";
$query = $this->db->query($sql);
$result = $query->rows;
}
return $result;
}
Now in your controller (on a product page that's catalog/controller/product/product.php) you can call this method to get results like this:
$order_product_history = $this->model_catalog_product->getOrderProductHistory($product_id);
And then do something based on the output:
if ($order_product_history) {
$data['has_been_ordered'] = true;
} else {
$data['has_been_ordered'] = false;
}
Now $has_been_ordered is a boolean that you can access in your view to display a message to the customer. There's still a bit more code for you to write but hopefully this helps get you off to a good start.
Related
I need to get the number of downloads bought and used, that's two methods that are available on $item object. But I can't instance $item on the file that I'm working:
app/code/core/Mage/Downloadable/Helper/Download.php
On this file, I need to retrieve the number of boughts and used of the download purchased.
I'm also trying to get the order ID or at least the link hash to identify that number of boughts/used downloads with the unique id of the purchase.
For example, I try this:
Mage::getModel('downloadable/link_purchased_item')
->load($this->getOrderItem()->getOrder()->getId(), 'order_id');
But $this->getOrderItem() is not available on Download.php file. I was trying this:
Mage::getModel('downloadable/link_purchased_item')->getCollection()
->addFieldToFilter('order_item_id', $this->getOrderItem()->getId());
But obviously getOrderItem() is unavailable.
Fatal error: Call to undefined method Mage_Downloadable_Helper_Download::getOrderItem() in /[...]/app/code/core/Mage/Downloadable/Helper/Download.php on line 135
But I'm able to use the customer singleton to retrieve client data like this:
$cliente = Mage::getSingleton('customer/session')->getCustomer();
So on this file I'm able to access others methods, but I'm unable to get the following details:
Number of downloads bought
Number of downloads used
Order ID or Link hash ID.
So please, I'm requesting how to get the current order instance and / or the current link instance, on the Download.php related with the file downloading.
Thank you!
You are doing it wrong, you can not get any object like this $this->getOrderItem() without set/declaring them. As you are trying to get order_id and item_id in the helper, which you are using on a custom page redirected from customer downloadable products. Here is what you have to do
Step - 1
From customer My Downloadable products, in the redirect url you have to pass that products order_id and item_id as parameter. You can get them from below code
$orderId = $_item->getPurchased()->getOrderId();
$itemId = $_item->getId();
Step -2
Now in your template file while using your helper function pass this order_id and item_id to method parameter. Like below code
$orderId = $this->getRequest()->getParam('order_param');
$itemId = $this->getRequest()->getParam('item_param');
//Your helper function
Mage::helper('your_helper')->yourMethod($orderId, $itemId);
Step - 3
In your helper file you can use below code
public function yourMethod($orderId, $itemId)
{
$linkPurchasedItem = Mage::getModel('downloadable/link_purchased_item')
->load($orderItem, 'order_id');
$LinkPurchaseOrderItemId = Mage::getModel('downloadable/link_purchased_item')->getCollection()
->addFieldToFilter('order_item_id', $itemId);
}
Note: Do not make any changes in core files, instead override them
I have a bit of an odd situation that I am trying to fix. Magento v1.9.2.4
I have only 2 different attribute sets. A and B.
I want to display the stock quantity/availability for set B, but not
set A.
To make things a bit more complex, I have 14 Customer Groups, I only want 6 of those groups to ever see any quantities/availability.
Here's what I have done so far to arrange this:
$customerSession = Mage::getSingleton('customer/session');
if($customerSession->isLoggedIn()){
$groupId = $customerSession->getCustomerGroupId();
$group = Mage::getModel('customer/group')->load($groupId);
if ('custgroup_1' == $group->getCode()){
$qty = (int) Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product)->getQty();
echo 'Quantity Available: ' . $qty;
}
}
The above snippet is repeated 5 times with the [if ('custgroup_1' ...] changed to accommodate the group I need this to show up for. That part is working just fine.
I only need to specify somehow that I only want the availability to show up for the attribute set B. Then Regardless of the customer group never show the qty/availability for attribute set A.
I have tried playing with the inventory options on the product page. (disabled stock management = qty still shows | enabled stock management, set qty to 0 and my custom options disappear | ect.) Nothing within the magento backend seems to work.
I'm a newbie to this whole Magento/Dev thing. So I apologize if this is considered a silly question.
Thank you for any/all help!
So, Immediately after posting this I realized I was thinking about the problem all wrong.
Because any item that isn't in attribute set B isn't having stock managed, I was able to write a condition that enables output only for products that have an inventory level greater than 0.
Here is the code for anyone who might happen to need to show a quantity for products based on a customer group, and hide availability for any item that has inventory management set to no, but is set to "In Stock".
$customerSession = Mage::getSingleton('customer/session');
if($customerSession->isLoggedIn()){
$groupId = $customerSession->getCustomerGroupId();
$group = Mage::getModel('customer/group')->load($groupId);
if ('custgroup_1' == $group->getCode()){
$__manStock = $_product->getStockItem()->getManageStock();
$__invAmt = (int)Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product)->getQty();
if ($__manStock > 0)
echo $this->__("Available Qty: $__invAmt");
}
}
Quick question about open cart, where are extension status and position set? I can see in the code
$postion = $this->config->get($extension . '_position');
and also
'status' => $this->config->get($extension . '_status')
However I can't see where these are defined?
At first, look into your extension file ( for example 'payment/free_checkout.php') and search for something like that
$this->model_setting_setting->editSetting( 'free_checkout', $this->request->post);
This is where settings stored into database ( you can go deeper into setting model, if you want )
After that, open admin/index.php and look at lines 38 - 48.
You can see, system gets data from database and store data into config object.
In Opencart Positions are used by Modules. They are set in admin unders extensions/modules. When you click save - it saves them to the database table oc_settings under the modulename_module
When Opencart is launched - in INDEX.php there is this code
// Settings
$query = $db->query("SELECT * FROM " . DB_PREFIX . "setting WHERE store_id = '0' OR store_id = '" . (int)$config->get('config_store_id') . "' ORDER BY store_id ASC");
foreach ($query->rows as $setting) {
if (!$setting['serialized']) {
$config->set($setting['key'], $setting['value']);
} else {
$config->set($setting['key'], unserialize($setting['value']));
}
}
it creates the config - a massive array of all the settings for the current store id.
Afterwards the position controllers (column_left.php, column_right.php, content_top.php and content_bottom.php) go through the extensions in the table oc_extension and finds all the modules that will need to be shown.
then it goes through this massive array CONFIG and collects the settings for these modules - this all is stored in a array $module_data
then the controller uses these settings to basicly launch every controller of the module that should be shown. It passes the controller route and $settings for every module in a foreach loop and in result gets a render of the modules.
You can access the config anywhere in the php file - it can be another controller, a model or even tpl file.
$this->config->get(...)
If you want - you can go directly to the databes oc_settings and get the data from there with these functions
$this->load->model('setting/setting'); // remeber to always load the model.
$this->model_setting_setting->editSetting( 'free_checkout', $this->request->post);
Hope this helps.
Also you can use this module to expend the number of positions for your opencart SUPER easy
Extra positions Unlimited
I have an issue. I want to show 4 related products in the product page. That is simple and I have done that. But if the product doesn't have any or has less than 4 products I want the remaining product to randomly appear in the page.
To select 4 random products first you need rewrite class that responsible for related block (or just move this file to local folder) and change logic for function that returns collection to something like next code:
$productsCollection = Mage::getResourceModel('catalog/product_collection');
$productsCollection->getSelect()->order('rand()');
$productsCollection->getSelect()->limit(4);
Hope, it will be helpful
If you're only interested in creating this functionality on the product page you can find most of the magic in Mage_Catalog_Block_Product_List_Related::_prepareData().
To fill out your related products with random products, we first need to know exactly how many random products we'll need. In this case, it's (4 - related products found):
// Existing Magento code near end of method
$this->_itemCollection->load();
// Our code
$numRandomsToGet = 4 - count($this->_itemCollection);
Then we can fetch the appropriate number of random products and add them to the collection:
// Our code
$randCollection = Mage::getResourceModel('catalog/product_collection');
Mage::getModel('catalog/layer')->prepareProductCollection($randCollection);
$randCollection->getSelect()->order('rand()');
$randCollection->addStoreFilter();
$randCollection->setPage(1, $numRandomsToGet);
$randCollection->addIdFilter($this->_itemCollection->getAllIds(), true);
foreach($randCollection as $randProduct)
{
$this->_itemCollection->addItem($randProduct);
}
// Existing Magento code
foreach ($this->_itemCollection as $product) {
$product->setDoNotUseCategoryId(true);
}
return $this;
Caveat/Plug: I pulled this code from our Related Products Manager extension for Magento so there might be some fiddling external to this method that needs to get done but I don't think so. If you get stuck you can try downloading the extension and examining the code in its entirety. Or, of course, you can just use the extension as-is.
I'm installing some tracking code into the checkout_success.php page. I need to be able to grab the coupon code/discount code name from the order, if one was used so that I can echo it out in my tracking script.
I was wondering if anyone knows how to do this?
I'm using this contribution of discount coupons; ot_discount_coupons.php, August 4, 2006, author: Kristen G. Thorson, ot_discount_coupon_codes version 3.0
It seems that the coupon code is not actually stored in the order_totals, but in a seperate discount_coupons_to_orders table. is there a query i can do on this table to find the matching coupon code used for this order? i tried the following but it return nothing;
$coupon_query = tep_db_query("select coupons_id from discount_coupons_to_orders where orders_id = '".(int)$orders['orders_id']."' ORDER BY orders_id DESC LIMIT 1"); $coupon_id = tep_db_fetch_array($coupon_query); $couponid = $coupon_id['coupon_id'];
Thank you.
Instead of:
$couponid = $coupon_id['coupon_id'];
Try:
$couponid = $coupon_id['coupons_id'];
My solution is probably a bit more than you're looking for but worked well for my work. I do a query at around line 76 in this php file that queries out the order information and the coupon code.
$orders_query = tep_db_query("select orders.orders_id from " . TABLE_ORDERS . " left join discount_coupons_to_orders dco on orders.orders_id=dco.orders_id where customers_id = '" . (int)$customer_id . "' order by date_purchased desc limit 1");
$orders = tep_db_fetch_array($orders_query);
The purpose of this is so that way a customer can get info on their order. You can reference your coupon code in here like I did showing that the discount was applied.
echo '<br /><br /><span style="color:red"><b>Your order number is #'.$orders['orders_id'].(!empty($orders['coupons_id']) ? ' Discount Code: '.$orders['coupons_id'] : "").' you can now view your receipt</b>.</span>';
We found customers immediately want to see a "receipt", so we link directly back to account history. But the key here is that if you use a join to the main order information you can access the order info and the coupon code in one shot.
If I remember correctly you can pass on the coupon code through the page, and have access to it. If not, hack into the coupon entry page, and on the "if coupon is ok" part, save it in a session variable. On the success page you`d just use something like $_SESSION['couponcode'], no use in having more queries. This is probably 2 lines of modification on the coupon entry page.