Skip to content

Commit 2cda229

Browse files
committed
refactor: extract prices function to util, comments
1 parent 8b616f0 commit 2cda229

File tree

5 files changed

+1447
-1528
lines changed

5 files changed

+1447
-1528
lines changed

src/app/api/categories/[...handle]/route.ts

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
import { NextRequest, NextResponse } from "next/server"
22
import { initialize as initializeProductModule } from "@medusajs/product"
33
import { ProductDTO } from "@medusajs/types/dist/product"
4+
import { IPricingModuleService } from "@medusajs/types"
45
import { notFound } from "next/navigation"
56
import { MedusaApp, Modules } from "@medusajs/modules-sdk"
7+
import { getPricesByPriceSetId } from "@lib/util/get-prices-by-price-set-id"
68

79
/**
8-
* This endpoint uses the serverless Product Module to retrieve a category and its products by handle.
10+
* This endpoint uses the serverless Product and Pricing Modules to retrieve a category and its products by handle.
911
* The module connects directly to you Medusa database to retrieve and manipulate data, without the need for a dedicated server.
1012
* Read more about the Product Module here: https://docs.medusajs.com/modules/products/serverless-module
1113
*/
1214
export async function GET(
1315
request: NextRequest,
1416
{ params }: { params: Record<string, any> }
1517
) {
18+
// Initialize the Product Module
1619
const productService = await initializeProductModule()
1720

21+
// Extract the query parameters
1822
const searchParams = Object.fromEntries(request.nextUrl.searchParams)
1923
const { page, limit } = searchParams
2024

@@ -24,6 +28,7 @@ export async function GET(
2428
categoryHandle.slice(0, index + 1).join("/")
2529
)
2630

31+
// Fetch the category by handle
2732
const product_categories = await productService
2833
.listCategories(
2934
{
@@ -45,17 +50,21 @@ export async function GET(
4550
return notFound()
4651
}
4752

53+
// Fetch the products by category id
4854
const {
4955
rows: products,
5056
metadata: { count },
5157
} = await getProductsByCategoryId(category.id, searchParams)
5258

59+
// Filter out unpublished products
5360
const publishedProducts: ProductDTO[] = products.filter(
5461
(product) => product.status === "published"
5562
)
5663

64+
// Calculate the next page
5765
const nextPage = parseInt(page) + parseInt(limit)
5866

67+
// Return the response
5968
return NextResponse.json({
6069
product_categories: Object.values(product_categories),
6170
response: {
@@ -66,6 +75,12 @@ export async function GET(
6675
})
6776
}
6877

78+
/**
79+
* This function uses the serverless Product and Pricing Modules to retrieve products by category id.
80+
* @param category_id The category id
81+
* @param params The query parameters
82+
* @returns The products and metadata
83+
*/
6984
async function getProductsByCategoryId(
7085
category_id: string,
7186
params: Record<string, any>
@@ -75,22 +90,18 @@ async function getProductsByCategoryId(
7590

7691
currency_code = currency_code && currency_code.toUpperCase()
7792

93+
// Initialize Remote Query with the Product and Pricing Modules
7894
const { query, modules } = await MedusaApp({
79-
modulesConfig: [
80-
{
81-
module: Modules.PRODUCT,
82-
path: "@medusajs/product",
83-
},
84-
{
85-
module: Modules.PRICING,
86-
path: "@medusajs/pricing",
87-
},
88-
],
95+
modulesConfig: {
96+
[Modules.PRODUCT]: true,
97+
[Modules.PRICING]: true,
98+
},
8999
sharedResourcesConfig: {
90100
database: { clientUrl: process.env.POSTGRES_URL },
91101
},
92102
})
93103

104+
// Set the filters for the query
94105
const filters = {
95106
take: parseInt(params.limit) || 100,
96107
skip: parseInt(params.offset) || 0,
@@ -100,6 +111,7 @@ async function getProductsByCategoryId(
100111
currency_code,
101112
}
102113

114+
// Set the GraphQL query
103115
const productsQuery = `#graphql
104116
query($filters: Record, $take: Int, $skip: Int) {
105117
products(filters: $filters, take: $take, skip: $skip) {
@@ -147,33 +159,19 @@ async function getProductsByCategoryId(
147159
}
148160
}`
149161

162+
// Run the query
150163
const { rows, metadata } = await query(productsQuery, filters)
151164

152-
for (const product of rows) {
153-
for (const variant of product.variants) {
154-
const priceSetIds = variant.price.map((price) => price.price_set.id)
155-
156-
const prices = await modules.pricingService.calculatePrices(
157-
{ id: priceSetIds },
158-
{
159-
context: { currency_code },
160-
}
161-
)
162-
163-
const price = prices.find(
164-
(price) => price.currency_code === currency_code
165-
)
166-
167-
if (!price) continue
168-
169-
delete variant.price
170-
variant.price = price
171-
variant.calculated_price = price.amount
172-
}
173-
}
165+
// Calculate prices
166+
const productsWithPrices = await getPricesByPriceSetId({
167+
products: rows,
168+
currency_code,
169+
pricingService: modules.pricingService as unknown as IPricingModuleService,
170+
})
174171

172+
// Return the response
175173
return {
176-
rows,
174+
rows: productsWithPrices,
177175
metadata,
178176
}
179177
}

src/app/api/collections/[handle]/route.ts

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { notFound } from "next/navigation"
44
import { initialize as initializeProductModule } from "@medusajs/product"
55
import { MedusaApp, Modules } from "@medusajs/modules-sdk"
66
import { ProductCollectionDTO, ProductDTO } from "@medusajs/types/dist/product"
7+
import { IPricingModuleService } from "@medusajs/types"
8+
import { getPricesByPriceSetId } from "@lib/util/get-prices-by-price-set-id"
79

810
/**
911
* This endpoint uses the serverless Product Module to retrieve a collection and its products by handle.
@@ -14,38 +16,47 @@ export async function GET(
1416
request: NextRequest,
1517
{ params }: { params: Record<string, any> }
1618
) {
19+
// Initialize the Product Module
1720
const productService = await initializeProductModule()
1821

22+
// Extract the query parameters
1923
const { handle } = params
2024

2125
const searchParams = Object.fromEntries(request.nextUrl.searchParams)
2226
const { page, limit } = searchParams
2327

28+
// Fetch the collections
2429
const collections = await productService.listCollections()
2530

31+
// Create a map of collections by handle
2632
const collectionsByHandle = new Map<string, ProductCollectionDTO>()
2733

2834
for (const collection of collections) {
2935
collectionsByHandle.set(collection.handle, collection)
3036
}
3137

38+
// Fetch the collection by handle
3239
const collection = collectionsByHandle.get(handle)
3340

3441
if (!collection) {
3542
return notFound()
3643
}
3744

45+
// Fetch the products by collection id
3846
const {
3947
rows: products,
4048
metadata: { count },
4149
} = await getProductsByCollectionId(collection.id, searchParams)
4250

51+
// Filter out unpublished products
4352
const publishedProducts: ProductDTO[] = products.filter(
4453
(product) => product.status === "published"
4554
)
4655

56+
// Calculate the next page
4757
const nextPage = parseInt(page) + parseInt(limit)
4858

59+
// Return the response
4960
return NextResponse.json({
5061
collections: [collection],
5162
response: {
@@ -56,6 +67,12 @@ export async function GET(
5667
})
5768
}
5869

70+
/**
71+
* This endpoint uses the serverless Product and Pricing Modules to retrieve a product list.
72+
* @param collection_id The collection id to filter by
73+
* @param params The query parameters
74+
* @returns The products and metadata
75+
*/
5976
async function getProductsByCollectionId(
6077
collection_id: string,
6178
params: Record<string, any>
@@ -65,22 +82,18 @@ async function getProductsByCollectionId(
6582

6683
currency_code = currency_code && currency_code.toUpperCase()
6784

85+
// Initialize Remote Query with the Product and Pricing Modules
6886
const { query, modules } = await MedusaApp({
69-
modulesConfig: [
70-
{
71-
module: Modules.PRODUCT,
72-
path: "@medusajs/product",
73-
},
74-
{
75-
module: Modules.PRICING,
76-
path: "@medusajs/pricing",
77-
},
78-
],
87+
modulesConfig: {
88+
[Modules.PRODUCT]: true,
89+
[Modules.PRICING]: true,
90+
},
7991
sharedResourcesConfig: {
8092
database: { clientUrl: process.env.POSTGRES_URL },
8193
},
8294
})
8395

96+
// Set the filters for the query
8497
const filters = {
8598
take: parseInt(params.limit) || 100,
8699
skip: parseInt(params.offset) || 0,
@@ -90,6 +103,7 @@ async function getProductsByCollectionId(
90103
currency_code,
91104
}
92105

106+
// Set the GraphQL query
93107
const productsQuery = `#graphql
94108
query($filters: Record, $take: Int, $skip: Int) {
95109
products(filters: $filters, take: $take, skip: $skip) {
@@ -137,33 +151,19 @@ async function getProductsByCollectionId(
137151
}
138152
}`
139153

154+
// Run the query
140155
const { rows, metadata } = await query(productsQuery, filters)
141156

142-
for (const product of rows) {
143-
for (const variant of product.variants) {
144-
const priceSetIds = variant.price.map((price) => price.price_set.id)
145-
146-
const prices = await modules.pricingService.calculatePrices(
147-
{ id: priceSetIds },
148-
{
149-
context: { currency_code },
150-
}
151-
)
152-
153-
const price = prices.find(
154-
(price) => price.currency_code === currency_code
155-
)
156-
157-
if (!price) continue
158-
159-
delete variant.price
160-
variant.price = price
161-
variant.calculated_price = price.amount
162-
}
163-
}
157+
// Calculate prices
158+
const productsWithPrices = await getPricesByPriceSetId({
159+
products: rows,
160+
currency_code,
161+
pricingService: modules.pricingService as unknown as IPricingModuleService,
162+
})
164163

164+
// Return the response
165165
return {
166-
rows,
166+
rows: productsWithPrices,
167167
metadata,
168168
}
169169
}

src/app/api/products/route.ts

Lines changed: 16 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { NextRequest, NextResponse } from "next/server"
22
import { notFound } from "next/navigation"
33

44
import { MedusaApp, Modules } from "@medusajs/modules-sdk"
5+
import { getPricesByPriceSetId } from "@lib/util/get-prices-by-price-set-id"
6+
import { IPricingModuleService } from "@medusajs/types"
57

68
/**
79
* This endpoint uses the serverless Product and Pricing Modules to retrieve a product list.
@@ -28,27 +30,15 @@ async function getProducts(params: Record<string, any>) {
2830
limit = limit && parseInt(limit)
2931
currency_code = currency_code && currency_code.toUpperCase()
3032

31-
// configure the modules for Remote Query
32-
const modulesConfig = [
33-
{
34-
module: Modules.PRODUCT,
35-
path: "@medusajs/product",
36-
},
37-
{
38-
module: Modules.PRICING,
39-
path: "@medusajs/pricing",
40-
},
41-
]
42-
43-
// configure the shared resources for Remote Query
44-
const sharedResourcesConfig = {
45-
database: { clientUrl: process.env.POSTGRES_URL },
46-
}
47-
4833
// Initialize Remote Query with the Product and Pricing Modules
4934
const { query, modules } = await MedusaApp({
50-
modulesConfig,
51-
sharedResourcesConfig,
35+
modulesConfig: {
36+
[Modules.PRODUCT]: true,
37+
[Modules.PRICING]: true,
38+
},
39+
sharedResourcesConfig: {
40+
database: { clientUrl: process.env.POSTGRES_URL },
41+
},
5242
})
5343

5444
// Set the filters for the query
@@ -112,35 +102,19 @@ async function getProducts(params: Record<string, any>) {
112102
metadata: { count },
113103
} = await query(productsQuery, filters)
114104

115-
for (const product of products) {
116-
for (const variant of product.variants) {
117-
const priceSetIds = variant.price.map((price) => price.price_set.id)
118-
119-
const prices = await modules.pricingService.calculatePrices(
120-
{ id: priceSetIds },
121-
{
122-
context: { currency_code },
123-
}
124-
)
125-
126-
const price = prices.find(
127-
(price) => price.currency_code === currency_code
128-
)
129-
130-
if (!price) continue
131-
132-
delete variant.price
133-
variant.price = price
134-
variant.calculated_price = price.amount
135-
}
136-
}
105+
// Calculate prices
106+
const productsWithPrices = await getPricesByPriceSetId({
107+
products,
108+
currency_code,
109+
pricingService: modules.pricingService as unknown as IPricingModuleService,
110+
})
137111

138112
// Calculate the next page
139113
const nextPage = offset + limit
140114

141115
// Return the response
142116
return {
143-
products,
117+
products: productsWithPrices,
144118
count: count,
145119
nextPage: count > nextPage ? nextPage : null,
146120
}

0 commit comments

Comments
 (0)