import { UploadedFileTypes } from '@/common/enums/enums' import { GoodSelect, GoodWhereInput } from '@/generated/prisma/models' import { UploaderService } from '@/modules/uploader/uploader.service' import { PrismaService } from '@/prisma/prisma.service' import { Injectable } from '@nestjs/common' import { ResponseMapper } from 'common/response/response-mapper' import { CreateGuildGoodDto, UpdateGuildGoodDto } from './dto/create-good.dto' @Injectable() export class GoodsService { constructor( private prisma: PrismaService, private readonly uploaderService: UploaderService, ) {} private readonly defaultSelect: GoodSelect = { id: true, name: true, pricing_model: true, image_url: true, description: true, sku: { select: { id: true, name: true, code: true, }, }, measure_unit: { select: { id: true, name: true, code: true, }, }, category: { select: { id: true, name: true, }, }, } private readonly defaultWhere = (guild_id: string): GoodWhereInput => ({ is_default_guild_good: true, category: { guild_id, }, }) async findAll(guildId: string) { const [goods, total] = await this.prisma.$transaction([ this.prisma.good.findMany({ where: this.defaultWhere(guildId), select: this.defaultSelect, }), this.prisma.good.count(), ]) return ResponseMapper.paginate(goods, { total, }) } async findOne(guild_id: string, id: string) { const good = await this.prisma.good.findUnique({ where: { id, ...(this.defaultWhere(guild_id) as any), }, select: this.defaultSelect, }) return ResponseMapper.single(good) } async create(data: CreateGuildGoodDto, file: Express.Multer.File) { const { category_id, measure_unit_id, sku_id, ...rest } = data const good = await this.prisma.$transaction(async tx => { let image_url = '' if (file) { const uploadedUrl = await this.uploaderService.uploadFile( file, UploadedFileTypes.GOOD, ) image_url = uploadedUrl || '' } return await tx.good.create({ data: { ...rest, is_default_guild_good: true, image_url, sku: { connect: { id: sku_id, }, }, measure_unit: { connect: { id: measure_unit_id, }, }, category: { connect: { id: category_id, }, }, }, select: this.defaultSelect, }) }) return ResponseMapper.create(good) } async update(id: string, data: UpdateGuildGoodDto, file: Express.Multer.File) { const { category_id, measure_unit_id, sku_id, ...rest } = data const good = await this.prisma.$transaction(async tx => { let image_url = '' if (file) { const uploadedUrl = await this.uploaderService.uploadFile( file, UploadedFileTypes.GOOD, ) image_url = uploadedUrl || '' } const prevImage = await tx.good.findUnique({ where: { id }, select: { image_url: true }, }) if (image_url && prevImage?.image_url) { this.uploaderService.deleteFile(prevImage.image_url, UploadedFileTypes.GOOD) } return await tx.good.update({ where: { id }, data: { ...rest, is_default_guild_good: true, image_url, sku: { connect: { id: sku_id, }, }, measure_unit: { connect: { id: measure_unit_id, }, }, category: { connect: { id: category_id, }, }, }, select: this.defaultSelect, }) }) return ResponseMapper.create(good) } }