import { UploadedFileTypes } from '@/common/enums/enums' import { ResponseMapper } from '@/common/response/response-mapper' 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 { PosCacheInvalidationService } from '../cache/pos-cache-invalidation.service' import { CreateOwnedGoodsDto } from './dto/create-owned-goods.dto' import { UpdateOwnedGoodsDto } from './dto/update-owned-goods.dto' @Injectable() export class OwnedGoodsService { constructor( private readonly prisma: PrismaService, private readonly uploaderService: UploaderService, private readonly posCacheInvalidationService: PosCacheInvalidationService, ) {} private readonly where = (business_activity_id: string): GoodWhereInput => ({ is_default_guild_good: false, business_activity_id, }) private readonly select: 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, }, }, } async findAll(business_activity_id: string) { const items = await this.prisma.good.findMany({ where: this.where(business_activity_id), select: this.select, }) return ResponseMapper.list(items) } async findOne(business_activity_id: string, id: string) { const item = await this.prisma.good.findUnique({ where: { ...(this.where(business_activity_id) as any), id }, select: this.select, }) return ResponseMapper.single(item) } async create( guild_id: string, business_activity_id: string, data: CreateOwnedGoodsDto, 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, }, }, business_activity: { connect: { id: business_activity_id, }, }, }, select: this.select, }) }) await this.posCacheInvalidationService.invalidatePosGoodsList( guild_id, business_activity_id, ) return ResponseMapper.create(good) } async update( guild_id: string, business_activity_id: string, id: string, data: UpdateOwnedGoodsDto, 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 = undefined as string | undefined 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: { ...(this.where(business_activity_id) as any), id }, data: { ...rest, is_default_guild_good: false, image_url, sku: { connect: { id: sku_id, }, }, measure_unit: { connect: { id: measure_unit_id, }, }, category: { connect: { id: category_id, }, }, business_activity: { connect: { id: business_activity_id, }, }, }, select: this.select, }) }) await this.posCacheInvalidationService.invalidatePosGoodsList( guild_id, business_activity_id, ) return ResponseMapper.create(good) } }