Is there a way to globally set the "QtyUsesDecimals" option in magento? My
I'm setting up a Magento site for a client who sells Fabric and other related materials. There is a minimum of .5 yards for any one Fabric product, After that, it can go to any amount, but the minimum is .5. Currently I'm able to type in .25, .125, etc. and add those to the shopping cart.
I only want this to apply to the Fabric products (there are around 2000 different fabric products) but not to the other types she sells on her site, like Rulers, needles, buttons, etc... I don't want people to be able to purchase .5 buttons.
Thanks
I was wondering the same thing, and I just googled this for you and in exactly 5 seconds.. I got the answer (and comprehended it too, mind you):
https://magento.stackexchange.com/questions/6193/magento-product-quantity-uses-decimals
And to apply this to just fabrics.. it should be something like this:
UPDATE `cataloginventory_stock_item`
SET `is_qty_decimal` = 1
WHERE `product_id` IN (
-- INSERT SUBQUERY HERE THAT GETS ALL PRODUCT ID's UNDER THE 'FABRIC' CATEGORY --
-- IT WOULD START WITH 'SELECT `product_id` FROM ..' you do the rest I believe in you --
);
For new/incoming products.. No, there isn't a global config that controls this, and no you can't set it in Default Configuration as it is already a global attribute. Unless, you are willing to invest some time into making an Observer module that sets that attribute for all new products that are created -and- saved (successfully).
There is a database query to solve this issue if the not fabrics products are just a few, or none.
This solution is not update safe and shouldn't be used unless you really understand what you're doing.
ALTER TABLE `cataloginventory_stock_item`
CHANGE COLUMN `is_qty_decimal` `is_qty_decimal` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '1' COMMENT 'Is Qty Decimal';
This will change just the default value of this column from DEFAULT '0' to DEFAULT '1'. In Magento 1.7.0.2 the other column fields are untouched, so you can check the query to see if your database version corresponds. Then you should check and rerun this query on each database update.
After executing this query you should modify the value back to '0' to the non fabrics products: you can do all at once via query (check Seth Jeremi Malaki's answer) or through the Admin interface (product->stock) one by one (the secure way).
Otherwise, if the fabric products are a lot less (or none), just keep the database at its state and modify only the fabrics via the admin interface.
Related
I am taking over a website from another developer, and have found the setup of attributes to be a bit of a mess.
Specifically, products have attributes that aren't associated with the relevant attribute sets.
If you take wine with an attribute set "Wines", one of whose attributes is "Grape Variety".
But I also have "Beers" with a completely different attribute set, but somehow one of my beers has a Grape Variety.
It's not assigned to the Beers attribute set, it doesn't show up in the back end for this product, (so I can't edit it) but if I look in the database it's there (in catalog_product_entity_* and catalog_product_index_eav), furthermore when I do an export it's there too, and if someone searches for "Merlot", they are coming up with this beer. There are hundreds of products like this.
What is the best way of removing all attributes from products that are not within their assigned attribute sets?
I could figure it out in SQL I'm sure, but that's not the best way of doing things as I'd be afraid of missing something and screwing up the products altogether.
This is what I ended up doing. A few weeks later and it doesn't seem to have caused any issues yet:
CREATE TABLE catalog_product_entity_int_old LIKE catalog_product_entity_int;
INSERT INTO catalog_product_entity_int_old SELECT * FROM catalog_product_entity_int;
DELETE FROM catalog_product_entity_int
WHERE value_id IN
(SELECT cpei.value_id
FROM catalog_product_entity_int_old cpei
WHERE cpei.attribute_id NOT IN
(SELECT eea.attribute_id
FROM eav_entity_attribute eea
JOIN catalog_product_entity cpe ON eea.attribute_set_id = cpe.attribute_set_id
WHERE cpe.entity_id = cpei.entity_id)
ORDER BY cpei.entity_id)
and
DELETE FROM catalog_product_index_eav WHERE
attribute_id NOT IN (
(SELECT eea.attribute_id
FROM eav_entity_attribute eea
JOIN catalog_product_entity cpe ON eea.attribute_set_id = cpe.attribute_set_id
WHERE cpe.entity_id = catalog_product_index_eav .entity_id)
);
Then regenerate the indices.
I would definitely use Magmi to clean this up:
First, do a product export from within Magento (System -> Import/Export -> Profiles) and choose "Export All Products." In the resulting CSV, you will have columns for each attribute and you can remove any irrelevant attribute values for each product. This will allow you to bypass the backend where attributes are set for a particular product, but not in the product's attribute set.
Take a good look at the Magmi Wiki, but a few quick tips: Magmi only imports the columns you specify, so you can safely remove most of the columns when you perform your import. For example, I always make sure to remove the image columns if I'm not importing images (or you may lose all of your images). Also, be sure to do a database backup before running your import in case something goes wrong.
Hi I am having a problem with importing Quote products in CRM 2011.
When I downloaded the template for import, the columns require that I state whether the product is a 'Write-in' or an 'Existing' product. Then there are an additional 2 columns: Write In, Existing.
On filling in the template with sample data for import, I wrote something like this:
Write-in | | New product |......
Existing | Existing Product 1 | |.......
(The | is a new column )
I am assuming that when the product is a write-in product, you must enter a new product and when the product is an existing product, you write the name of an existing product in the system. The other columns are then left blank.
However, I am getting errors on import and I have no clue why :/ I am giving it the wrong data?
Also... the company does not make use of a Product List. Is there a way in which I can bypass its use since every time I enter a new product, I am asked to give the price list and this is not viable for the company since there are hundreds of products and the items and their prices change constantly so we cannot make use of a Product List especially when I am asked to enter a New Product List every time :/
Does anyone have a clue of what can be done? Thanks :)
IMHO, I can suggest the following.
Have a default price list, Onload of such forms, autofill that field with that PriceList.
Also, when quote is created, use JScript to say there is always going to be a write In product. (Then, you dont require the Product Lookup filled in).
Also, I dont know what kind of errors you get here, but when you specify an existing product, you also have to specify the UniOfMeasure or something. Make sure you have one supplied in your CSV.
I understand how to programmatically create a product and also add to cart. I know this might sound dumb but is it is possible to generate a product on the fly and add that to the cart/quote but never actually save it in the database.
We want to create a made to order interface and I was thinking at the end it could add a bundle product with all the selections but that bundle product wouldn't actually exist in the backend.
I figured as long as you can make sure the quote and order has what it needs in terms of the product it would be ok, but obviously there is probably a lot that is tied to looking up stuff in the db on a specific sku or ID. I know that if you delete a product and then look at an order in the admin that causes issues, at least it did for this one scenario I was dealing with.
I was thinking of creating a giant bundle product that had like 6 different bundle items and each item could potentially have like 500 products and then based on what the user selects I programmatically add the bundle to cart. But then I wasn't sure if there would be a negative affect with having a gigantic bundle product like that as well.
UPDATE:
I don't think this will work, obviously there are a lot of information tied to the product in the database and we setup a test and right away we get an error for $item->getProduct(). We are moving forward with creating a giant bundle product and also the generic product with adding custom options on the fly, which Anda pointed out below. Any other suggestions will be greatly appreciated.
I'm not sure that clockworkgeek's approach is going to work. On every page load, Magento loads the items from the cart to make sure that they are still valid (in-stock, prices correct, etc), and amends the cart to reflect those values. My understanding of the system in the past has been that a product in the cart needs to have a corresponding database value to survive this process.
The "giant bundle product" approach is a pain, but in the past has been the best approach I have found. Attempting to change the values of the product (such as price or attributes) will be overridden by the cart checks, so you need a product w/ maximal flexibility, such as an overly-customized bundle product or configurable product.
Hope that helps!
Thanks,
Joe
Why not create a generic product in db and then set the product customization as custom options (additional_options) on the fly depending on the user selection. You can add custom options to the product (actually to the quote item) without having to save them in the database. I did this once for a website that sells glasses with prescription. The prescription was added as an option.
You can programmatically create Mage_Sales_Model_Quote_Items and add them to the cart. You've noticed it needs a product to match it's product ID but it needn't be a useful one. It could be a blank, disabled product, also created in code. All that's needed is a stub.
The necessary stuff for the cart is stored in the quote item - fields like name, value and quantity. Those fields are then copied directly to the order without using a product.
Mage::getModel('catalog/product')
creates a new product. you can add it to a cart, by doing something like this:
$cart = Mage::getSingleton('checkout/cart');
$product = Mage::getModel('catalog/product')
->setStoreId($storeid)
->setTypeId($type_id)
->setQty($quantyty)
->setWhatAttributYouWant($attribute);
$cart->addProduct($product);
product attributes you can find in the DB in tables that start like catalog_product_... or take an already created product, and see what attributes it has in the _data array (with debugger or just print_r($product->getData))
I am facing a problem while making product configurable i used this link http://www.magentocommerce.com/knowledge-base/entry/tutorial-creating-a-configurable-product/ but In associated tab the products doesnt show up
Thankds and regards
2 things you can check:
Are you sure that the simple products you want to associate to the configurable product actually have values for the attribute you made the configurable product configurable by? So if you made a configurable product based on 'color', do the simple products have values selected for 'color'?
When you are looking at the associated products tab, and seeing the blank grid there, have you tried resetting the filter, or selecting 'No' or 'Any' in the first column? If it is set to 'Yes', it is only looking for products that have already been associated.
How does configurables products linking works in magento ?
Getting rid of being trolled by the linking of configurables products with their simple counterparts ? Let's explain how does Magento link'em... and why it sometimes doesn't work as expected.
The first point to understand is how the data persistence is managed by the application. As expected, links are stored in database. Thought it was in catalog_product_relation ? You were wrong. It should be too simple to respect the Magento's spirit :)
catalog_product_relation vs catalog_product_super_* tables
I won't tell catalog_product_relation is useless – in fact, it's necessarily there for something. But from version 1.5+, this is not there that links are stored, and I can't explain what does its purpose is.
First step
The first step of the linking process is the definition of the configurable product's configurable attributes. Supposing we're creating a new configurable product from an attribute set having a few global-select attributes.
If you try to access to your configurable product, the application will ask you which of 'em should be used as configurable attributes, in a form using a list of checkboxes associated to each attribute. By selecting some and saving your product, you insert in catalog_product_super_attribute a row by attribute (an association between product's id and attribute's one).
Second step
The second step is the linking itself with the associated simple products. This step is a bit more complex, because it implies some checks of the database's content, which we'll detail further below. Some rules to keep in mind about that :
only products having the same attribute set as the current configurable product
options must be defined for the configurable attribute
only one simple can be linked for a given configurable attribute combination
simple can be linked to as many configurables as desired
Then, what happens when we go to our configurable's associated products tab ? Don't be scray to not see any of your simple-corresponding-product in the list that display – it's filter is configured by default to display only already linked products. Here is what happens behind the scene :
the application go check the catalog_product_super_attribute table, and bring back each corresponding attribute id defined there for the current product (our configurables attributes)
from them, it will go check eav_attribute to get some details about them – in which ones the backend_type, which is the more important part of this explanation
parallely, the catalog_product_super_link table is checked too. Any product linked to current_product is a potential linked product
for each attribute, the application check if a value exists in catalog_product_entity_{backend_type} for each potentially linked product. Note that if no value exists for a given product, it won't be validated nor as a potential link nor than an effective one, even if it has already been linked (we'll see below what it implies for attribute creation).
To resume, only products with a valid value are diplayable and effectively linked / linkable. Note that all of the combination must have valid values – if any of the configurable's attribute as none, game over, you'll not have any link between your simple product and its configurable counterpart.
We should think it's ok, and everything will go right now, since we know how everything works in database. That's true if you always create your attributes from the application's back-office. But since scripting attributes is a very common way to proceed, you're much like to be in this second case, which implies a potential HUGE problem.
Programatically created attributes and... What the hell !?! This attribute has change of backend type !
Edit note: this case happens effectively when using a eav/entity_attribute_source_table source model
This a trouble I personnally runned through. If you check attributes backend models in database (only for select attributes – we do not care about which ones are not usable as configurable's ones), you'll see some varchar, some int... In short, multiple ones, and we could rightfully expect any of them works.
And they do so. Since you do not decide to add an option to your attribute from the back-office, or anything else that require to click on the « save » button on the attribute page.
The point is that when you save your attribute, Magento, in it's great goodness, ask itself what is the type of the attribute you ask him to save. The point is that before anything else, it's a select. And a select has options. And options has id. Which are the values that will be put in catalog_product_entity_{backend_type}, in any case. The label is just properly ignored in that (it's stored in it's proper table and doesn't affect anything there). Only the id is used.
And what shall we expect from Magento :) ?
It just change the attribute backend type to int systematically.
So, if you have products that used to be linked and are no more, go check the catalog_product_entity_{backend_type} tables and the eav_attribute one – compare the backend type, look for values in each values table... If you find 'em in a table that does not correspond, you get your problem. You have a few ways to correct the problem, here are the both I find myself (and I really do not promote the first, which I put only for explanation purpose).
First way: get the backend type back (The Dirty Trick)
It has changed to int ? Don't care. Bring it back to what you want it to be.
Why it's dirty : because you want you user to be able to update it's attributes when he wants. If you update the backend type to varchar, for example, any label change in the back-office for an option will rollback to int as it will be saved.
Second way: let's correct everything ! (The Right Thing)
You can pass throught this... bad situation, with a bit of MySQL without harming your database. But please, first, dump it. Then you'll require 4 steps :
check that you don't already have the data in catalog_product_entity_int table
duplicate the rows of the current ...entity{attribute} table to the ..._entity_int one by using an INSERT / SELECT statement (this query can be a bit long)
update your configurable attributes (not all your attributes, ONLY the ones you know you have created and are use to set configurable products) to set their backend type to int (and never do something else again for configurable selects :) )
delete all entries corresponding to attribute in the ..._entity{attribute} table that you'll no more use (it can do pretty much entries since you can have a lot of products if you get a lot of options)
Here are some MySQL scripts, corresponding to these steps, supposing you have at start a list of the attributes codes concerned :
Check existing entries in entity int for a given list of attribute codes
-- Check existing entries to not duplicate
SELECT ea.attribute_code,
count(*)
FROM eav_attribute as ea
INNER JOIN catalog_product_entity_int as cpei
ON ea.attribute_id = cpei.attribute_id
WHERE ea.attribute_code IN(
{attributeCodesList}
)
GROUP BY ea.attribute_code
Duplicate entries from entity_varchar table (for example) to entity_int for a given list of attribute codes
-- Duplicating missed selects from varchat entity table to int
INSERT INTO catalog_product_entity_int (entity_type_id, attribute_id, store_id, entity_id, value)
SELECT cpev.entity_type_id,
cpev.attribute_id,
cpev.store_id,
cpev.entity_id,
cpev.value
FROM eav_attribute as ea
INNER JOIN catalog_product_entity_varchar as cpev
ON ea.attribute_id = cpev.attribute_id
WHERE ea.attribute_code IN(
{attributeCodesList}
)
Update attributes to never have the problem again!
-- Update missed select attributes from varchar backend type to int one
UPDATE eav_attribute as ea
SET ea.backend_type = 'int'
WHERE ea.attribute_code IN (
{attributeCodesList}
)
Remove the no more used entries from your database
-- Kill old varchar in varchar entity table
DELETE FROM catalog_product_entity_varchar
WHERE attribute_id IN (
SELECT ea.attribute_id
FROM eav_attribute as ea
WHERE ea.attribute_code IN (
{attributeCodesList}
)
)
Hope it will help all of the ones who can't make their associated products show up to get the trick!
I have a customer who retails third party batteries, and some batteries can replace several OEM models.
For instance, 3rd party SKU 12345 may replace Toshiba N23 and HP 53214, thus my customer would like to create two products with the same SKU in front end (they are essentially the same product). However, Magento by default does not allow duplicated SKU.
My current solution is to set SKU to not required from the backend, and add another attribute called Model that allows duplicated values, and display the Model in front end.
Is there a better way to do this? Or is it possible to allow duplicated SKU?
Tian Bo
Noble Technologies
It sounds to me like you've found a good solution. I'm not so sure you should try to have duplicate values for SKU for two reasons.
First the whole point of SKU is that it is a unique identifier. That's its only reason for existing. If you're going to have duplicate values, then it's not a unique identifier; it's just another attribute. But of course Magento still needs a unique identifier to work, which means that this is an extra field, which takes us exactly where you are now.
That said we come to my second point which is this... I'm not exactly a Magento guru, but I've built my share of e-commerce sites and one thing I've learned is that they depend on certain unbreakable rules to work properly. One of them is that unique identifiers are unique, both on the database and application level. As such, a large part of the website depends on this to function correctly. Which I'm pretty sure goes for Magento too.
So trying to change such a basic premise in something so complicated will only lead to horrors and a slow descent into madness.
This sounds like a good solution that I extended a bit further, however what I did with multiple store was to create a visible attribute ITEM_SKU (Item SKU) - make it visible and searchable and then concatenate the store_id to Magneto SKU to make it unique.
So SKU becomes (Store_id "-" SKU).
It surprises me how often people are willing to break who-knows-what parts of Magento, just to get a specific piece working how they expect.
The proper way to allow for duplicate skus is NOT to (unless you'd like to re-write large parts of the framework). You CAN, however, add a custom attribute to products that shares all the same settings as "sku" minus the setting that requires values to be unique.
Changing product pages, emails, etc to show this value instead will require a little extra work but will save you headaches later.
Why don't you create 1 product (SKU 12345) and list this product in multiple categories. So your multiple categories will be Toshiba and HP. The same product (SKU 12345) will be listed in Toshiba and HP.