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:
Philip Korsholm
2022-03-10 13:05:46 +01:00
committed by GitHub
parent 8e7de6dd36
commit dacc9c6c4b
10 changed files with 153 additions and 6 deletions
@@ -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)
+25 -1
View File
@@ -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()
}
}
+1 -3
View File
@@ -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
View File
@@ -4,4 +4,8 @@ export class AdminListCustomerSelector {
@IsString()
@IsOptional()
q?: string
@IsOptional()
@IsString({ each: true })
groups?: string[]
}