Present for Craft CMS

FAQ

Why not just use a variant?

Because a variant is one thing with one SKU and one stock figure. If "Gift Box" is a variant, you have to keep its stock in step with three other products by hand, you cannot ship half of it, and selling one does not take a mug off the shelf.

Why does a bundle put several line items in the cart?

Because that is what makes the rest of it possible. Commerce commits stock per purchasable and records fulfilment per line item. Components that are real line items get both — correctly, even when the same variant is also in the cart on its own — plus their own tax categories, shipping categories and weights.

A bundle sold as a single line item cannot do any of that, which is why every other bundle plugin for Craft stops at "set a price". WooCommerce Product Bundles works the same way, for the same reason.

Will my existing cart template break?

It will list a box's contents as separate rows until you tell it not to. Two helpers fix that — craft.present.isComponent() and craft.present.cartLineItems(). See Templating.

Can a shopper delete one thing out of a box?

Not meaningfully. If they delete a component line item, Present puts it back on the next recalculation (or removes the whole box, depending on your setting). To let them change a box's contents, turn on Editable in the cart and post to present/cart/update.

What happens if a component runs out after a box is in the cart?

Commerce's own stock validation catches it at checkout, because the components are ordinary line items. Present catches it earlier and names the shelf that is empty.

Can I put a bundle inside a bundle?

No. The stock rollup would have to recurse, the fulfilment rollup would have to nest, and Commerce would still see one flat list of line items at the end of it. Present refuses rather than half-supporting it.

How is a fixed bundle price taxed?

By default it is spread across the component line items in proportion to their value, so each keeps its own tax category and a box of mixed-rate goods is taxed correctly. You can put it all on the bundle line instead (Pro), which is simpler to read on an order and right when everything in the box shares a tax category.

Does it work with shipping rate plugins?

Yes. Components are shippable line items carrying their own weights and shipping categories, so weight-based and table-rate plugins see a box exactly as they would see its contents bought separately. The container line ships only if you give the bundle a weight of its own — which is how you say "the packaging weighs something". Otherwise a per-item shipping rate would charge for a box that does not exist.

Do Commerce discounts work on bundles?

Yes, on the container and the components alike, since they are ordinary line items. Present clears a component's promotional price, because a component inside a box is sold at the box's price and a promotional price underneath would undercut the bundle.

Two identical boxes — one line or two?

One line at quantity two. The group key is a hash of the configuration, so identical boxes merge the way any other purchasable does, and differently-configured boxes stay apart.

Can I bulk-load bundles from a migration or a script?

Yes — Bundle is an ordinary element and setSlots() takes Slot models. If your script also creates or deletes bundle types, call Craft::$app->getProjectConfig()->flush() before it exits: a bare console script never fires the event Craft flushes project config on, so the write is silently lost.

Does it support multiple stores?

Bundles are per-site like any element, and their prices live in Commerce's per-store purchasable tables, so a bundle is priced per store the way a variant is.

What happens on a Pro licence lapse?

Pro settings are ignored, not obeyed. Range slots behave as fixed, query pools fall back to their configured list, allocation falls back to spreading, item limits stop applying, and the control panel flags which bundles are affected. Nothing is deleted, and upgrading restores it. The store stops selling boxes it can no longer validate rather than selling them wrongly.