Magento Order Table: custom column - php

I recently made a module that calculates the real gross margin for every order and order_item based on shipping cost data I import. I did this by adding 2 columns to the sales_flat_order table and the sales_flat_order_item table. This seemed to work great, until I realized that when I saved the imported data, it also updated the updated_at value. Since this was the first import of all orders, they all now report having been updated today. This is throwing off reports and other shipping software that syncs with it.
This brings me to 2 questions:
Is adding a column to an existing table (in this case, the sales tables) a major NO-NO?
If not, is there a way to set the data that doesn't increase the updated_at value?
If it helps, the code that actually writes the data is inside my IndexController.php file. It loops through the collection of orders and the items within those orders and sets the necessary values using something like $order->setGrossMargin($orderGM)->save();. I imagine it is the call to save() that is doing it, but I'm not sure the right way around this problem.
In the mean time, I'm working on a solution in which I import the data to custom tables and only read from the sales tables when necessary. Either way, it's a good exercise :)
Brian

Instead of calling save(), did you try:
$order->getResource()->saveAttribute('gross_margin')

Related

How to sync external product feed with internal product database in PHP/SQL?

I'm in the process of creating an application where we are fed several external product feeds daily, and we populate our products database with the feeds.
However the trick is we need to keep the product db in sync with the latest feed(s).
Previously I had toyed with the theory of populating the current product list from db in an array, and doing array comparison with the latest feed, that got gunned down once the product count was in the thousands. (Ran out of memory when trying to get a 5000 records).
So after abit of research, it seems the solution would probably lie on the SQL side, using TRIGGERS perhaps. Though I'm not quite sure how to go about it, hence my question.
So the 2 objectives I need to accomplish with the syncing process:
1) Insert new products that do not already exist in our db. We can accomplish this with the INSERT IGNORE method.
2) Find products on our DB that do NOT exist on the latest feed, and do something to them. (flag as deleted, or move to a deleted products table, etc.)
Step 2 is where I'm having trouble. I'm thinking now maybe for every sync operation, we insert the products from the latest feed into a 'Temp-Products' table, and somehow compare 'Products Table' with 'Temp-Products' table in finding the records that need to be flagged as deleted.
Any advice please?
Thanks
Obviously over-thought this one. The solution as suspected and further enforced by Anigel is to create a temporary table, 'products_temp' to store new feeds. We then run a simple join to find out what products are in the Products table, but not in 'products_temp', hence suggesting that the products have been sold out or deleted on the retailer.
We can then either flag the results of the query as deleted/sold out/do whatever.
The query I used is this:
SELECT products.sku_number, products_temp.sku_number FROM products LEFT OUTER JOIN products_temp ON products.`sku_number` = products_temp.`sku_number` WHERE products_temp.sku_number IS null

Magento attribute values saved in admin disappear

I had set up the catalog to sort on these values, which I saved through the admin last night. For most of a full day they were there. Now, like ghosts they have disappeared.
I suspect the problem could be tied to values saved through the admin rather than imported.
Can anyone point me to the source of this problem and the solution in the code?
Between the last time I saw the values working on the frontend (a few hours ago) and now, I did several things:
1.) Added 2 new attributes and some test values (unrelated to problem attribute), reindexed.
2.) Tried to import unrelated values for 60,000 products. Import hanged, so
3.) Imported values for 20,000 products at a time, no errors.
4.) reindexed.
Now all values saved manually are gone. Again, how can this happen? If they were saved to the DB, then shouldn't it take an delete call from the code to the DB to do this? How/why would such a call be made when I did not execute any such command in code or through admin? How can I fix this and avaoid in future?
TO AXEL (clarifying):
Thanks for your reply, #Axel.
1.) I created a text attribute called "sort_order" and entered some integer values through the admin.
2.) Then I did a full db backup with mysqldump.
3.) Then, I created two new attributes, "random_order" (price type) and "random_order_1" (text type). The purpose was to experiment with two solutions for shuffling the products in the catalog pages.
4.) Through phpMyAdmin I did a simple query to give me all products in random order:
SELECT `sku`
FROM `catalog_product_entity`
WHERE 1
ORDER BY RAND( )
and exported the result to csv. I simply used excel to number the items from 1-60,000, creating an import csv file with columns: sku, random_order (price type), random_order_1 (text type), with both attributes having same integer values.
5.) I used standard import method (replace existing complex data) in admin, 20k products at a time. After import, values for previously set and seemingly totally unrelated "random_order" have been deleted.
Before reindexing, every item's sort_order is now reset to default (=1), but it still appears in proper order on the frontend (so value still exists in product flat table), while the random_order and random_order_1 attributes have their imported values.
After reindex, all trace of sort_order is wiped out. That would make sense if I was actually importing that attribute, but I'm not. No other attribute appears to have been affected.
I restored db from mysqldump, tried whole process again. Same result.

Is there a field in the Magento database which holds the date for when an order is shipped?

Is there a field in the Magento database which holds the date for when an order is shipped?
The only date fields I've come across are created_at and updated_at but i don't think that's what i need.
Thanks for any help.
First off, the hierarchy of objects/database tables surrounding orders underwent a major reorganization from EAV style objects to "flat" objects during the 1.4.x branch. This specifics of this answer refer to modern versions of Magento.
When you create a shipment in Magento, you're creating a sales/order_shipment object. These objects are stored in the sales_flat_shipment table. This table has created_at and updated_at columns.
Each of these order shipment objects links to a 1 or many order shipment items objects. These objects are stored in the sales_flat_shipment_item table. Each row in this table represents a shipped line item in the order. This table links back to sales_flat_shipment by its parent_id column, and can be used to ensure a particular product, as well as its quantity, shipped.
Keep in mind that in most large scale e-commerce rollouts, Magento isn't the ultimate "source-of-truth" for what has and hasn't shipped. Every ERP integration I've ever seen is a lump of undocumented custom code that's used to communicate with an oversold bit of warehouse management software. The above data is usually used as a flag to a larger system that an order is ready to ship. Whether it has or not depends entirely on your process.
$shippingDate = Mage::getModel('sales/order_shipment')->getCreatedAt()
Comes from the sales_flat_shipment table in the magento version i'm running.
If you want to display actual shipping date then this date stored in 'sales_flat_shipment_grid' table. You can fetch data from this table using Mage::getResourceModel('sales/order_shipment_grid_collection');.
If you want to check then you can check from shipping grid at 'admin->sales->shipping'.
If this one help full then please up vote. :)

Take snapshot of DB table row?

I want to take a snap shot of a row in a MySQL table.
The reason being, if someone buys a product. I want to take a snapshot of that product to store for the order.
It needs to be a snapshot to maintain data integrity. If I just assign the product to the order, if the product changes in the future the order will show those changes. For example if the price changes, the order will now load the new data and say that it sold the product at its new price rather than what the price was when the order was placed. So a snapshot needs to be assigned to the order instead.
The way I did this in the past was having 2 tables, one for products, and one for snapshots of products. The snapshot had every column as the regular table plus extra colums like order_id
I had a script to take a snapshot that automatically looked at the fields in the regular table and tried to do an insert into the same fields into the snapshot table.
The biggest problem with that approach is that, if I added a column to the regular table and forgot to add the same column to the snapshot table; the script would try to insert data into a non existent field and fail.
I also disliked the idea of having 2 tables that were nearly identical. I think maybe figuring out a way to use one table for both purposes might be better.
So I am wondering if there is a known method I am unaware of to solve this issue?
My previous project used no framework but my next one will be using CakePHP if that matters.
I think the best way of handling this would be to roll the "snapshot" information into an orders_products table. So if you have an order, store the total price, tax, etc. information in a single row on the orders table and reference that order_id on your orders_products table. On your orders_products table, you can have order_id, product_id, price, quantity, discount and whatever else you need.
Seems like your previous is fine. But that you just need to do more testing to ensure that you don't forget to add the new fields to the snapshot table. Seems like a basic test that would be easy to do. The other alternative is to just use a big text field, and store the snapshot as XML. This will let you store the snapshot regardless of if the schema changes. Depending on how much you want to query this data, it may or may not work for you.
Also you may not want to store every field, as it may just take up extra space. For instance, if you have the location of the image file of the item, you may not want to store that, as it may not be important at a later date. You could try querying information_schema to query which fields are in the snapshot table, and only copy the available fields.

magic records being deleted

i have customised oscommerce to pull in a csv file of products, delete anything thats not with an image/proper description/proper title gets removed.
The import runs on a cron job basis pulling information from a supplier, it hasnt run since yesterday but a product has disappeared-
Anyone who has used oscommerce will know that, product information is stored over multiple tables. example is-
products
product_description
and so on. the thing that has got me that the information is deleted from the product table but not from the product_description table.
The product that is being deleted is a manually input one which carries a special tag/prefix on the model item of the product table. Therefore shouldn't be touched at all. Am clueles as what is going on.
Is there mysql integrity checks deleting records? could there be another plugin working on oscommerce?
If you can identify 'magic' rows in your table you could create a BEFORE DELETE trigger on that table to check the row someone is planning to delete isn't one of them, and raising an error if it is. I haven't created a trigger for quite a while so I forget the syntax, but there's more about triggers here... http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html

Categories