Below is our current solution for how we create product packages and use them in opportunities. I hope to do other posts like this that give examples of solutions without going into code. We may build some of these solutions into AppExchange apps one day.
We first create products in Salesforce that will act as the parent products for packages. They are the products that users can search for and add to an opportunity like normal. Using some custom objects and a visualforce page, we provide a way for other products to be related as child products to the parent product. Children have options like initial quantity, max quantity, min quantity, locked quantity, and is it deletable. All child prices are rolled up to the package level to form the initial package cost. A discount can be applied to the package to bring the cost of the package down. As the package price is changed, the pricebook entry record for the package product changes too so that as users are browsing packages they will see the correct cost. If the price of a child product is ever changed, then an apex job will detect the change and update packages that used that product.
Using Packages in Opportunities
When package products are added to opportunities, we have triggers that identify the products as package products and copy the package children into the opportunity. We have overriden the Opportunity page with a visualforce page that displays the user’s normal page layout, but replaces the standard product list with a custom list that highlights the relationship of the child products to the parent products. Users can discount the package in the opportunity if they want to offer clients discounts or they can delete products that are marked as deletable. Multiple packages can be added to an opportunity and, if the parent product is deleted, then the entire package is deleted.