import { Injectable, NotFoundException, ConflictException } from '@nestjs/common'; import { EntityManager, RequiredEntityData } from '@mikro-orm/postgresql'; import { Delivery } from '../entities/delivery.entity'; import { DeliveryRepository } from '../repositories/delivery.repository'; import { CreateDeliveryDto } from '../dto/create-delivery.dto'; import { UpdateDeliveryDto } from '../dto/update-delivery.dto'; import { ShopRepository } from '../../shops/repositories/rest.repository'; import { DeliveryMethodEnum } from '../interface/delivery'; import { DeliveryMessage } from 'src/common/enums/message.enum'; @Injectable() export class DeliveryService { constructor( private readonly deliveryRepository: DeliveryRepository, private readonly shopRepository: ShopRepository, private readonly em: EntityManager, ) { } async create(shopId: string, createDto: CreateDeliveryDto): Promise { const shop = await this.shopRepository.findOne({ id: shopId }); if (!shop) { throw new NotFoundException(DeliveryMessage.SHOP_NOT_FOUND); } // Check if the delivery method with the same name already exists for this shop const existing = await this.deliveryRepository.findOne({ shop: { id: shopId }, method: createDto.method, }); if (existing) { throw new ConflictException('این روش ارسال قبلاً برای این رستوران ثبت شده است.'); } const data: RequiredEntityData = { shop, method: createDto.method, deliveryFee: createDto.deliveryFee, minOrderPrice: createDto.minOrderPrice, description: createDto.description, enabled: createDto.enabled ?? true, order: createDto.order ?? 0, deliveryFeeType: createDto.deliveryFeeType, perKilometerFee: createDto.perKilometerFee ?? null, distanceBasedMinCost: createDto.distanceBasedMinCost ?? null, }; const delivery = this.deliveryRepository.create(data); await this.em.persistAndFlush(delivery); return delivery; } async findAllForRestaurantId(shopId: string): Promise { return this.deliveryRepository.find({ shop: { id: shopId } }, { orderBy: { order: 'asc' } }); } async findOrFail(shopId: string, deliveryId: string): Promise { const delivery = await this.deliveryRepository.findOne({ id: deliveryId, shop: { id: shopId }, }); if (!delivery) { throw new NotFoundException(DeliveryMessage.DELIVERY_METHOD_NOT_FOUND); } return delivery; } async update(shopId: string, deliveryId: string, updateDto: UpdateDeliveryDto): Promise { const delivery = await this.deliveryRepository.findOne({ shop: { id: shopId }, id: deliveryId, }); if (!delivery) { throw new NotFoundException(DeliveryMessage.DELIVERY_METHOD_NOT_FOUND); } // If method is being updated, check for conflicts if (updateDto.method !== undefined && updateDto.method !== delivery.method) { const existing = await this.deliveryRepository.findOne({ shop: { id: shopId }, method: updateDto.method, id: { $ne: deliveryId }, }); if (existing) { throw new ConflictException('این روش ارسال قبلاً برای این رستوران ثبت شده است.'); } } this.em.assign(delivery, updateDto); await this.em.persistAndFlush(delivery); return delivery; } async remove(shopId: string, deliveryId: string): Promise { const delivery = await this.deliveryRepository.findOne({ shop: { id: shopId }, id: deliveryId, }); if (!delivery) { throw new NotFoundException(DeliveryMessage.DELIVERY_METHOD_NOT_FOUND); } await this.em.removeAndFlush(delivery); } findAll(): DeliveryMethodEnum[] { return Object.values(DeliveryMethodEnum); } }