docs: add details on updating a cart's customer (#10226)

Should be merged after releasing v2.0.5

Closes DX-1096
This commit is contained in:
Shahed Nasser
2024-11-25 13:56:35 +02:00
committed by GitHub
parent 01b0a84898
commit ae1c607f4e
12 changed files with 110 additions and 65 deletions

View File

@@ -233,7 +233,7 @@ export const GET = async (
const b = req.validatedQuery.b as number
res.json({
sum: a + b
sum: a + b,
})
}
```

View File

@@ -149,7 +149,7 @@ class HelloModuleService {
data: {
id: "123",
// other data payload
}
},
})
}
}
@@ -167,7 +167,7 @@ export const depsHighlight = [
]
```ts title="medusa-config.ts" highlights={depsHighlight}
import { Modules } from '@medusajs/framework/utils'
import { Modules } from "@medusajs/framework/utils"
module.exports = defineConfig({
// ...
@@ -175,10 +175,10 @@ module.exports = defineConfig({
{
resolve: "./src/modules/hello",
dependencies: [
Modules.EVENT_BUS
]
}
]
Modules.EVENT_BUS,
],
},
],
})
```

View File

@@ -150,7 +150,7 @@ const { data: productCustoms } = await query.graph({
take: 5,
skip: 0,
},
});
})
```
In the object passed to the `graph` method:
@@ -318,9 +318,9 @@ export default defineMiddlewares({
defaults: [
"id",
"name",
"products.*"
"products.*",
],
isList: true
isList: true,
}
),
],
@@ -371,7 +371,7 @@ export const GET = async (
const { data: myCustoms } = await query.graph({
entity: "my_custom",
...req.remoteQueryConfig
...req.remoteQueryConfig,
})
res.json({ my_customs: myCustoms })

View File

@@ -106,7 +106,7 @@ const myWorkflow = createWorkflow(
const today = new Date()
return new WorkflowResponse({
today
today,
})
})
@@ -117,7 +117,7 @@ const myWorkflow = createWorkflow(
const today = transform({}, () => new Date())
return new WorkflowResponse({
today
today,
})
})
```

View File

@@ -16,7 +16,7 @@ Each workflow step must have a unique ID, which is the ID passed as a first para
```ts
const useQueryGraphStep = createStep(
"use-query-graph",
"use-query-graph"
// ...
)
```
@@ -29,13 +29,13 @@ const helloWorkflow = createWorkflow(
() => {
const { data: products } = useQueryGraphStep({
entity: "product",
fields: ["id"]
fields: ["id"],
})
// ERROR OCCURS HERE: A STEP HAS THE SAME ID AS ANOTHER IN THE WORKFLOW
const { data: customers } = useQueryGraphStep({
entity: "customer",
fields: ["id"]
fields: ["id"],
})
}
)
@@ -63,13 +63,13 @@ const helloWorkflow = createWorkflow(
() => {
const { data: products } = useQueryGraphStep({
entity: "product",
fields: ["id"]
fields: ["id"],
})
// ✓ No error occurs, the step has a different ID.
const { data: customers } = useQueryGraphStep({
entity: "customer",
fields: ["id"]
fields: ["id"],
}).config({ name: "fetch-customers" })
}
)

View File

@@ -54,8 +54,8 @@ export default async function orderPlacedHandler({
await sendOrderConfirmationWorkflow(container)
.run({
input: {
id: data.id
}
id: data.id,
},
})
}

View File

@@ -133,8 +133,8 @@ export const loaderHighlights = [
```ts title="src/modules/mongo/loaders/connection.ts" highlights={loaderHighlights}
import { LoaderOptions } from "@medusajs/framework/types"
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
import { asValue } from "awilix";
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
import { asValue } from "awilix"
import { MongoClient } from "mongodb"
type ModuleOptions = {
@@ -144,7 +144,7 @@ type ModuleOptions = {
export default async function mongoConnectionLoader({
container,
options
options,
}: LoaderOptions<ModuleOptions>) {
if (!options.connection_url) {
throw new Error(`[MONGO MDOULE]: connection_url option is required.`)
@@ -187,10 +187,10 @@ module.exports = defineConfig({
resolve: "./src/modules/mongo",
options: {
connection_url: process.env.MONGO_CONNECTION_URL,
db_name: process.env.MONGO_DB_NAME
}
}
]
db_name: process.env.MONGO_DB_NAME,
},
},
],
})
```
@@ -239,11 +239,11 @@ export default class MongoModuleService {
const moviesCol = this.mongoClient_.collection("movie")
const insertedMovie = await moviesCol.insertOne({
title
title,
})
const movie = await moviesCol.findOne({
_id: insertedMovie.insertedId
_id: insertedMovie.insertedId,
})
return movie
@@ -254,8 +254,8 @@ export default class MongoModuleService {
await moviesCol.deleteOne({
_id: {
equals: id
}
equals: id,
},
})
}
}
@@ -274,7 +274,7 @@ export const MONGO_MODULE = "mongo"
export default Module(MONGO_MODULE, {
service: MongoModuleService,
loaders: [mongoConnectionLoader]
loaders: [mongoConnectionLoader],
})
```

View File

@@ -26,8 +26,8 @@ export const highlights = [
]
```ts highlights={highlights}
import { MedusaRequest, MedusaResponse } from "@medusajs/framework";
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
import { MedusaRequest, MedusaResponse } from "@medusajs/framework"
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
export async function GET(
req: MedusaRequest,
@@ -41,12 +41,12 @@ export async function GET(
entity: "product",
fields: ["*"],
filters: {
id: "prod_123"
}
id: "prod_123",
},
})
res.json({
products
products,
})
}
```
@@ -84,7 +84,7 @@ export const subscriberHighlights = [
```ts highlights={subscriberHighlights}
import { SubscriberArgs, type SubscriberConfig } from "@medusajs/framework"
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
export default async function productCreateHandler({
event: { data },
@@ -96,8 +96,8 @@ export default async function productCreateHandler({
entity: "product",
fields: ["*"],
filters: {
id: data.id
}
id: data.id,
},
})
console.log(`You created a product with the title ${products[0].title}`)
@@ -119,7 +119,7 @@ export const scheduledJobHighlights = [
```ts highlights={scheduledJobHighlights}
import { MedusaContainer } from "@medusajs/framework/types"
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
export default async function myCustomJob(
container: MedusaContainer
@@ -130,8 +130,8 @@ export default async function myCustomJob(
entity: "product",
fields: ["*"],
filters: {
id: "prod_123"
}
id: "prod_123",
},
})
console.log(
@@ -160,7 +160,7 @@ import {
createStep,
StepResponse,
} from "@medusajs/framework/workflows-sdk"
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
const step1 = createStep("step-1", async (_, { container }) => {
const query = container.resolve(ContainerRegistrationKeys.QUERY)
@@ -169,8 +169,8 @@ const step1 = createStep("step-1", async (_, { container }) => {
entity: "product",
fields: ["*"],
filters: {
id: "prod_123"
}
id: "prod_123",
},
})
return new StepResponse(products)

View File

@@ -37,7 +37,7 @@ import { model } from "@medusajs/framework/utils"
const Post = model.define("post", {
id: model.id().primaryKey(),
title: model.text()
title: model.text(),
})
export default Post
@@ -143,8 +143,8 @@ module.exports = defineConfig({
},
modules: [
{
resolve: "./src/modules/blog"
}
resolve: "./src/modules/blog",
},
],
})
```
@@ -168,16 +168,16 @@ npx medusa db:generate blog
The `db:generate` command of the Medusa CLI accepts one or more module names to generate the migration for. It will create a migration file for the Blog Module in the directory `src/modules/blog/migrations` similar to the following:
```ts
import { Migration } from '@mikro-orm/migrations';
import { Migration } from "@mikro-orm/migrations"
export class Migration20241121103722 extends Migration {
async up(): Promise<void> {
this.addSql('create table if not exists "post" ("id" text not null, "title" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "post_pkey" primary key ("id"));');
this.addSql("create table if not exists \"post\" (\"id\" text not null, \"title\" text not null, \"created_at\" timestamptz not null default now(), \"updated_at\" timestamptz not null default now(), \"deleted_at\" timestamptz null, constraint \"post_pkey\" primary key (\"id\"));")
}
async down(): Promise<void> {
this.addSql('drop table if exists "post" cascade;');
this.addSql("drop table if exists \"post\" cascade;")
}
}
@@ -226,10 +226,10 @@ import {
createStep,
createWorkflow,
StepResponse,
WorkflowResponse
} from "@medusajs/framework/workflows-sdk";
import { BLOG_MODULE } from "../modules/blog";
import BlogModuleService from "../modules/blog/service";
WorkflowResponse,
} from "@medusajs/framework/workflows-sdk"
import { BLOG_MODULE } from "../modules/blog"
import BlogModuleService from "../modules/blog/service"
type CreatePostWorkflowInput = {
title: string
@@ -241,7 +241,7 @@ const createPostStep = createStep(
const blogModuleService: BlogModuleService = container.resolve(BLOG_MODULE)
const post = await blogModuleService.createPosts({
title
title,
})
return new StepResponse(post, post)
@@ -272,11 +272,11 @@ You'll now execute that workflow in an API route to expose the feature of creati
```ts
import type {
MedusaRequest,
MedusaResponse
} from "@medusajs/framework/http";
MedusaResponse,
} from "@medusajs/framework/http"
import {
createPostWorkflow
} from "../../../workflows/create-post";
createPostWorkflow,
} from "../../../workflows/create-post"
export async function POST(
req: MedusaRequest,
@@ -285,12 +285,12 @@ export async function POST(
const { result: post } = await createPostWorkflow(req.scope)
.run({
input: {
title: "My Post"
}
title: "My Post",
},
})
res.json({
post
post,
})
}
```

View File

@@ -159,7 +159,7 @@ module.exports = defineConfig({
},
},
},
]
],
})
```

View File

@@ -118,3 +118,5 @@ This is necessary, as only products matching the cart's sales channel(s) can be
## Associate Customer with Cart
When the cart is created for a logged-in customer, it's automatically associated with that customer.
However, if the cart is created for a guest customer, then the customer logs in, then you have to set the cart's customer as explained in [this guide](../update/page.mdx#set-carts-customer).

View File

@@ -46,3 +46,46 @@ fetch(`http://localhost:9000/store/carts/${cartId}`, {
```
The Update Cart API route accepts a `region_id` request body parameter, whose value is the new region to associate with the cart.
---
## Set Cart's Customer
You might need to change the cart's customer in two cases:
- You created the cart for the customer as a guest, then they logged-in, so you want to associate the cart with them as a registered customer.
- You're transfering the cart from one customer to another, which is useful in company setups, such as when implementing B2B commerce applicatons.
To set or change the cart's customer, send an authenticated `POST` request to the Set Cart's Customer API route:
<Note>
This API route is only available after [Medusa v2.0.5](https://github.com/medusajs/medusa/releases/tag/v2.0.5).
</Note>
```ts
fetch(`http://localhost:9000/store/carts/${cartId}/customer`, {
credentials: "include",
method: "POST",
headers: {
"Content-Type": "application/json",
},
})
.then((res) => res.json())
.then(({ cart }) => {
// use cart...
console.log(cart)
})
```
To send an authenticated request, either use `credentials: include` if the customer is already authenticated with a cookie session, or pass the Authorization Bearer token in the request's header.
<Note title="Tip">
Learn more about authenticating customers in [this guide](../../customers/login/page.mdx).
</Note>
The cart is now associated with the logged-in customer.