Product Setup Module

Bundle Management

Bundle Management lets you combine multiple products into one sellable bundle with automatic pricing, discount calculation, and inventory sync.

Screen Breakdown (Based on Your UI)

  • Bundle identity: Set bundle name, discount type, default sell qty, and discount value.
  • Price preview panel: Shows base total, discount applied, and estimated final bundle price in real time.
  • Bundle products: Add one or more products with quantity per bundle.
  • Bundle status: Toggle whether the bundle stays active in product list after save.

How It Works

  1. User opens Bundle module and clicks Add.
  2. System captures bundle identity fields and selected products.
  3. Price preview computes base total from product prices and quantities.
  4. Discount is applied using percentage or fixed mode.
  5. On save, backend validates products, stock rules, and pricing availability.
  6. Bundle record is created/updated and item rows are synchronized.
  7. A linked sellable product and inventory row are auto-created/updated for the bundle.

API Endpoints

MethodEndpointPurpose
GET/api/v1/bundlesList bundles with filters/pagination
POST/api/v1/bundlesCreate bundle
GET/api/v1/bundles/{id}Get bundle details
PUT/api/v1/bundles/{id}Update bundle
DELETE/api/v1/bundles/{id}Delete bundle
GET/api/v1/bundles/{id}/price-previewPreview bundle total and stock feasibility

Feature gate: bundle endpoints are guarded by feature.access:ftr_bundle_product.

Validation Rules

  • name: required, string, max 191, unique per company
  • discount_type: required, percentage or fixed
  • discount_value: required numeric, minimum 0
  • bundle_qty: optional numeric, minimum 0.01
  • deduction_mode: optional, strict or relaxed
  • is_active: optional boolean
  • products: required array, minimum 1 item
  • products.*.product_id: required
  • products.*.quantity: required numeric, minimum 0.01

Pricing Logic

  1. Base price per bundle = sum of (unit_price x quantity_per_bundle) for all items.
  2. Discount amount: percentage => base_price x discount_value / 100, fixed => discount_value.
  3. Discount is clamped so it never exceeds base price.
  4. Bundle price = max(base_price - discount, 0).
  5. Discount share is distributed across components to compute effective component price.

Inventory and Product Sync

  • Saving a bundle updates/creates a linked product row with is_bundle = true.
  • Bundle barcode/code is synchronized to the linked product SKU/barcode.
  • Inventory + inventory item for the bundle product are created/updated with computed bundle price.
  • On selling/preview, stock validation can ensure each component has enough quantity.

Restrictions and Safety

  • Bundle cannot be saved if any selected product has no selling price.
  • Deletion is blocked if the bundle was used in invoice items.
  • Invalid products or over-quantity vs stock raise validation errors.

Troubleshooting

IssueCauseFix
Bundle save failsMissing product selling priceSet selling price for each selected product
Price preview errorInsufficient component stockAdjust quantities or replenish stock
Delete blockedBundle used in sales invoiceKeep bundle for history; create new replacement bundle
Unexpected totalDiscount type/value mismatchCheck percentage vs fixed and recalculate

Screenshots

Bundle Management
Bundle management screen