fix(medusa): support searching for price lists (#1407)

This commit is contained in:
Zakaria El Asri
2022-05-08 18:45:18 +02:00
committed by GitHub
parent e7cb76ab6e
commit f71b9b3a87
6 changed files with 268 additions and 44 deletions
+92 -2
View File
@@ -1,5 +1,95 @@
import { EntityRepository, Repository } from "typeorm"
import { groupBy, map } from "lodash"
import {
Brackets,
EntityRepository,
FindManyOptions, Repository
} from "typeorm"
import { PriceList } from "../models/price-list"
import { CustomFindOptions } from "../types/common"
type PriceListFindOptions = CustomFindOptions<PriceList, 'status' | 'type'>
@EntityRepository(PriceList)
export class PriceListRepository extends Repository<PriceList> {}
export class PriceListRepository extends Repository<PriceList> {
public async getFreeTextSearchResultsAndCount(
q: string,
options: PriceListFindOptions = { where: {} },
relations: (keyof PriceList)[] = []
): Promise<[PriceList[], number]> {
options.where = options.where ?? {}
let qb = this.createQueryBuilder("price_list")
.leftJoinAndSelect("price_list.customer_groups", "customer_group")
.select(["price_list.id"])
.where(options.where)
.andWhere(
new Brackets((qb) => {
qb.where(`price_list.description ILIKE :q`, { q: `%${q}%` })
.orWhere(`price_list.name ILIKE :q`, { q: `%${q}%` })
.orWhere(`customer_group.name ILIKE :q`, { q: `%${q}%` })
})
)
.skip(options.skip)
.take(options.take)
const [results, count] = await qb.getManyAndCount()
const price_lists = await this.findWithRelations(
relations,
results.map((r) => r.id)
)
return [price_lists, count]
}
public async findWithRelations(
relations: (keyof PriceList)[] = [],
idsOrOptionsWithoutRelations:
| Omit<FindManyOptions<PriceList>, "relations">
| string[] = {}
): Promise<PriceList[]> {
let entities
if (Array.isArray(idsOrOptionsWithoutRelations)) {
entities = await this.findByIds(idsOrOptionsWithoutRelations)
} else {
entities = await this.find(idsOrOptionsWithoutRelations)
}
const groupedRelations: Record<string, string[]> = {}
for (const relation of relations) {
const [topLevel] = relation.split(".")
if (groupedRelations[topLevel]) {
groupedRelations[topLevel].push(relation)
} else {
groupedRelations[topLevel] = [relation]
}
}
const entitiesIds = entities.map(({ id }) => id)
const entitiesIdsWithRelations = await Promise.all(
Object.values(groupedRelations).map((relations: string[]) => {
return this.findByIds(entitiesIds, {
select: ["id"],
relations: relations as string[],
})
})
).then(entitiesIdsWithRelations => entitiesIdsWithRelations.flat())
const entitiesAndRelations = entitiesIdsWithRelations.concat(entities)
const entitiesAndRelationsById = groupBy(entitiesAndRelations, "id")
return map(entitiesAndRelationsById, (entityAndRelations) =>
this.merge(this.create(), ...entityAndRelations)
)
}
public async findOneWithRelations(
relations: (keyof PriceList)[] = [],
options: Omit<FindManyOptions<PriceList>, "relations"> = {}
): Promise<PriceList | undefined> {
options.take = 1
return (await this.findWithRelations(
relations,
options
))?.pop()
}
}
+11 -2
View File
@@ -260,9 +260,18 @@ class PriceListService extends BaseService {
config: FindConfig<PriceList> = { skip: 0, take: 20 }
): Promise<[PriceList[], number]> {
const priceListRepo = this.manager_.getCustomRepository(this.priceListRepo_)
const q = selector.q
const { relations, ...query } = this.buildQuery_(selector, config)
const query = this.buildQuery_(selector, config)
return await priceListRepo.findAndCount(query)
if (q) {
delete query.where.q
return await priceListRepo.getFreeTextSearchResultsAndCount(
q,
query,
relations
)
}
return await priceListRepo.findAndCount({ ...query, relations })
}
async upsertCustomerGroups_(
+17
View File
@@ -1,6 +1,12 @@
import { Transform, Type } from "class-transformer"
import { IsDate, IsNumber, IsOptional, IsString } from "class-validator"
import "reflect-metadata"
import {
BaseEntity,
FindManyOptions,
FindOperator,
OrderByCondition,
} from "typeorm"
import { transformDate } from "../utils/validators/date-transform"
export type PartialPick<T, K extends keyof T> = {
@@ -25,6 +31,17 @@ export interface FindConfig<Entity> {
order?: Record<string, "ASC" | "DESC">
}
export interface CustomFindOptions<TModel, InKeys extends keyof TModel> {
select?: FindManyOptions<TModel>["select"]
where?: FindManyOptions<TModel>["where"] &
{
[P in InKeys]?: TModel[P][]
}
order?: OrderByCondition
skip?: number
take?: number
}
export type PaginatedResponse = { limit: number; offset: number; count: number }
export type DeleteResponse = {