# Class BundleService

java.lang.Object
com.university.bookstore.composite.BundleService

public class BundleService extends Object
Service for managing material bundles using the Composite pattern. Provides operations for creating, managing, and analyzing material bundles.

This service demonstrates the Composite pattern in action by providing a high-level interface for working with both individual materials and bundles.

Since:
  2024-09-15
Version:
  3.0
Author:
  Navid Mohaghegh

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static class`
  `BundleService.BundleStats`
  Statistics class for bundle analysis.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `BundleService()`
  Creates a new bundle service.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `addBundleToBundle(String parentBundleName, String childBundleName)`
  Adds a bundle to another bundle (nested bundles).
  `void`
  `addComponentToBundle(String bundleName, MaterialComponent component)`
  Adds a component to the specified bundle.
  `void`
  `addToBundle(String bundleName, Material material)`
  Adds a material to the specified bundle.
  `double`
  `calculateBundleSavings(String bundleName)`
  Calculates the total savings for a bundle.
  `double`
  `calculateTotalSavings()`
  Calculates the total savings across all bundles.
  `void`
  `clearAllBundles()`
  Clears all bundles.
  `MaterialBundle`
  `createBundle(String name, double discount)`
  Creates a new material bundle with the specified name and discount.
  `List<MaterialBundle>`
  `getAllBundles()`
  Gets all bundles.
  `Optional<MaterialBundle>`
  `getBundle(String name)`
  Gets a bundle by name.
  `int`
  `getBundleCount()`
  Gets the number of bundles.
  `List<String>`
  `getBundleNames()`
  Gets all bundle names.
  `List<MaterialBundle>`
  `getBundlesByDiscount(double minDiscount)`
  Gets bundles with discounts greater than or equal to the specified threshold.
  `List<MaterialBundle>`
  `getBundlesByMaterialType(Material.MaterialType type)`
  Gets bundles that contain materials of the specified type.
  `List<MaterialBundle>`
  `getBundlesByValueRange(double minValue, double maxValue)`
  Gets bundles with values within the specified range.
  `BundleService.BundleStats`
  `getBundleStats()`
  Gets bundle statistics.
  `double`
  `getTotalBundleValue()`
  Gets the total value of all bundles.
  `double`
  `getTotalDiscountedBundleValue()`
  Gets the total discounted value of all bundles.
  `boolean`
  `isEmpty()`
  Checks if any bundles exist.
  `boolean`
  `removeBundle(String name)`
  Removes a bundle by name.
  `boolean`
  `removeFromBundle(String bundleName, Material material)`
  Removes a material from the specified bundle.
  `String`
  `toString()`

  ### Methods inherited from class java.lang.Object

  `equals, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- ## Constructor Details

  - ### BundleService

    public BundleService()
    Creates a new bundle service.

- ## Method Details

  - ### createBundle

    public MaterialBundle createBundle(String name, double discount)
    Creates a new material bundle with the specified name and discount.
    Parameters:
      `name` - the bundle name
      `discount` - the discount rate (0.0 to 1.0)
    Returns:
      the created bundle
    Throws:
      `IllegalArgumentException` - if name is null or empty

  - ### addToBundle

    public void addToBundle(String bundleName, Material material)
    Adds a material to the specified bundle.
    Parameters:
      `bundleName` - the name of the bundle
      `material` - the material to add
    Throws:
      `IllegalArgumentException` - if bundle not found or material is null

  - ### addBundleToBundle

    public void addBundleToBundle(String parentBundleName, String childBundleName)
    Adds a bundle to another bundle (nested bundles).
    Parameters:
      `parentBundleName` - the name of the parent bundle
      `childBundleName` - the name of the child bundle to add
    Throws:
      `IllegalArgumentException` - if either bundle is not found

  - ### addComponentToBundle

    public void addComponentToBundle(String bundleName, MaterialComponent component)
    Adds a component to the specified bundle.
    Parameters:
      `bundleName` - the name of the bundle
      `component` - the component to add
    Throws:
      `IllegalArgumentException` - if bundle not found or component is null

  - ### removeFromBundle

    public boolean removeFromBundle(String bundleName, Material material)
    Removes a material from the specified bundle.
    Parameters:
      `bundleName` - the name of the bundle
      `material` - the material to remove
    Returns:
      true if the material was removed, false if not found

  - ### getBundle

    public Optional<MaterialBundle> getBundle(String name)
    Gets a bundle by name.
    Parameters:
      `name` - the bundle name
    Returns:
      Optional containing the bundle if found

  - ### getAllBundles

    public List<MaterialBundle> getAllBundles()
    Gets all bundles.
    Returns:
      list of all bundles

  - ### getBundleNames

    public List<String> getBundleNames()
    Gets all bundle names.
    Returns:
      list of bundle names

  - ### calculateBundleSavings

    public double calculateBundleSavings(String bundleName)
    Calculates the total savings for a bundle.
    Parameters:
      `bundleName` - the name of the bundle
    Returns:
      the total savings amount
    Throws:
      `IllegalArgumentException` - if bundle not found

  - ### calculateTotalSavings

    public double calculateTotalSavings()
    Calculates the total savings across all bundles.
    Returns:
      the total savings amount

  - ### getTotalBundleValue

    public double getTotalBundleValue()
    Gets the total value of all bundles.
    Returns:
      the total value

  - ### getTotalDiscountedBundleValue

    public double getTotalDiscountedBundleValue()
    Gets the total discounted value of all bundles.
    Returns:
      the total discounted value

  - ### getBundlesByMaterialType

    public List<MaterialBundle> getBundlesByMaterialType(Material.MaterialType type)
    Gets bundles that contain materials of the specified type.
    Parameters:
      `type` - the material type to filter by
    Returns:
      list of bundles containing the specified type

  - ### getBundlesByDiscount

    public List<MaterialBundle> getBundlesByDiscount(double minDiscount)
    Gets bundles with discounts greater than or equal to the specified threshold.
    Parameters:
      `minDiscount` - the minimum discount rate
    Returns:
      list of bundles meeting the criteria

  - ### getBundlesByValueRange

    public List<MaterialBundle> getBundlesByValueRange(double minValue, double maxValue)
    Gets bundles with values within the specified range.
    Parameters:
      `minValue` - the minimum value
      `maxValue` - the maximum value
    Returns:
      list of bundles within the value range

  - ### removeBundle

    public boolean removeBundle(String name)
    Removes a bundle by name.
    Parameters:
      `name` - the bundle name
    Returns:
      true if the bundle was removed, false if not found

  - ### clearAllBundles

    public void clearAllBundles()
    Clears all bundles.

  - ### getBundleCount

    public int getBundleCount()
    Gets the number of bundles.
    Returns:
      the bundle count

  - ### isEmpty

    public boolean isEmpty()
    Checks if any bundles exist.
    Returns:
      true if no bundles exist

  - ### getBundleStats

    public BundleService.BundleStats getBundleStats()
    Gets bundle statistics.
    Returns:
      bundle statistics

  - ### toString

    public String toString()
    Overrides:
      `toString` in class `Object`