@@ -1,4 +1,5 @@
|
||||
import { Injectable, NotFoundException, BadRequestException, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { EntityManager } from '@mikro-orm/postgresql';
|
||||
import { Order } from '../entities/order.entity';
|
||||
import { OrderItem } from '../entities/order-item.entity';
|
||||
@@ -8,6 +9,7 @@ import { UserRestaurant } from '../../users/entities/user-restuarant.entity';
|
||||
import { Restaurant } from '../../restaurants/entities/restaurant.entity';
|
||||
import { Food } from '../../foods/entities/food.entity';
|
||||
import { CartService } from '../../cart/providers/cart.service';
|
||||
import { CartValidationService } from '../../cart/providers/cart-validation.service';
|
||||
import { OrderStatus, OrderUserAddress, OrderCarAddress } from '../interface/order.interface';
|
||||
import { PaymentMethodEnum, PaymentStatusEnum } from '../../payments/interface/payment';
|
||||
import { Cart } from '../../cart/interfaces/cart.interface';
|
||||
@@ -36,6 +38,7 @@ import { CashShiftsService } from './cash-shifts.service';
|
||||
import { WalletTransaction } from 'src/modules/users/entities/wallet-transaction.entity';
|
||||
import { WalletTransactionReason, WalletTransactionType } from 'src/modules/users/interface/wallet';
|
||||
import { OrderMessage, PaymentMessage } from 'src/common/enums/message.enum';
|
||||
import { SmsQueueService } from 'src/modules/notifications/services/sms-queue.service';
|
||||
type OrderItemData = { food: Food; quantity: number; unitPrice: number; discount: number };
|
||||
|
||||
type ValidatedCartForOrder = {
|
||||
@@ -65,11 +68,14 @@ export class OrdersService {
|
||||
constructor(
|
||||
private readonly em: EntityManager,
|
||||
private readonly cartService: CartService,
|
||||
private readonly cartValidationService: CartValidationService,
|
||||
private readonly orderRepository: OrderRepository,
|
||||
private readonly paymentsService: PaymentsService,
|
||||
private readonly inventoryService: InventoryService,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
private readonly cashShiftsService: CashShiftsService,
|
||||
private readonly smsQueueService: SmsQueueService,
|
||||
private readonly configService: ConfigService,
|
||||
) { }
|
||||
|
||||
async checkout(userId: string, restaurantId: string) {
|
||||
@@ -180,6 +186,14 @@ export class OrdersService {
|
||||
? await this.resolveUserAddressForOrder(user!, dto.addressId!)
|
||||
: null;
|
||||
|
||||
if (userAddress) {
|
||||
await this.cartValidationService.assertAddressInsideServiceArea(
|
||||
restaurantId,
|
||||
userAddress.latitude,
|
||||
userAddress.longitude,
|
||||
);
|
||||
}
|
||||
|
||||
const orderItemsData = await this.buildOrderItemsDataFromDto(dto.items, restaurantId);
|
||||
|
||||
// Validate admin discount against item totals (not persisted — DB recomputes order money fields)
|
||||
@@ -434,6 +448,14 @@ export class OrdersService {
|
||||
this.assertMeetsMinOrderForDelivery(cart, delivery);
|
||||
this.assertDeliveryMethodRequirements(cart, delivery);
|
||||
|
||||
if (delivery.method === DeliveryMethodEnum.DeliveryCourier && cart.userAddress) {
|
||||
await this.cartValidationService.assertAddressInsideServiceArea(
|
||||
restaurantId,
|
||||
cart.userAddress.latitude,
|
||||
cart.userAddress.longitude,
|
||||
);
|
||||
}
|
||||
|
||||
const paymentMethod = await this.getPaymentMethodOrFail(cart.paymentMethodId!, restaurantId);
|
||||
this.assertPaymentMethodEnabled(paymentMethod);
|
||||
this.assertCreditCardPaymentDetails(paymentMethod, cart.paymentDesc, cart.attachments);
|
||||
@@ -788,6 +810,38 @@ export class OrdersService {
|
||||
return order;
|
||||
}
|
||||
|
||||
async sendPleaseComeSms(orderId: string, restId: string): Promise<void> {
|
||||
const order = await this.getOrderOrFail(orderId, restId);
|
||||
const user = order.user;
|
||||
|
||||
if (!user) {
|
||||
throw new BadRequestException(OrderMessage.PLEASE_COME_USER_MISSING);
|
||||
}
|
||||
|
||||
if (!user.phone) {
|
||||
throw new BadRequestException(OrderMessage.PLEASE_COME_PHONE_MISSING);
|
||||
}
|
||||
|
||||
const templateId = this.configService.get<string>('SMS_PATTERN_PLEASE_COME');
|
||||
if (!templateId) {
|
||||
throw new BadRequestException(OrderMessage.PLEASE_COME_SMS_PATTERN_MISSING);
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
`Queueing please-come SMS for order ${orderId} to user ${user.id} (${user.phone})`,
|
||||
);
|
||||
|
||||
await this.smsQueueService.enqueue({
|
||||
phone: user.phone,
|
||||
templateId,
|
||||
restaurantId: restId,
|
||||
quantity: 1,
|
||||
params: {
|
||||
name: user.firstName ?? '',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private assertCartHasItems(cart: Cart) {
|
||||
if (!cart.items || cart.items.length === 0) {
|
||||
throw new BadRequestException(OrderMessage.CART_EMPTY);
|
||||
|
||||
Reference in New Issue
Block a user