feat(customers): add delete and update (#6148)
Depends on #6137 **What** - Add update and delete methods to the customer module
This commit is contained in:
@@ -309,4 +309,104 @@ describe("Customer Module Service", () => {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("update", () => {
|
||||
it("should update a single customer", async () => {
|
||||
const [customer] = await service.create([
|
||||
{ first_name: "John", last_name: "Doe", email: "john.doe@example.com" },
|
||||
])
|
||||
|
||||
const updateData = { first_name: "Jonathan" }
|
||||
const updatedCustomer = await service.update(customer.id, updateData)
|
||||
|
||||
expect(updatedCustomer).toEqual(
|
||||
expect.objectContaining({ id: customer.id, first_name: "Jonathan" })
|
||||
)
|
||||
})
|
||||
|
||||
it("should update multiple customers by IDs", async () => {
|
||||
const customers = await service.create([
|
||||
{ first_name: "John", last_name: "Doe", email: "john.doe@example.com" },
|
||||
{
|
||||
first_name: "Jane",
|
||||
last_name: "Smith",
|
||||
email: "jane.smith@example.com",
|
||||
},
|
||||
])
|
||||
|
||||
const updateData = { last_name: "Updated" }
|
||||
const customerIds = customers.map((customer) => customer.id)
|
||||
const updatedCustomers = await service.update(customerIds, updateData)
|
||||
|
||||
updatedCustomers.forEach((updatedCustomer) => {
|
||||
expect(updatedCustomer).toEqual(
|
||||
expect.objectContaining({ last_name: "Updated" })
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it("should update customers using a selector", async () => {
|
||||
await service.create([
|
||||
{ first_name: "John", last_name: "Doe", email: "john.doe@example.com" },
|
||||
{ first_name: "Jane", last_name: "Doe", email: "jane.doe@example.com" },
|
||||
])
|
||||
|
||||
const selector = { last_name: "Doe" }
|
||||
const updateData = { last_name: "Updated" }
|
||||
const updatedCustomers = await service.update(selector, updateData)
|
||||
|
||||
updatedCustomers.forEach((updatedCustomer) => {
|
||||
expect(updatedCustomer).toEqual(
|
||||
expect.objectContaining({ last_name: "Updated" })
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("delete", () => {
|
||||
it("should delete a single customer", async () => {
|
||||
const [customer] = await service.create([
|
||||
{ first_name: "John", last_name: "Doe", email: "john.doe@example.com" },
|
||||
])
|
||||
|
||||
await service.delete(customer.id)
|
||||
|
||||
await expect(service.retrieve(customer.id)).rejects.toThrow(
|
||||
`Customer with id: ${customer.id} was not found`
|
||||
)
|
||||
})
|
||||
|
||||
it("should delete multiple customers by IDs", async () => {
|
||||
const customers = await service.create([
|
||||
{ first_name: "John", last_name: "Doe", email: "john.doe@example.com" },
|
||||
{
|
||||
first_name: "Jane",
|
||||
last_name: "Smith",
|
||||
email: "jane.smith@example.com",
|
||||
},
|
||||
])
|
||||
|
||||
const customerIds = customers.map((customer) => customer.id)
|
||||
await service.delete(customerIds)
|
||||
|
||||
for (const customer of customers) {
|
||||
await expect(service.retrieve(customer.id)).rejects.toThrow(
|
||||
`Customer with id: ${customer.id} was not found`
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it("should delete customers using a selector", async () => {
|
||||
await service.create([
|
||||
{ first_name: "John", last_name: "Doe", email: "john.doe@example.com" },
|
||||
{ first_name: "Jane", last_name: "Doe", email: "jane.doe@example.com" },
|
||||
])
|
||||
|
||||
const selector = { last_name: "Doe" }
|
||||
await service.delete(selector)
|
||||
|
||||
const remainingCustomers = await service.list({ last_name: "Doe" })
|
||||
expect(remainingCustomers.length).toBe(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -12,6 +12,8 @@ import {
|
||||
InjectManager,
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
isString,
|
||||
isObject,
|
||||
} from "@medusajs/utils"
|
||||
import { joinerConfig } from "../joiner-config"
|
||||
import * as services from "../services"
|
||||
@@ -91,22 +93,101 @@ export default class CustomerModuleService implements ICustomerModuleService {
|
||||
) {
|
||||
const data = Array.isArray(dataOrArray) ? dataOrArray : [dataOrArray]
|
||||
const customer = await this.customerService_.create(data, sharedContext)
|
||||
const serialized = await this.baseRepository_.serialize<
|
||||
CustomerTypes.CustomerDTO[]
|
||||
>(customer, {
|
||||
populate: true,
|
||||
})
|
||||
return Array.isArray(dataOrArray) ? serialized : serialized[0]
|
||||
}
|
||||
|
||||
if (Array.isArray(dataOrArray)) {
|
||||
return await this.baseRepository_.serialize<CustomerTypes.CustomerDTO[]>(
|
||||
customer,
|
||||
update(
|
||||
customerId: string,
|
||||
data: Partial<CustomerTypes.CreateCustomerDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<CustomerTypes.CustomerDTO>
|
||||
update(
|
||||
customerIds: string[],
|
||||
data: Partial<CustomerTypes.CreateCustomerDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<CustomerTypes.CustomerDTO[]>
|
||||
update(
|
||||
selector: CustomerTypes.FilterableCustomerProps,
|
||||
data: Partial<CustomerTypes.CreateCustomerDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<CustomerTypes.CustomerDTO[]>
|
||||
|
||||
@InjectTransactionManager("baseRepository_")
|
||||
async update(
|
||||
idsOrSelector: string | string[] | CustomerTypes.FilterableCustomerProps,
|
||||
data: Partial<CustomerTypes.CreateCustomerDTO>,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
) {
|
||||
let updateData: CustomerTypes.UpdateCustomerDTO[] = []
|
||||
if (typeof idsOrSelector === "string") {
|
||||
updateData = [
|
||||
{
|
||||
populate: true,
|
||||
}
|
||||
id: idsOrSelector,
|
||||
...data,
|
||||
},
|
||||
]
|
||||
} else if (Array.isArray(idsOrSelector)) {
|
||||
updateData = idsOrSelector.map((id) => ({
|
||||
id,
|
||||
...data,
|
||||
}))
|
||||
} else {
|
||||
const ids = await this.customerService_.list(
|
||||
idsOrSelector,
|
||||
{ select: ["id"] },
|
||||
sharedContext
|
||||
)
|
||||
updateData = ids.map(({ id }) => ({
|
||||
id,
|
||||
...data,
|
||||
}))
|
||||
}
|
||||
|
||||
return await this.baseRepository_.serialize<CustomerTypes.CustomerDTO>(
|
||||
customer[0],
|
||||
{
|
||||
populate: true,
|
||||
}
|
||||
const customers = await this.customerService_.update(
|
||||
updateData,
|
||||
sharedContext
|
||||
)
|
||||
const serialized = await this.baseRepository_.serialize<
|
||||
CustomerTypes.CustomerDTO[]
|
||||
>(customers, {
|
||||
populate: true,
|
||||
})
|
||||
|
||||
return isString(idsOrSelector) ? serialized[0] : serialized
|
||||
}
|
||||
|
||||
delete(customerId: string, sharedContext?: Context): Promise<void>
|
||||
delete(customerIds: string[], sharedContext?: Context): Promise<void>
|
||||
delete(
|
||||
selector: CustomerTypes.FilterableCustomerProps,
|
||||
sharedContext?: Context
|
||||
): Promise<void>
|
||||
|
||||
@InjectTransactionManager("baseRepository_")
|
||||
async delete(
|
||||
idsOrSelector: string | string[] | CustomerTypes.FilterableCustomerProps,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
) {
|
||||
let toDelete = Array.isArray(idsOrSelector)
|
||||
? idsOrSelector
|
||||
: [idsOrSelector as string]
|
||||
if (isObject(idsOrSelector)) {
|
||||
const ids = await this.customerService_.list(
|
||||
idsOrSelector,
|
||||
{
|
||||
select: ["id"],
|
||||
},
|
||||
sharedContext
|
||||
)
|
||||
toDelete = ids.map(({ id }) => id)
|
||||
}
|
||||
|
||||
return await this.customerService_.delete(toDelete, sharedContext)
|
||||
}
|
||||
|
||||
@InjectManager("baseRepository_")
|
||||
@@ -174,19 +255,13 @@ export default class CustomerModuleService implements ICustomerModuleService {
|
||||
: [dataOrArrayOfData]
|
||||
|
||||
const groups = await this.customerGroupService_.create(data, sharedContext)
|
||||
const serialized = await this.baseRepository_.serialize<
|
||||
CustomerTypes.CustomerGroupDTO[]
|
||||
>(groups, {
|
||||
populate: true,
|
||||
})
|
||||
|
||||
if (Array.isArray(dataOrArrayOfData)) {
|
||||
return await this.baseRepository_.serialize<
|
||||
CustomerTypes.CustomerGroupDTO[]
|
||||
>(groups, {
|
||||
populate: true,
|
||||
})
|
||||
}
|
||||
|
||||
return await this.baseRepository_.serialize<CustomerTypes.CustomerGroupDTO>(
|
||||
groups[0],
|
||||
{ populate: true }
|
||||
)
|
||||
return Array.isArray(dataOrArrayOfData) ? serialized : serialized[0]
|
||||
}
|
||||
|
||||
async addCustomerToGroup(
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { CreateCustomerDTO, DAL } from "@medusajs/types"
|
||||
import { CustomerTypes, DAL } from "@medusajs/types"
|
||||
import { ModulesSdkUtils } from "@medusajs/utils"
|
||||
import { Customer } from "@models"
|
||||
|
||||
type InjectedDependencies = {
|
||||
cartRepository: DAL.RepositoryService
|
||||
customerRepository: DAL.RepositoryService
|
||||
}
|
||||
|
||||
export default class CustomerService<
|
||||
TEntity extends Customer = Customer
|
||||
> extends ModulesSdkUtils.abstractServiceFactory<
|
||||
InjectedDependencies,
|
||||
{ create: CreateCustomerDTO }
|
||||
{
|
||||
create: CustomerTypes.CreateCustomerDTO
|
||||
update: CustomerTypes.UpdateCustomerDTO
|
||||
}
|
||||
>(Customer)<TEntity> {
|
||||
constructor(container: InjectedDependencies) {
|
||||
// @ts-ignore
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface CreateCustomerDTO {
|
||||
}
|
||||
|
||||
export interface UpdateCustomerDTO {
|
||||
id: string
|
||||
company_name?: string
|
||||
first_name?: string
|
||||
last_name?: string
|
||||
@@ -28,6 +29,24 @@ export interface CustomerGroupUpdatableFileds {
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export interface UpdateCustomerGroupDTO {
|
||||
id?: string
|
||||
name?: string
|
||||
customer_ids?: string[]
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export interface CreateCustomerGroupDTO {
|
||||
name: string
|
||||
metadata?: Record<string, unknown> | null
|
||||
created_by?: string
|
||||
}
|
||||
|
||||
export interface CustomerGroupUpdatableFileds {
|
||||
name?: string
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export interface UpdateCustomerGroupDTO {
|
||||
id?: string
|
||||
name?: string
|
||||
|
||||
@@ -24,6 +24,29 @@ export interface ICustomerModuleService extends IModuleService {
|
||||
|
||||
create(data: CreateCustomerDTO, sharedContext?: Context): Promise<CustomerDTO>
|
||||
|
||||
update(
|
||||
customerId: string,
|
||||
data: Partial<CreateCustomerDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<CustomerDTO>
|
||||
update(
|
||||
customerIds: string[],
|
||||
data: Partial<CreateCustomerDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<CustomerDTO[]>
|
||||
update(
|
||||
selector: FilterableCustomerProps,
|
||||
data: Partial<CreateCustomerDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<CustomerDTO[]>
|
||||
|
||||
delete(customerId: string, sharedContext?: Context): Promise<void>
|
||||
delete(customerIds: string[], sharedContext?: Context): Promise<void>
|
||||
delete(
|
||||
selector: FilterableCustomerProps,
|
||||
sharedContext?: Context
|
||||
): Promise<void>
|
||||
|
||||
createCustomerGroup(
|
||||
data: CreateCustomerGroupDTO[],
|
||||
sharedContext?: Context
|
||||
|
||||
Reference in New Issue
Block a user