fix: introduce listAndCount for gift cards to enable pagination (#1754)
**What** Proper `listAndCount` implementation for gift cards.
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { Type } from "class-transformer"
|
||||
import { IsInt, IsOptional, IsString } from "class-validator"
|
||||
import { pickBy } from "lodash"
|
||||
import { defaultAdminGiftCardFields, defaultAdminGiftCardRelations } from "."
|
||||
import { GiftCardService } from "../../../../services"
|
||||
import { validator } from "../../../../utils/validator"
|
||||
|
||||
@@ -30,14 +29,14 @@ export default async (req, res) => {
|
||||
|
||||
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"),
|
||||
req.listConfig
|
||||
)
|
||||
|
||||
res.status(200).json({
|
||||
gift_cards: giftCards,
|
||||
count: giftCards.length,
|
||||
count,
|
||||
offset: validated.offset,
|
||||
limit: validated.limit,
|
||||
})
|
||||
|
||||
@@ -15,12 +15,18 @@ export class GiftCardRepository extends Repository<GiftCard> {
|
||||
idsOrOptionsWithoutRelations:
|
||||
| Omit<FindManyOptions<GiftCard>, "relations">
|
||||
| string[] = {}
|
||||
): Promise<GiftCard[]> {
|
||||
let entities
|
||||
): Promise<[GiftCard[], number]> {
|
||||
let entities: GiftCard[] = []
|
||||
let count = 0
|
||||
if (Array.isArray(idsOrOptionsWithoutRelations)) {
|
||||
entities = await this.findByIds(idsOrOptionsWithoutRelations)
|
||||
count = idsOrOptionsWithoutRelations.length
|
||||
} else {
|
||||
entities = await this.find(idsOrOptionsWithoutRelations)
|
||||
const [results, resultCount] = await this.findAndCount(
|
||||
idsOrOptionsWithoutRelations
|
||||
)
|
||||
entities = results
|
||||
count = resultCount
|
||||
}
|
||||
const entitiesIds = entities.map(({ id }) => id)
|
||||
|
||||
@@ -45,15 +51,19 @@ export class GiftCardRepository extends Repository<GiftCard> {
|
||||
const entitiesAndRelations = entitiesIdsWithRelations.concat(entities)
|
||||
|
||||
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(
|
||||
q: string,
|
||||
where: Partial<Writable<QuerySelector<GiftCard>>>,
|
||||
rels: (keyof GiftCard | string)[]
|
||||
): Promise<GiftCard[]> {
|
||||
const raw = await this.createQueryBuilder("gift_card")
|
||||
rels: (keyof GiftCard | string)[],
|
||||
shouldCount = false
|
||||
): Promise<[GiftCard[], number]> {
|
||||
const qb = this.createQueryBuilder("gift_card")
|
||||
.leftJoinAndSelect("gift_card.order", "order")
|
||||
.select(["gift_card.id"])
|
||||
.where(where)
|
||||
@@ -64,12 +74,39 @@ export class GiftCardRepository extends Repository<GiftCard> {
|
||||
.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,
|
||||
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(
|
||||
@@ -81,9 +118,12 @@ export class GiftCardRepository extends Repository<GiftCard> {
|
||||
const where = query.where
|
||||
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(
|
||||
@@ -93,7 +133,7 @@ export class GiftCardRepository extends Repository<GiftCard> {
|
||||
// Limit 1
|
||||
optionsWithoutRelations.take = 1
|
||||
|
||||
const result = await this.findWithRelations(
|
||||
const [result] = await this.findWithRelations(
|
||||
relations,
|
||||
optionsWithoutRelations
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import randomize from "randomatic"
|
||||
import { Brackets, EntityManager, FindOneOptions } from "typeorm"
|
||||
import { EntityManager } from "typeorm"
|
||||
import { EventBusService } from "."
|
||||
import { TransactionBaseService } from "../interfaces"
|
||||
import { GiftCard } from "../models"
|
||||
@@ -76,6 +76,36 @@ class GiftCardService extends TransactionBaseService<GiftCardService> {
|
||||
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 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) => {
|
||||
const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_)
|
||||
|
||||
let q
|
||||
if ("q" in selector) {
|
||||
let q: string | undefined
|
||||
if (typeof selector.q !== "undefined") {
|
||||
q = selector.q
|
||||
delete selector.q
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user