Files
dkala-api/src/modules/delivery/providers/delivery.service.ts
T
2026-02-10 10:15:35 +03:30

116 lines
3.8 KiB
TypeScript

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<Delivery> {
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<Delivery> = {
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<Delivery[]> {
return this.deliveryRepository.find({ shop: { id: shopId } }, { orderBy: { order: 'asc' } });
}
async findOrFail(shopId: string, deliveryId: string): Promise<Delivery> {
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<Delivery> {
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<void> {
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);
}
}