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:
1 parent
da5cc4cf7f
commit
76291823f4
5 files changed
+245
-25
No files matched your search
@@ -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,
|
InjectManager,
|
||||||
InjectTransactionManager,
|
InjectTransactionManager,
|
||||||
MedusaContext,
|
MedusaContext,
|
||||||
|
isString,
|
||||||
|
isObject,
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
import { joinerConfig } from "../joiner-config"
|
import { joinerConfig } from "../joiner-config"
|
||||||
import * as services from "../services"
|
import * as services from "../services"
|
||||||
@@ -91,22 +93,101 @@ export default class CustomerModuleService implements ICustomerModuleService {
|
|||||||
) {
|
) {
|
||||||
const data = Array.isArray(dataOrArray) ? dataOrArray : [dataOrArray]
|
const data = Array.isArray(dataOrArray) ? dataOrArray : [dataOrArray]
|
||||||
const customer = await this.customerService_.create(data, sharedContext)
|
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)) {
|
update(
|
||||||
return await this.baseRepository_.serialize<CustomerTypes.CustomerDTO[]>(
|
customerId: string,
|
||||||
customer,
|
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>(
|
const customers = await this.customerService_.update(
|
||||||
customer[0],
|
updateData,
|
||||||
{
|
sharedContext
|
||||||
populate: true,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
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_")
|
@InjectManager("baseRepository_")
|
||||||
@@ -174,19 +255,13 @@ export default class CustomerModuleService implements ICustomerModuleService {
|
|||||||
: [dataOrArrayOfData]
|
: [dataOrArrayOfData]
|
||||||
|
|
||||||
const groups = await this.customerGroupService_.create(data, sharedContext)
|
const groups = await this.customerGroupService_.create(data, sharedContext)
|
||||||
|
const serialized = await this.baseRepository_.serialize<
|
||||||
|
CustomerTypes.CustomerGroupDTO[]
|
||||||
|
>(groups, {
|
||||||
|
populate: true,
|
||||||
|
})
|
||||||
|
|
||||||
if (Array.isArray(dataOrArrayOfData)) {
|
return Array.isArray(dataOrArrayOfData) ? serialized : serialized[0]
|
||||||
return await this.baseRepository_.serialize<
|
|
||||||
CustomerTypes.CustomerGroupDTO[]
|
|
||||||
>(groups, {
|
|
||||||
populate: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return await this.baseRepository_.serialize<CustomerTypes.CustomerGroupDTO>(
|
|
||||||
groups[0],
|
|
||||||
{ populate: true }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async addCustomerToGroup(
|
async addCustomerToGroup(
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
import { CreateCustomerDTO, DAL } from "@medusajs/types"
|
import { CustomerTypes, DAL } from "@medusajs/types"
|
||||||
import { ModulesSdkUtils } from "@medusajs/utils"
|
import { ModulesSdkUtils } from "@medusajs/utils"
|
||||||
import { Customer } from "@models"
|
import { Customer } from "@models"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
cartRepository: DAL.RepositoryService
|
customerRepository: DAL.RepositoryService
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class CustomerService<
|
export default class CustomerService<
|
||||||
TEntity extends Customer = Customer
|
TEntity extends Customer = Customer
|
||||||
> extends ModulesSdkUtils.abstractServiceFactory<
|
> extends ModulesSdkUtils.abstractServiceFactory<
|
||||||
InjectedDependencies,
|
InjectedDependencies,
|
||||||
{ create: CreateCustomerDTO }
|
{
|
||||||
|
create: CustomerTypes.CreateCustomerDTO
|
||||||
|
update: CustomerTypes.UpdateCustomerDTO
|
||||||
|
}
|
||||||
>(Customer)<TEntity> {
|
>(Customer)<TEntity> {
|
||||||
constructor(container: InjectedDependencies) {
|
constructor(container: InjectedDependencies) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export interface CreateCustomerDTO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateCustomerDTO {
|
export interface UpdateCustomerDTO {
|
||||||
|
id: string
|
||||||
company_name?: string
|
company_name?: string
|
||||||
first_name?: string
|
first_name?: string
|
||||||
last_name?: string
|
last_name?: string
|
||||||
@@ -28,6 +29,24 @@ export interface CustomerGroupUpdatableFileds {
|
|||||||
metadata?: Record<string, unknown> | null
|
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 {
|
export interface UpdateCustomerGroupDTO {
|
||||||
id?: string
|
id?: string
|
||||||
name?: string
|
name?: string
|
||||||
|
|||||||
@@ -24,6 +24,29 @@ export interface ICustomerModuleService extends IModuleService {
|
|||||||
|
|
||||||
create(data: CreateCustomerDTO, sharedContext?: Context): Promise<CustomerDTO>
|
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(
|
createCustomerGroup(
|
||||||
data: CreateCustomerGroupDTO[],
|
data: CreateCustomerGroupDTO[],
|
||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
|
|||||||
Reference in new issue
Block a user