Good question, and I think actually a very important interaction to get right. Here are some aspects that I think play into it:
Preliminary Thoughts
- Self-Efficacy: We humans, in general, want to be able to influence the world. Not being able to do something we think we should be allowed to to (like clicking a button) feels frustrating.
- Getting Told What To Do: Remember being really motivated to clean your room right up until your mom told you to do it? We also react very allergic to any kind of "you have to do this" - including "please do this action first"
- Developer/User Mental Model Mismatch: You, the designer, has a certain model of this interaction in your head - from what I gather it might go something like
"Products have suppliers and categories, that's just how to organize it best. Since the former two are parent classes, obviously you would create them first - now how do I communicate this..."
while a user might go
"Huh, interesting app. Let's see if I can run my business here. Let's put Dual Blade Shaver X356
in here as a test. What are categories? Don't care yet - just want to put in a product. Why doesn't this work?!".
This is quite a dangerous mismatch!
(Please don't take this as a personal attack of any kind - I am kinda brazenly pretending to know your thoughts to make a general point)
- Danger of Bouncing: I presume this is a scenario that would be encountered mostly by new users, who might have just discovered your app. If it's an online SaaS, any of the above frustrations might lead to the user just leaving never to return, or at least to form a bad first impression!
Some General Guidelines
So with all this in mind, you can certainly do something like greyed-out and tooltip. However, I would urge you to be very gentle and obvious about why! You need to explain everything in a way that makes sense to the user (not just: "my app needs it like that") and buffer any frustration (like StackExchange with their cute little message when you attempt to do an action you are not allowed to). Also you should then design your flow in a way that the user usually already has a category and supplier when encountering the New Product
button as to mostly avoid this situation wholesale. Doable, but hard.
A possible elegant solution?
Now what I would do if I understand your app correctly and if it's technically feasible:
Do not disable the button in any way. Just let the user click it, and then just have a dialog going like Hey! Let's create a product. First, enter the category of the product...
. You see where I am going? So you kinda just have this optional two screens when the parent objects in question do not exist yet, but for the user it feels like they are just creating a product - because they don't care how your database works ;).
Now I know this may be a bit of pain depending how your backend is setup, but I would call it a very elegant side-stepping of the whole problem from a UX perspective...