
import BundleFields from "../../../src/reference/subbly-sdk/types/Bundle.mdx";
import BundleItemFields from "../../../src/reference/subbly-sdk/types/BundleItem.mdx";
import BundleGroupFields from "../../../src/reference/subbly-sdk/types/BundleGroup.mdx";
import BundleQuoteFields from "../../../src/reference/subbly-sdk/types/BundleQuote.mdx";
import PaginationFields from "../../../src/reference/subbly-sdk/types/Pagination.mdx";

<SdkPage group="bundles" />

Every method here takes an optional `headers` argument to price one call in
another currency, and every amount is a whole number in the minor unit; see
[Currency](/reference/subbly-sdk#currency) and
[Amounts and dates](/reference/subbly-sdk#amounts-and-dates).

A typical flow: `load` the bundle for its plans and rules, `loadItems` for what
the customer can pick, `quote` to show the price, then `subbly.cart.addItem` to
buy it.

<Method id="list" signature="subbly.bundles.list(params, headers?)">

Gets a paginated list of the shop's bundles.

<Params>
  <Param name="params" required type="BundleListParams">
    Paging and filters. Pass `{}` for the defaults — the argument is required by
    position even though every field inside it is optional.

    <Properties label="params">
      <Param name="page" optional type="number">
      Page to fetch, counting from 1.
      </Param>
      <Param name="perPage" optional type="number">
      How many bundles per page.
      </Param>
      <Param name="tags" optional type="string[]">
      Keep only bundles carrying these tags.
      </Param>
      <Param name="slugs" optional type="string[]">
      Keep only bundles with these slugs.
      </Param>
      <Param name="ids" optional type="number[]">
      Keep only these bundle IDs.
      </Param>
      <Param name="digital" optional type="boolean">
      `true` keeps only digital bundles, `false` only physical ones.
      </Param>
      <Param name="configurable" optional type="boolean">
      `true` keeps only bundles the customer configures, `false` only fixed ones.
      </Param>
      <Param name="expand" optional type="string[]">
      Relations to include: `plans.variant`, `plans.variant.parent`,
      `plans.plan`, `plans.plan.parent` and `metadata`.
      </Param>
    </Properties>
  </Param>
  <Param name="headers" optional type="BundleRequestHeaders">
    Extra request headers.

    <Properties label="headers">
      <Param name="x-currency" optional type="string">
      Currency for the prices in the response, such as `EUR`.
      </Param>
    </Properties>
  </Param>
</Params>

<Returns type="Promise<BundleListResponse>">
One page of bundles.
<Properties label="response">
  <Param name="data" type="Bundle[]">
  The bundles on this page.
  <Properties label="bundle" collapsed>
    <BundleFields />
  </Properties>
  </Param>
  <Param name="pagination" type="Pagination">
  Where this page sits in the list.
  <Properties label="pagination">
    <PaginationFields />
  </Properties>
  </Param>
</Properties>
</Returns>

<Example>

```js title="List the bundles"
const { data, pagination } = await subbly.bundles.list({})
```

```js title="List the configurable bundles with their plans"
const { data } = await subbly.bundles.list({
  perPage: 24,
  configurable: true,
  expand: ['plans.plan', 'plans.variant'],
})
```

</Example>

</Method>

<Method id="load" signature="subbly.bundles.load(bundleId, params?, headers?)">

Gets one bundle with its plans, prices, discounts, rulesets, filters and
preferences — everything the picker needs except the items themselves.

<Params>
  <Param name="bundleId" required type="number">
  ID of the bundle.
  </Param>
  <Param name="params" optional type="BundleResourceParams">
    Relations to include.

    <Properties label="params">
      <Param name="expand" optional type="string[]">
      `plans.variant`, `plans.variant.parent`, `plans.plan`, `plans.plan.parent`
      and `metadata`.
      </Param>
    </Properties>
  </Param>
  <Param name="headers" optional type="BundleRequestHeaders">
    Extra request headers.

    <Properties label="headers">
      <Param name="x-currency" optional type="string">
      Currency for the prices in the response.
      </Param>
    </Properties>
  </Param>
</Params>

<Returns type="Promise<Bundle>">
The bundle.
<Properties label="bundle" collapsed>
  <BundleFields />
</Properties>
</Returns>

<Example>

```js title="Load a bundle"
const bundle = await subbly.bundles.load(512, {
  expand: ['plans.plan', 'plans.plan.parent'],
})
```

</Example>

</Method>

<Method id="load-items" signature="subbly.bundles.loadItems(bundleId, params?, headers?)">

Gets a paginated, filterable list of the products a customer can pick for the
bundle. Send the picks to `quote` and to `subbly.cart.addItem` as
`{ productId, quantity }`.

<Params>
  <Param name="bundleId" required type="number">
  ID of the bundle.
  </Param>
  <Param name="params" optional type="BundleItemsParams">
    Paging, filters and relations.

    <Properties label="params">
      <Param name="page" optional type="number">
      Page to fetch, counting from 1.
      </Param>
      <Param name="perPage" optional type="number">
      How many items per page.
      </Param>
      <Param name="filters" optional type="object[]">
      Attribute filters, built from `bundle.filters`.
      <Properties label="filter">
        <Param name="attributeId" required type="number">
        ID of the attribute, from `bundle.filters[].attributeId`.
        </Param>
        <Param name="values" required type="number[]">
        IDs of the chosen values, from `bundle.filters[].values[].id`.
        </Param>
      </Properties>
      </Param>
      <Param name="productIds" optional type="number[]">
      Keep only these variant IDs.
      </Param>
      <Param name="query" optional type="string">
      Free-text search over the item names.
      </Param>
      <Param name="expand" optional type="string[]">
      `product` and `product.parent`.
      </Param>
    </Properties>
  </Param>
  <Param name="headers" optional type="BundleRequestHeaders">
    Extra request headers.

    <Properties label="headers">
      <Param name="x-currency" optional type="string">
      Currency for the prices in the response.
      </Param>
    </Properties>
  </Param>
</Params>

<Returns type="Promise<BundleItemsResponse>">
One page of bundle items.
<Properties label="response">
  <Param name="data" type="BundleItem[]">
  The items on this page.
  <Properties label="item" collapsed>
    <BundleItemFields />
  </Properties>
  </Param>
  <Param name="pagination" type="Pagination">
  Where this page sits in the list.
  <Properties label="pagination">
    <PaginationFields />
  </Properties>
  </Param>
</Properties>
</Returns>

<Example>

```js title="Load the bundle items"
const { data } = await subbly.bundles.loadItems(512, {
  perPage: 50,
  expand: ['product'],
})
```

```js title="Filter the items by an attribute"
const { data } = await subbly.bundles.loadItems(512, {
  filters: [{ attributeId: 9, values: [31, 32] }],
})
```

</Example>

</Method>

<Method id="load-groups" signature="subbly.bundles.loadGroups(bundleId, params?, headers?)">

Gets the item groups of a bundle. A group gathers the variants of one product
and sets its own minimum and maximum quantity, so a customer can be asked for,
say, two coffees and one tea.

<Params>
  <Param name="bundleId" required type="number">
  ID of the bundle.
  </Param>
  <Param name="params" optional type="BundleGroupsParams">
    Paging and relations.

    <Properties label="params">
      <Param name="page" optional type="number">
      Page to fetch, counting from 1.
      </Param>
      <Param name="perPage" optional type="number">
      How many groups per page.
      </Param>
      <Param name="expand" optional type="string[]">
      `product`, `items.product` and `items.product.parent`.
      </Param>
    </Properties>
  </Param>
  <Param name="headers" optional type="BundleRequestHeaders">
    Extra request headers.

    <Properties label="headers">
      <Param name="x-currency" optional type="string">
      Currency for the prices in the response.
      </Param>
    </Properties>
  </Param>
</Params>

<Returns type="Promise<BundleGroupsResponse>">
One page of groups.
<Properties label="response">
  <Param name="data" type="BundleGroup[]">
  The groups on this page.
  <Properties label="group" collapsed>
    <BundleGroupFields />
  </Properties>
  </Param>
  <Param name="pagination" type="Pagination">
  Where this page sits in the list.
  <Properties label="pagination">
    <PaginationFields />
  </Properties>
  </Param>
</Properties>
</Returns>

<Example>

```js title="Load the bundle groups"
const { data } = await subbly.bundles.loadGroups(512, {
  expand: ['items.product'],
})
```

</Example>

</Method>

<Method id="quote" signature="subbly.bundles.quote(bundleId, payload, params?, headers?)">

Prices a bundle for the exact items and preferences a customer picked, before it
goes in the cart. Use it to show a running total in the picker.

<Params>
  <Param name="bundleId" required type="number">
  ID of the bundle.
  </Param>
  <Param name="payload" required type="BundleQuotePayload">
    What the customer picked. `items` and `preferences` are both required; send
    an empty array when the bundle has no preferences.

    <Properties label="payload">
      <Param name="productId" required type="number">
      The plan or variant the customer chose, from `bundle.plans[].plan.id` or
      `bundle.plans[].variant.id`.
      </Param>
      <Param name="quantity" required type="number">
      How many bundles.
      </Param>
      <Param name="items" required type="object[]">
      The picked items.
      <Properties label="item">
        <Param name="productId" required type="number">
        ID of the picked variant, from `bundleItem.productId`.
        </Param>
        <Param name="quantity" required type="number">
        How many of it.
        </Param>
      </Properties>
      </Param>
      <Param name="preferences" required type="object[]">
      The answers to the bundle preferences. Send `[]` when there are none.
      <Properties label="preference">
        <Param name="attributeId" required type="number">
        ID of the attribute, from `bundle.preferences[].attributeId`.
        </Param>
        <Param name="values" required type="number[]">
        IDs of the chosen values.
        </Param>
      </Properties>
      </Param>
    </Properties>
  </Param>
  <Param name="params" optional type="BundleQuoteParams">
    Relations to include.

    <Properties label="params">
      <Param name="expand" optional type="string[]">
      `items.product` and `items.product.parent`.
      </Param>
    </Properties>
  </Param>
  <Param name="headers" optional type="BundleRequestHeaders">
    Extra request headers.

    <Properties label="headers">
      <Param name="x-currency" optional type="string">
      Currency for the prices in the response.
      </Param>
    </Properties>
  </Param>
</Params>

<Returns type="Promise<BundleQuote>">
The priced bundle, with a line for every picked item.
<Properties label="quote" collapsed>
  <BundleQuoteFields />
</Properties>
</Returns>

<Example>

```js title="Quote a bundle"
const quote = await subbly.bundles.quote(512, {
  productId: 8801,
  quantity: 1,
  items: [
    { productId: 3301, quantity: 2 },
    { productId: 3307, quantity: 1 },
  ],
  preferences: [],
})
```

</Example>

</Method>
