If you create a pre-order downloadable product (you will need some module for that) and let's say you still don't have the link or file that will be used in the product, but you need to create the pre-order product and allow users to buy right now. Most likely you will ended up adding some link like "http://TBD/" or just write "TBD" or upload some file that is not the right one as customers still can't buy. This also applies to backorders or regular orders that for some reason you want customers to buy, but the link/file won't be available right away because you don't have the final link/file.
It also applies in case you need to update a link/file as it might change and you need all your customers to have the updated link/file. Unfortunately Magento doesn't update the orders with the new links/files and this is VERY annoying when you have a lot of orders like these examples. For that I created a simple module that will do just that. When you update the link/file in the product it will also update ALL orders for that product.
This is the table responsible for the purchased downloadable links: downloadable_link_purchased_item
So I did a test order on my local environment and if I check the link_url from that table, I will see the link configured in the product:
SELECT link_url FROM downloadable_link_purchased_item;
+----------------------+
| link_url |
+----------------------+
| http://tbd/somefile.zip |
+----------------------+
1 row in set (0.00 sec)
And then we can confirm that this link is "linked" to a product:
SELECT product_id, sku, link_url
-> FROM downloadable_link
-> INNER JOIN catalog_product_entity
-> WHERE entity_id = 3;
+------------+-----------------+----------------------+
| product_id | sku | link_url |
+------------+-----------------+----------------------+
| 3 | digital_product | http://tbd/somefile.zip |
+------------+-----------------+----------------------+
And we can confirm there is an order for that product (sorry for the queries, it's just so you can visualize):
SELECT c.product_id, b.sku, c.link_url, b.order_id
-> FROM downloadable_link c
-> INNER JOIN catalog_product_entity a
-> INNER JOIN sales_flat_order_item b
-> WHERE entity_id = 3;
+------------+-----------------+----------------------+----------+
| product_id | sku | link_url | order_id |
+------------+-----------------+----------------------+----------+
| 3 | digital_product | http://tbd/somefile.zip | 1 |
+------------+-----------------+----------------------+----------+
So I am going to do is update the link url from somefile.zip to myrealfile.zip in the Magento admin and we will see that nothing happens to that order from table downloadable_link_purchased_item.
First let's check the downloadable_link to make sure link was updated:
SELECT link_url FROM downloadable_link WHERE product_id = 3;
+---------------------------+
| link_url |
+---------------------------+
| http://tbd/myrealfile.zip |
+---------------------------+
Ok, so the product has the new link. Now let's see the orders:
SELECT item_id, link_url FROM downloadable_link_purchased_item;
+---------+-------------------------+
| item_id | link_url |
+---------+-------------------------+
| 1 | http://tbd/somefile.zip |
+---------+-------------------------+
Well, it looks like it still has the old link, but any new order will use myrealfile.zip. But it would be nice if any updated link or file would also update older orders. And that's why I created module MageBR_UpdateLinksPurchased and it's free for use. You can download latest version here: https://github.com/CajuCLC/MageBR_UpdateLinksPurchased/releases/latest
Or if you would like to contribute and make it better: https://github.com/CajuCLC/MageBR_UpdateLinksPurchased
After installing the module and refreshing caches, let's update the downloadable product again, now we will change link from myrealfile.zip to updatedlink.zip.
Let's check if the product has the new link:
SELECT link_url FROM downloadable_link WHERE product_id = 3;
+----------------------------+
| link_url |
+----------------------------+
| http://tbd/updatedlink.zip |
+----------------------------+
And the order item should also contain the new link:
SELECT item_id, link_url FROM downloadable_link_purchased_item;
+---------+----------------------------+
| item_id | link_url |
+---------+----------------------------+
| 1 | http://tbd/updatedlink.zip |
+---------+----------------------------+
There we are, all older orders will always have the updated link or file. BUT we are not done yet. If you get an error saying you can't save the product because order id can't be null, it means that you have orders that were deleted instead of canceled. When you delete an order it leaves all products hanging with no order (NULL). You can check by running these MySQL queries:
SELECT * FROM downloadable_link_purchased WHERE order_id IS NULL;
SELECT * FROM downloadable_link_purchased_item WHERE order_item_id IS NULL;
If any of the queries return some values, you will need to remove the those hanging orders and order items. Most of the time it won't be an issue, but please create a backup and make sure you can perform the next queries as they are destructive and we are not responsible for any issues:
DELETE FROM downloadable_link_purchased_item WHERE order_item_id IS NULL;
DELETE FROM downloadable_link_purchased WHERE order_id IS NULL;
And that's it, everything should be working now.
If you liked this tutorial/module please don't forget to share.