feat(core-flows,payment,medusa,types): Refund reasons management API (#8436)

* feat(core-flows,payment,medusa,types): add ability to set and manage refund reasons

* fix(payment): validate total amount when refunding payment (#8437)

Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>

* feature: introduce additional_data to the product endpoints (#8405)

* chore(docs): Generated References (#8440)

Generated the following references:
- `product`

* chore: align payment database schema

* Update packages/core/core-flows/src/payment-collection/steps/create-refund-reasons.ts

Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>

* chore: address review

---------

Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
Co-authored-by: Harminder Virk <virk.officials@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2024-08-06 11:47:42 +02:00
1 parent 8fb079786d
commit 0ff5b975e7
36 files changed
+2412 -9

No files matched your search

@@ -15,7 +15,7 @@ export const POST = async (
input: {
payment_id: id,
created_by: req.auth_context.actor_id,
amount: req.validatedBody.amount,
...req.validatedBody,
},
})
@@ -9,7 +9,9 @@ export const defaultAdminPaymentFields = [
"captures.amount",
"refunds.id",
"refunds.amount",
"refunds.note",
"refunds.payment_id",
"refunds.refund_reason.label",
]
export const listTransformQueryConfig = {
@@ -55,5 +55,17 @@ export type AdminCreatePaymentRefundType = z.infer<
export const AdminCreatePaymentRefund = z
.object({
amount: z.number().optional(),
refund_reason_id: z.string().optional(),
note: z.string().optional(),
})
.strict()
export type AdminCreatePaymentRefundReasonType = z.infer<
typeof AdminCreatePaymentRefundReason
>
export const AdminCreatePaymentRefundReason = z
.object({
label: z.string(),
description: z.string().optional(),
})
.strict()
@@ -0,0 +1,66 @@
import {
deleteReturnReasonsWorkflow,
updateRefundReasonsWorkflow,
} from "@medusajs/core-flows"
import { RefundReasonResponse } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../types/routing"
import { refetchEntity } from "../../../utils/refetch-entity"
import { AdminUpdatePaymentRefundReasonType } from "../validators"
export const GET = async (
req: AuthenticatedMedusaRequest,
res: MedusaResponse<RefundReasonResponse>
) => {
const refund_reason = await refetchEntity(
"refund_reason",
req.params.id,
req.scope,
req.remoteQueryConfig.fields
)
res.json({ refund_reason })
}
export const POST = async (
req: AuthenticatedMedusaRequest<AdminUpdatePaymentRefundReasonType>,
res: MedusaResponse<RefundReasonResponse>
) => {
const { id } = req.params
await updateRefundReasonsWorkflow(req.scope).run({
input: [
{
...req.validatedBody,
id,
},
],
})
const refund_reason = await refetchEntity(
"refund_reason",
req.params.id,
req.scope,
req.remoteQueryConfig.fields
)
res.json({ refund_reason })
}
export const DELETE = async (
req: AuthenticatedMedusaRequest,
res: MedusaResponse
) => {
const { id } = req.params
const input = { ids: [id] }
await deleteReturnReasonsWorkflow(req.scope).run({ input })
res.json({
id,
object: "refund_reason",
deleted: true,
})
}
@@ -0,0 +1,64 @@
import { MiddlewareRoute } from "@medusajs/framework"
import { validateAndTransformBody } from "../../utils/validate-body"
import { validateAndTransformQuery } from "../../utils/validate-query"
import * as queryConfig from "./query-config"
import {
AdminCreatePaymentRefundReason,
AdminGetRefundReasonsParams,
AdminUpdatePaymentRefundReason,
} from "./validators"
export const adminRefundReasonsRoutesMiddlewares: MiddlewareRoute[] = [
{
method: ["GET"],
matcher: "/admin/refund-reasons",
middlewares: [
validateAndTransformQuery(
AdminGetRefundReasonsParams,
queryConfig.listTransformQueryConfig
),
],
},
{
method: ["POST"],
matcher: "/admin/refund-reasons",
middlewares: [
validateAndTransformBody(AdminCreatePaymentRefundReason),
validateAndTransformQuery(
AdminGetRefundReasonsParams,
queryConfig.retrieveTransformQueryConfig
),
],
},
{
method: ["POST"],
matcher: "/admin/refund-reasons/:id",
middlewares: [
validateAndTransformBody(AdminUpdatePaymentRefundReason),
validateAndTransformQuery(
AdminGetRefundReasonsParams,
queryConfig.retrieveTransformQueryConfig
),
],
},
{
method: ["GET"],
matcher: "/admin/refund-reasons/:id",
middlewares: [
validateAndTransformQuery(
AdminGetRefundReasonsParams,
queryConfig.retrieveTransformQueryConfig
),
],
},
{
method: ["DELETE"],
matcher: "/admin/refund-reasons/:id",
middlewares: [
validateAndTransformQuery(
AdminGetRefundReasonsParams,
queryConfig.retrieveTransformQueryConfig
),
],
},
]
@@ -0,0 +1,23 @@
export const defaultAdminRefundReasonFields = [
"id",
"label",
"description",
"created_at",
"updated_at",
"deleted_at",
]
export const defaultAdminRetrieveRefundReasonFields = [
...defaultAdminRefundReasonFields,
]
export const retrieveTransformQueryConfig = {
defaultFields: defaultAdminRetrieveRefundReasonFields,
isList: false,
}
export const listTransformQueryConfig = {
defaults: defaultAdminRefundReasonFields,
defaultLimit: 20,
isList: true,
}
@@ -0,0 +1,49 @@
import { createRefundReasonsWorkflow } from "@medusajs/core-flows"
import { AuthenticatedMedusaRequest, MedusaResponse } from "@medusajs/framework"
import {
PaginatedResponse,
RefundReasonResponse,
RefundReasonsResponse,
} from "@medusajs/types"
import { refetchEntities, refetchEntity } from "../../utils/refetch-entity"
import { AdminCreatePaymentRefundReasonType } from "./validators"
export const GET = async (
req: AuthenticatedMedusaRequest,
res: MedusaResponse<PaginatedResponse<RefundReasonsResponse>>
) => {
const { rows: refund_reasons, metadata } = await refetchEntities(
"refund_reasons",
req.filterableFields,
req.scope,
req.remoteQueryConfig.fields,
req.remoteQueryConfig.pagination
)
res.json({
refund_reasons,
count: metadata.count,
offset: metadata.skip,
limit: metadata.take,
})
}
export const POST = async (
req: AuthenticatedMedusaRequest<AdminCreatePaymentRefundReasonType>,
res: MedusaResponse<RefundReasonResponse>
) => {
const {
result: [refundReason],
} = await createRefundReasonsWorkflow(req.scope).run({
input: { data: [req.validatedBody] },
})
const refund_reason = await refetchEntity(
"refund_reason",
refundReason.id,
req.scope,
req.remoteQueryConfig.fields
)
res.status(200).json({ refund_reason })
}
@@ -0,0 +1,41 @@
import { z } from "zod"
import { createFindParams, createOperatorMap } from "../../utils/validators"
export type AdminCreatePaymentRefundReasonType = z.infer<
typeof AdminCreatePaymentRefundReason
>
export const AdminCreatePaymentRefundReason = z
.object({
label: z.string(),
description: z.string().nullish(),
})
.strict()
export type AdminUpdatePaymentRefundReasonType = z.infer<
typeof AdminUpdatePaymentRefundReason
>
export const AdminUpdatePaymentRefundReason = z
.object({
label: z.string().optional(),
description: z.string().nullish(),
})
.strict()
/**
* Parameters used to filter and configure the pagination of the retrieved refund reason.
*/
export const AdminGetRefundReasonsParams = createFindParams({
limit: 15,
offset: 0,
}).merge(
z.object({
id: z.union([z.string(), z.array(z.string())]).optional(),
q: z.string().optional(),
created_at: createOperatorMap().optional(),
updated_at: createOperatorMap().optional(),
deleted_at: createOperatorMap().optional(),
})
)
export type AdminGetRefundReasonsParamsType = z.infer<
typeof AdminGetRefundReasonsParams
>
+2
View File
@@ -23,6 +23,7 @@ import { adminProductTagRoutesMiddlewares } from "./admin/product-tags/middlewar
import { adminProductTypeRoutesMiddlewares } from "./admin/product-types/middlewares"
import { adminProductRoutesMiddlewares } from "./admin/products/middlewares"
import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares"
import { adminRefundReasonsRoutesMiddlewares } from "./admin/refund-reasons/middlewares"
import { adminRegionRoutesMiddlewares } from "./admin/regions/middlewares"
import { adminReservationRoutesMiddlewares } from "./admin/reservations/middlewares"
import { adminReturnReasonRoutesMiddlewares } from "./admin/return-reasons/middlewares"
@@ -107,5 +108,6 @@ export default defineMiddlewares([
...storeReturnReasonRoutesMiddlewares,
...adminReturnReasonRoutesMiddlewares,
...adminClaimRoutesMiddlewares,
...adminRefundReasonsRoutesMiddlewares,
...adminExchangeRoutesMiddlewares,
])