import { In } from "typeorm"; import Item from "../../domain/entities/item"; import User from "../../domain/entities/user"; import ItemRepository from "../../domain/repositories/item.repository"; import { CreateItemAttr, DeleteItemAttr, FindItemAttr, ListItemAttr, UpdateItemAttr } from "../../domain/types/item.type"; import { ItemRecord } from "../db/records/item.record"; export default class ItemRepositoryImpl implements ItemRepository { async find(payload: FindItemAttr): Promise { const record = await ItemRecord.createQueryBuilder() .where({ id: payload.id, available: true }) .getOne(); return record?.toEntity(); } async list(payload: ListItemAttr, user?: User): Promise<{ count: number, items: Item[] }> { const filtered = ItemRecord.createQueryBuilder() .leftJoinAndSelect("ItemRecord.stock", "StockRecord") .where({ ...(payload.itemType && { type: In(payload.itemType) }), ...(typeof payload.visible !== "undefined" && { visible: payload.visible }), available: true }); const records = await filtered .take(Number(process.env.PER_PAGE)) .offset(Number(process.env.PER_PAGE) * ((payload?.page || 1) - 1)) .orderBy("ItemRecord.price", "ASC") .getMany(); const count = await filtered .getCount(); const items: Item[] = []; for await (const record of records) { const item = await record.toAsyncEntity(user); items.push(item); } return { count, items }; } async create(payload: CreateItemAttr): Promise { const record = await ItemRecord.createQueryBuilder() .insert() .values({ ...(payload.id && { id: payload.id }), name: payload.name, description: payload.description, type: payload.type, image: payload.image, link: payload.link, price: payload.price, dueDate: payload.dueDate, onClickRedirect: payload.onClickRedirect, visible: payload.visible }) .execute(); return this.find({ id: record.identifiers[0].id }); } async update(payload: UpdateItemAttr): Promise { const record = await ItemRecord.createQueryBuilder() .update() .where({ id: payload.id }) .set({ name: payload.data.name, description: payload.data.description, type: payload.data.type, image: payload.data.image, link: payload.data.link, price: payload.data.price, dueDate: payload.data.dueDate, onClickRedirect: payload.data.onClickRedirect, visible: payload.data.visible }) .execute(); if (record.affected === 0) return; return await this.find({ id: payload.id }); } async delete(payload: DeleteItemAttr): Promise { const record = await ItemRecord.createQueryBuilder() .update() .where({ id: payload.id }) .set({ available: false }) .execute(); return record.affected === 1; } }