Feat: Add groups to list customer (#1113)
* add controllers directory and loaders * update integration tests * start groups * move controllers to pure functions * group filtering for customers * print errors * remove verbose flag * controller refactor * update imports * Feat/list customers by customer group (#1114) * move controllers to pure functions * add customer group test * add api for list customer group customers * remove unused imports * controller refactor * update imports * Update packages/medusa/src/api/routes/admin/customer-groups/get-customer-group-customers.ts Co-authored-by: Sebastian Rindom <skrindom@gmail.com> Co-authored-by: Sebastian Rindom <skrindom@gmail.com> * fix: dedupe Co-authored-by: Sebastian Rindom <skrindom@gmail.com>
This commit is contained in:
@@ -193,6 +193,53 @@ describe("/admin/customer-groups", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("GET /admin/customer-groups/{id}/customers", () => {
|
||||
beforeEach(async () => {
|
||||
try {
|
||||
await adminSeeder(dbConnection)
|
||||
await customerSeeder(dbConnection)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
throw err
|
||||
}
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
const db = useDb()
|
||||
await db.teardown()
|
||||
})
|
||||
|
||||
it("lists customers in group and count", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api
|
||||
.get("/admin/customer-groups/test-group-5/customers", {
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.count).toEqual(3)
|
||||
expect(response.data.customers).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: "test-customer-5",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: "test-customer-6",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: "test-customer-7",
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /admin/customer-groups/{id}/customers/batch", () => {
|
||||
beforeEach(async () => {
|
||||
try {
|
||||
|
||||
@@ -75,6 +75,36 @@ describe("/admin/customers", () => {
|
||||
)
|
||||
})
|
||||
|
||||
it("lists customers in group and count", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api
|
||||
.get("/admin/customers?groups[]=test-group-5", {
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.count).toEqual(3)
|
||||
expect(response.data.customers).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: "test-customer-5",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: "test-customer-6",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: "test-customer-7",
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("lists customers with specific query", async () => {
|
||||
const api = useApi()
|
||||
|
||||
|
||||
@@ -216,7 +216,7 @@ describe("/admin/tax-rates", () => {
|
||||
)
|
||||
})
|
||||
|
||||
test.only("fails with 404 on unknown rate", async () => {
|
||||
test("fails with 404 on unknown rate", async () => {
|
||||
await adminSeeder(dbConnection)
|
||||
const { tax_rates } = await createTaxRates(dbConnection, 1, 1, 200)
|
||||
const [rate] = tax_rates
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import CustomerController from "../../../../controllers/customers"
|
||||
|
||||
/**
|
||||
* @oas [get] /customer-groups/{id}/customers
|
||||
* operationId: "GetCustomerGroupsGroupCustomers"
|
||||
* summary: "List Customers"
|
||||
* description: "Retrieves a list of Customers."
|
||||
* x-authenticated: true
|
||||
* tags:
|
||||
* - Customer
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* customer:
|
||||
* $ref: "#/components/schemas/customer"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const { id } = req.params
|
||||
|
||||
req.query.groups = [id]
|
||||
|
||||
const result = await CustomerController.listAndCount(
|
||||
req.scope,
|
||||
req.query,
|
||||
req.body
|
||||
)
|
||||
|
||||
res.json(result)
|
||||
}
|
||||
@@ -24,6 +24,12 @@ export default (app) => {
|
||||
"/:id",
|
||||
middlewares.wrap(require("./delete-customer-group").default)
|
||||
)
|
||||
|
||||
route.get(
|
||||
"/:id/customers",
|
||||
middlewares.wrap(require("./get-customer-group-customers").default)
|
||||
)
|
||||
|
||||
route.post(
|
||||
"/:id",
|
||||
middlewares.wrap(require("./update-customer-group").default)
|
||||
|
||||
@@ -8,7 +8,11 @@ const route = Router()
|
||||
export default (app) => {
|
||||
app.use("/customers", route)
|
||||
|
||||
route.get("/", middlewares.wrap(require("./list-customers").default))
|
||||
route.get(
|
||||
"/",
|
||||
middlewares.normalizeQuery(),
|
||||
middlewares.wrap(require("./list-customers").default)
|
||||
)
|
||||
route.get("/:id", middlewares.wrap(require("./get-customer").default))
|
||||
|
||||
route.post("/", middlewares.wrap(require("./create-customer").default))
|
||||
|
||||
@@ -36,6 +36,7 @@ export class AdminGetCustomersParams extends AdminListCustomerSelector {
|
||||
@Type(() => Number)
|
||||
limit = 50
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
|
||||
@@ -2,4 +2,28 @@ import { EntityRepository, Repository } from "typeorm"
|
||||
import { Customer } from "../models/customer"
|
||||
|
||||
@EntityRepository(Customer)
|
||||
export class CustomerRepository extends Repository<Customer> {}
|
||||
export class CustomerRepository extends Repository<Customer> {
|
||||
async listAndCount(query): Promise<[Customer[], number]> {
|
||||
const groups = query?.where?.groups
|
||||
delete query?.where?.groups
|
||||
|
||||
let qb = this.createQueryBuilder("customer")
|
||||
.where(query.where)
|
||||
.skip(query.skip)
|
||||
.take(query.take)
|
||||
|
||||
if (groups) {
|
||||
qb = qb
|
||||
.leftJoinAndSelect("customer.groups", "group")
|
||||
.andWhere(`group.id IN (:...ids)`, { ids: groups.value })
|
||||
}
|
||||
|
||||
if (query.relations?.length) {
|
||||
query.relations.forEach((rel) => {
|
||||
qb = qb.leftJoinAndSelect(`customer.${rel}`, rel)
|
||||
})
|
||||
}
|
||||
|
||||
return await qb.getManyAndCount()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +199,6 @@ class CustomerService extends BaseService {
|
||||
|
||||
query.where = (qb) => {
|
||||
qb.where(where)
|
||||
|
||||
qb.andWhere(
|
||||
new Brackets((qb) => {
|
||||
qb.where({ email: ILike(`%${q}%`) })
|
||||
@@ -210,8 +209,7 @@ class CustomerService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
const [customers, count] = await customerRepo.findAndCount(query)
|
||||
return [customers, count]
|
||||
return await customerRepo.listAndCount(query)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,4 +4,8 @@ export class AdminListCustomerSelector {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
q?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsString({ each: true })
|
||||
groups?: string[]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user