My advice is to avoid this general design altogether. Don't use inheritance at all. Object orientation works well when different types of objects have different behavior. For asset tracking, none of the objects really has any behavior at all -- you're storing relatively "dumb" data, none of which does (or should) really do anything at all.
Right now, you seem to be approaching this as an object oriented program with a database as a backing store (so to speak). I'd reverse that: it's a database with a front-end that is (or at least might be) object oriented.
Then again, unless you have some really specific and unusual needs in your asset tracking, chances are that you shouldn't do this at all. There are literally dozens of perfectly reasonable asset tracking packages already on the market. Unless your needs really are pretty unusual, reinventing this particular wheel won't accomplish much.
Edit: I don't intend to advise against using OOP within the application itself at all. Quite the contrary, MVC (for example) works quite well, and I'd almost certainly use it for almost any kind of task like this.
Where I'd avoid OOP would be in the design of the data being stored. Here, you benefit far more from using something like an SQL-based database via something like OLE DB, ODBC, or JDBC.
Using a semi-standard component for this will give you things like scalability and incremental backup nearly automatically, and is likely to make future requirements (e.g. integration with other systems) considerably easier, as you'll have a standardized, well understood layer for access to the data.
Edit2: As far as when to use (or not use) inheritance, one hint (though I'll admit it's no more than that) is to look at behaviors, and whether the hierarchy you're considering really reflects behaviors that are important to your program. In some cases, the data you work with are relatively "active" in the program -- i.e. the behavior of the program itself revolves around the behavior of the data. In such a case, it makes sense (or at least can make sense) to have a relatively tight relationship between the data and the code.
In other cases, however, the behavior of the code is relatively unaffected by the data. I would posit that asset tracking is such a case. To the asset tracking program, it doesn't make much (if any) real difference whether the current item is a telephone, or a radio, or a car. There are a few (usually much broader) classes you might want to take into account -- at least for quite a few businesses, it matters whether assets are considered "real estate", "equipment", "office supplies", etc. These classifications lead to differences in things like how the asset has to be tracked, taxes that have to be paid on it, and so on.
At the same time, two items that fall under office supplies (e.g. paper clips and staples) don't have significantly different behaviors -- each has a description, cost, location, etc. Depending on what you're trying to accomplish, each might have things like a trigger when the quantity falls below a certain level, to let somebody know that it's time to re-order.
One way to summarize that might be to think in terms of whether the program can reasonably work with data for which it wasn't really designed. For asset tracking, there's virtually no chance that you can (or would want to) create a class for every kind of object somebody might decide to track. You need to plan from the beginning on the fact that it's going to be used for all kinds of data you didn't explicitly account for in the original design. Chances are that for the majority of items, you need to design your code to be able to just pass data through, without knowing (or caring) much about most of the content.
Modeling the data in your code makes sense primarily when/if the program really needs to know about the exact properties of the data, and can't reasonably function without it.