v2.1.3

medusajs/medusav2.1.3Dec 20, 2024by olivermrbl

AI Summary

This version introduces dynamically calculated shipping option prices, allows nesting Admin UI routes under existing domains, and enables custom prices on line items.

Key Highlights

  • New storefront endpoint `POST /store/shipping-options/:id/calculate` for dynamically pricing shipping options.
  • Custom prices on line items allow decoupling variants from line items in cart workflows.
  • Admin UI Routes can now be nested under existing domains (e.g., Brands under Products).
  • Module DML migrations have been applied with non-breaking schema changes.
  • Orphan deletion has been removed from one-to-one relationships.

New Features

  • Support for Fulfillment Options with calculated prices.
  • Custom line items feature.
  • Add Credit Line to order module.
  • Pass variant details when creating fulfillment.

Full Release Notes

<!-- 
![ui-routes](https://github.com/user-attachments/assets/1b6520b3-a81f-456a-8c08-d08b2e0cf6a6)

# v2.1.3

This release introduces calculated shipping option prices, nesting UI Routes under existing domains, and more.

CMS_BREAK -->

## Highlights

### Calculated shipping option price

This release introduces dynamically calculated shipping option prices, which comprise three key changes:

**- Admin support for creating dynamically priced options**

When creating a shipping option, choose the "calculated" price type. Upon sending the request to create the option, our fulfillment module verifies if the provider and method support calculated prices.

**- New storefront endpoint to calculate shipping option prices**

To display calculated prices on the storefront, use the endpoint below. Calculated shipping options do not include a price in the regular request to retrieve options for a cart. These are calculated separately–one request for each option.

```
POST /store/shipping-options/:id/calculate
{ cart_id: "cart_1234", data: { ... } }
```

Pass custom data in the `data` property of the payload. The `data` is passed down to the provider and can be used for the calculation, e.g. distance to destination.

Our Next.js starter has been updated to include this feature. Check it out [here](https://github.com/medusajs/nextjs-starter-medusa/pull/436).

**- Changes to the `addShippingMethodToCartWorkflow`**

When adding a calculated shipping option to a cart, the price is computed dynamically similarly to the calculation endpoint. 

### Module DML migrations

More core modules have been migrated from MikroORM to DML. These migrations come with non-breaking schema changes, primarily around index renaming and adding default timestamp columns. 

**Removed orphan deletion**

Additionally, we've removed the default `orphanRemoval: true` configuration from one-to-one relationships. This is a less aggressive approach to cascade removal, meaning that disconnecting entities in such a relation will not delete the "child" of the association. 

**Required action**

Run migrations to ensure your server functions as expected after upgrading:
```
npx medusa db:migrate
```

As part of migrating modules to use DML, we've uncovered a range of minor bugs (not affecting end-users) and improvements. You can read more about those in [this PR](https://github.com/medusajs/medusa/pull/10617).


### Line items with custom prices

This release allows for custom prices on line items by decoupling variants and line items in the cart and order workflows.

Our core API doesn't support custom prices out of the box, however the underlying `addToCartWorkflow` does. 

Here's an example of how to use it in a custom API Route:
```ts
// POST /store/carts/:id/custom-line-items
import { addToCartWorkflow } from "@medusajs/medusa/core-flows"

async function thirdPartyCallToComputePrice(item: any) {
  return {
    ...item,
    unit_price: Math.floor(Math.random() * 900) + 100,
  }
}

export const POST = async (req, res) => {
  const { id } = req.params
  const { items } = req.body

  const query = req.scope.resolve("query")

  const itemsWithDynamicPrice = await Promise.all(
    items.map((item) => {
      return thirdPartyCallToComputePrice(item)
    })
  )

  const workflowInput = {
    items: itemsWithDynamicPrice,
    cart_id: id,
  }

  await addToCartWorkflow(req.scope).run({
    input: workflowInput,
  })

  const updatedCart = await query.graph({
    entity: "cart",
    filters: { id },
    fields: ["id", "items.*"],
  })

  res.status(200).json({ cart: updatedCart })
}
```

### Nesting Admin UI Routes under existing domains

This release introduces support for nesting a UI Route under an existing domain in the sidebar instead of in the extensions section. 

For example, you can locate Brands under Products:
```tsx title="src/admin/routes/products/brands/page.tsx"
 import { defineRouteConfig } from "@medusajs/admin-sdk"
 import { Container, Heading } from "@medusajs/ui"

 const NestedProductsPage = () => {
   return (
     <Container className="divide-y p-0">
       <div className="flex items-center justify-between px-6 py-4">
         <Heading level="h1">Nested Products Page</Heading>
       </div>
     </Container>
   )
 }

 export const config = defineRouteConfig({
   label: "Nested Products",
   nested: "/products",
 })

 export default NestedProductsPage
 ```

This improvement to our existing UI Routes tooling was a community contribution from @eugenepro2. 

## Features
* feat(core-flows,dashboard,js-sdk,medusa,types): support Fulfillment Options by @fPolic in https://github.com/medusajs/medusa/pull/10622
* feat: Custom line items by @olivermrbl in https://github.com/medusajs/medusa/pull/10408
* feat(order, types): Add Credit Line to order module by @riqwan in https://github.com/medusajs/medusa/pull/10636
* feat(core-flows): pass fields variant details when creating fulfillment by @fPolic in https://github.com/medusajs/medusa/pull/10665

## Bugs
* fix(core-flows): export getItemTaxLinesStep by @shahednasser in https://github.com/medusajs/medusa/pull/10640
* fix(medusa): Missing metadata field on order by @olivermrbl in https://github.com/medusajs/medusa/pull/10651
* fix(dashboard): order details status by @fPolic in https://github.com/medusajs/medusa/pull/10650
* fix(notification): Only use enabled providers for notis by @olivermrbl in https://github.com/medusajs/medusa/pull/10659
* fix(core-flows): use useQueryGraphStep instead of useQueryStep by @shahednasser in https://github.com/medusajs/medusa/pull/10643
* fix(core-flows): data passed to to fulfillment provider context by @fPolic in https://github.com/medusajs/medusa/pull/10660
* fix(core-flows): refresh payment collections upon shipping changes by @riqwan in https://github.com/medusajs/medusa/pull/10673
* fix(product): updating collections with products fix by @riqwan in https://github.com/medusajs/medusa/pull/10668
* fix(core-flows): select stock locations for reservation from correct SC by @fPolic in https://github.com/medusajs/medusa/pull/10661

## Documentation
* docs: document float property (for v2.1.2) by @shahednasser in https://github.com/medusajs/medusa/pull/10575
* docs-util: infer resolved resources in workflow + steps by @shahednasser in https://github.com/medusajs/medusa/pull/10637
* docs: generate references manually for v2.1.2 by @shahednasser in https://github.com/medusajs/medusa/pull/10639
* chore: fix redocly circular dependencies by @shahednasser in https://github.com/medusajs/medusa/pull/10642
* docs: add tags package to generate tags by @shahednasser in https://github.com/medusajs/medusa/pull/10666
* docs: support generating sidebar items with tags by @shahednasser in https://github.com/medusajs/medusa/pull/10672
* docs: add tags manually to doc pages by @shahednasser in https://github.com/medusajs/medusa/pull/10675
* docs: remove duplicate parsed tag items by @shahednasser in https://github.com/medusajs/medusa/pull/10676
 
## Chores
* chore(types): Keep intelisense while being more loosen by @adrien2p in https://github.com/medusajs/medusa/pull/10657
* chore: improve tsdocs of fulfillment provider by @shahednasser in https://github.com/medusajs/medusa/pull/10649
* chore(fulfillment, utils): Migrate module to DML by @adrien2p in https://github.com/medusajs/medusa/pull/10617

## Other Changes
* Add FilterableRefundReason filter by description and label by @vethan in https://github.com/medusajs/medusa/pull/10606
* feat(dashboard): ability to locate new admin route under existing route by @eugenepro2 in https://github.com/medusajs/medusa/pull/10587

## New Contributors
* @vethan made their first contribution in https://github.com/medusajs/medusa/pull/10606
* @eugenepro2 made their first contribution in https://github.com/medusajs/medusa/pull/10587

**Full Changelog**: https://github.com/medusajs/medusa/compare/v2.1.2...v2.1.3