fix: introduce listAndCount for gift cards to enable pagination (#1754)
**What** Proper `listAndCount` implementation for gift cards.
This commit is contained in:
1 parent
9b5c2e8c1f
commit
9a14b84e58
3 files changed
+87
-18
No files matched your search
@@ -1,7 +1,6 @@
|
|||||||
import { Type } from "class-transformer"
|
import { Type } from "class-transformer"
|
||||||
import { IsInt, IsOptional, IsString } from "class-validator"
|
import { IsInt, IsOptional, IsString } from "class-validator"
|
||||||
import { pickBy } from "lodash"
|
import { pickBy } from "lodash"
|
||||||
import { defaultAdminGiftCardFields, defaultAdminGiftCardRelations } from "."
|
|
||||||
import { GiftCardService } from "../../../../services"
|
import { GiftCardService } from "../../../../services"
|
||||||
import { validator } from "../../../../utils/validator"
|
import { validator } from "../../../../utils/validator"
|
||||||
|
|
||||||
@@ -30,14 +29,14 @@ export default async (req, res) => {
|
|||||||
|
|
||||||
const giftCardService: GiftCardService = req.scope.resolve("giftCardService")
|
const giftCardService: GiftCardService = req.scope.resolve("giftCardService")
|
||||||
|
|
||||||
const giftCards = await giftCardService.list(
|
const [giftCards, count] = await giftCardService.listAndCount(
|
||||||
pickBy(req.filterableFields, (val) => typeof val !== "undefined"),
|
pickBy(req.filterableFields, (val) => typeof val !== "undefined"),
|
||||||
req.listConfig
|
req.listConfig
|
||||||
)
|
)
|
||||||
|
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
gift_cards: giftCards,
|
gift_cards: giftCards,
|
||||||
count: giftCards.length,
|
count,
|
||||||
offset: validated.offset,
|
offset: validated.offset,
|
||||||
limit: validated.limit,
|
limit: validated.limit,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -15,12 +15,18 @@ export class GiftCardRepository extends Repository<GiftCard> {
|
|||||||
idsOrOptionsWithoutRelations:
|
idsOrOptionsWithoutRelations:
|
||||||
| Omit<FindManyOptions<GiftCard>, "relations">
|
| Omit<FindManyOptions<GiftCard>, "relations">
|
||||||
| string[] = {}
|
| string[] = {}
|
||||||
): Promise<GiftCard[]> {
|
): Promise<[GiftCard[], number]> {
|
||||||
let entities
|
let entities: GiftCard[] = []
|
||||||
|
let count = 0
|
||||||
if (Array.isArray(idsOrOptionsWithoutRelations)) {
|
if (Array.isArray(idsOrOptionsWithoutRelations)) {
|
||||||
entities = await this.findByIds(idsOrOptionsWithoutRelations)
|
entities = await this.findByIds(idsOrOptionsWithoutRelations)
|
||||||
|
count = idsOrOptionsWithoutRelations.length
|
||||||
} else {
|
} else {
|
||||||
entities = await this.find(idsOrOptionsWithoutRelations)
|
const [results, resultCount] = await this.findAndCount(
|
||||||
|
idsOrOptionsWithoutRelations
|
||||||
|
)
|
||||||
|
entities = results
|
||||||
|
count = resultCount
|
||||||
}
|
}
|
||||||
const entitiesIds = entities.map(({ id }) => id)
|
const entitiesIds = entities.map(({ id }) => id)
|
||||||
|
|
||||||
@@ -45,15 +51,19 @@ export class GiftCardRepository extends Repository<GiftCard> {
|
|||||||
const entitiesAndRelations = entitiesIdsWithRelations.concat(entities)
|
const entitiesAndRelations = entitiesIdsWithRelations.concat(entities)
|
||||||
|
|
||||||
const entitiesAndRelationsById = groupBy(entitiesAndRelations, "id")
|
const entitiesAndRelationsById = groupBy(entitiesAndRelations, "id")
|
||||||
return Object.values(entitiesAndRelationsById).map((v) => merge({}, ...v))
|
return [
|
||||||
|
Object.values(entitiesAndRelationsById).map((v) => merge({}, ...v)),
|
||||||
|
count,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async queryGiftCards(
|
protected async queryGiftCards(
|
||||||
q: string,
|
q: string,
|
||||||
where: Partial<Writable<QuerySelector<GiftCard>>>,
|
where: Partial<Writable<QuerySelector<GiftCard>>>,
|
||||||
rels: (keyof GiftCard | string)[]
|
rels: (keyof GiftCard | string)[],
|
||||||
): Promise<GiftCard[]> {
|
shouldCount = false
|
||||||
const raw = await this.createQueryBuilder("gift_card")
|
): Promise<[GiftCard[], number]> {
|
||||||
|
const qb = this.createQueryBuilder("gift_card")
|
||||||
.leftJoinAndSelect("gift_card.order", "order")
|
.leftJoinAndSelect("gift_card.order", "order")
|
||||||
.select(["gift_card.id"])
|
.select(["gift_card.id"])
|
||||||
.where(where)
|
.where(where)
|
||||||
@@ -64,12 +74,39 @@ export class GiftCardRepository extends Repository<GiftCard> {
|
|||||||
.orWhere(`display_id::varchar(255) ILIKE :dId`, { dId: `${q}` })
|
.orWhere(`display_id::varchar(255) ILIKE :dId`, { dId: `${q}` })
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.getMany()
|
|
||||||
|
|
||||||
return this.findWithRelations(
|
let raw: GiftCard[] = []
|
||||||
|
let count = 0
|
||||||
|
if (shouldCount) {
|
||||||
|
const [results, resultCount] = await qb.getManyAndCount()
|
||||||
|
raw = results
|
||||||
|
count = resultCount
|
||||||
|
} else {
|
||||||
|
raw = await qb.getMany()
|
||||||
|
}
|
||||||
|
|
||||||
|
const [results] = await this.findWithRelations(
|
||||||
rels,
|
rels,
|
||||||
raw.map((i) => i.id)
|
raw.map((i) => i.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return [results, count]
|
||||||
|
}
|
||||||
|
|
||||||
|
public async listGiftCardsAndCount(
|
||||||
|
inputQuery: ExtendedFindConfig<GiftCard, QuerySelector<GiftCard>>,
|
||||||
|
rels: (keyof GiftCard | string)[] = [],
|
||||||
|
q?: string
|
||||||
|
): Promise<[GiftCard[], number]> {
|
||||||
|
const query = { ...inputQuery }
|
||||||
|
|
||||||
|
if (q) {
|
||||||
|
const where = query.where
|
||||||
|
delete where.id
|
||||||
|
|
||||||
|
return await this.queryGiftCards(q, where, rels, true)
|
||||||
|
}
|
||||||
|
return await this.findWithRelations(rels, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async listGiftCards(
|
public async listGiftCards(
|
||||||
@@ -81,9 +118,12 @@ export class GiftCardRepository extends Repository<GiftCard> {
|
|||||||
const where = query.where
|
const where = query.where
|
||||||
delete where.id
|
delete where.id
|
||||||
|
|
||||||
return await this.queryGiftCards(q, where, rels)
|
const [result] = await this.queryGiftCards(q, where, rels)
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
return this.findWithRelations(rels, query)
|
|
||||||
|
const [results] = await this.findWithRelations(rels, query)
|
||||||
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findOneWithRelations(
|
public async findOneWithRelations(
|
||||||
@@ -93,7 +133,7 @@ export class GiftCardRepository extends Repository<GiftCard> {
|
|||||||
// Limit 1
|
// Limit 1
|
||||||
optionsWithoutRelations.take = 1
|
optionsWithoutRelations.take = 1
|
||||||
|
|
||||||
const result = await this.findWithRelations(
|
const [result] = await this.findWithRelations(
|
||||||
relations,
|
relations,
|
||||||
optionsWithoutRelations
|
optionsWithoutRelations
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { MedusaError } from "medusa-core-utils"
|
||||||
import randomize from "randomatic"
|
import randomize from "randomatic"
|
||||||
import { Brackets, EntityManager, FindOneOptions } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { EventBusService } from "."
|
import { EventBusService } from "."
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { GiftCard } from "../models"
|
import { GiftCard } from "../models"
|
||||||
@@ -76,6 +76,36 @@ class GiftCardService extends TransactionBaseService<GiftCardService> {
|
|||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param selector - the query object for find
|
||||||
|
* @param config - the configuration used to find the objects. contains relations, skip, and take.
|
||||||
|
* @return the result of the find operation
|
||||||
|
*/
|
||||||
|
async listAndCount(
|
||||||
|
selector: QuerySelector<GiftCard> = {},
|
||||||
|
config: FindConfig<GiftCard> = { relations: [], skip: 0, take: 10 }
|
||||||
|
): Promise<[GiftCard[], number]> {
|
||||||
|
return await this.atomicPhase_(async (manager) => {
|
||||||
|
const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_)
|
||||||
|
|
||||||
|
let q: string | undefined
|
||||||
|
if (typeof selector.q !== "undefined") {
|
||||||
|
q = selector.q
|
||||||
|
delete selector.q
|
||||||
|
}
|
||||||
|
|
||||||
|
const query: ExtendedFindConfig<
|
||||||
|
GiftCard,
|
||||||
|
QuerySelector<GiftCard>
|
||||||
|
> = buildQuery<QuerySelector<GiftCard>, GiftCard>(selector, config)
|
||||||
|
|
||||||
|
const rels = query.relations
|
||||||
|
delete query.relations
|
||||||
|
|
||||||
|
return await giftCardRepo.listGiftCardsAndCount(query, rels, q)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param selector - the query object for find
|
* @param selector - the query object for find
|
||||||
* @param config - the configuration used to find the objects. contains relations, skip, and take.
|
* @param config - the configuration used to find the objects. contains relations, skip, and take.
|
||||||
@@ -88,8 +118,8 @@ class GiftCardService extends TransactionBaseService<GiftCardService> {
|
|||||||
return await this.atomicPhase_(async (manager) => {
|
return await this.atomicPhase_(async (manager) => {
|
||||||
const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_)
|
const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_)
|
||||||
|
|
||||||
let q
|
let q: string | undefined
|
||||||
if ("q" in selector) {
|
if (typeof selector.q !== "undefined") {
|
||||||
q = selector.q
|
q = selector.q
|
||||||
delete selector.q
|
delete selector.q
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user