This commit is contained in:
2025-12-02 23:15:17 +03:30
parent 8298e2fb3e
commit c759a120e7
5 changed files with 36 additions and 47 deletions
+8 -1
View File
@@ -4,12 +4,19 @@ import { CartService } from './providers/cart.service';
import { CartController } from './controllers/cart.controller'; import { CartController } from './controllers/cart.controller';
import { Food } from '../foods/entities/food.entity'; import { Food } from '../foods/entities/food.entity';
import { Restaurant } from '../restaurants/entities/restaurant.entity'; import { Restaurant } from '../restaurants/entities/restaurant.entity';
import { PaymentMethod } from '../payments/entities/payment-method.entity';
import { UserAddress } from '../users/entities/user-address.entity';
import { AuthModule } from '../auth/auth.module'; import { AuthModule } from '../auth/auth.module';
import { JwtModule } from '@nestjs/jwt'; import { JwtModule } from '@nestjs/jwt';
import { UtilsModule } from '../utils/utils.module'; import { UtilsModule } from '../utils/utils.module';
@Module({ @Module({
imports: [MikroOrmModule.forFeature([Food, Restaurant]), AuthModule, JwtModule, UtilsModule], imports: [
MikroOrmModule.forFeature([Food, Restaurant, PaymentMethod, UserAddress]),
AuthModule,
JwtModule,
UtilsModule,
],
controllers: [CartController], controllers: [CartController],
providers: [CartService], providers: [CartService],
exports: [CartService], exports: [CartService],
+14 -30
View File
@@ -10,7 +10,7 @@ import { ApplyCouponDto } from '../dto/apply-coupon.dto';
import { SetAddressDto } from '../dto/set-address.dto'; import { SetAddressDto } from '../dto/set-address.dto';
import { SetPaymentMethodDto } from '../dto/set-payment-method.dto'; import { SetPaymentMethodDto } from '../dto/set-payment-method.dto';
import { UserAddress } from '../../users/entities/user-address.entity'; import { UserAddress } from '../../users/entities/user-address.entity';
import { RestaurantPaymentMethod } from '../../payments/entities/restaurant-payment-method.entity'; import { PaymentMethod } from '../../payments/entities/payment-method.entity';
import { Cart, CartItem, CartCoupon } from '../interfaces/cart.interface'; import { Cart, CartItem, CartCoupon } from '../interfaces/cart.interface';
@Injectable() @Injectable()
@@ -423,35 +423,29 @@ export class CartService {
const cart = await this.findOne(userId, restaurantId); const cart = await this.findOne(userId, restaurantId);
// Find and validate payment method belongs to restaurant // Find and validate payment method belongs to restaurant
const restaurantPaymentMethod = await this.em.findOne( const paymentMethod = await this.em.findOne(
RestaurantPaymentMethod, PaymentMethod,
{ {
id: setPaymentMethodDto.paymentMethodId,
restaurant: { id: restaurantId }, restaurant: { id: restaurantId },
paymentMethod: { id: setPaymentMethodDto.paymentMethodId },
}, },
{ populate: ['restaurant', 'paymentMethod'] }, { populate: ['restaurant'] },
); );
if (!restaurantPaymentMethod) { if (!paymentMethod) {
throw new NotFoundException( throw new NotFoundException(
`Payment method with ID ${setPaymentMethodDto.paymentMethodId} not found for restaurant ${restaurantId}`, `Payment method with ID ${setPaymentMethodDto.paymentMethodId} not found for restaurant ${restaurantId}`,
); );
} }
// Verify payment method is active // Verify payment method is enabled
if (!restaurantPaymentMethod.isActive) { if (!paymentMethod.enabled) {
throw new BadRequestException('Payment method is not active for this restaurant'); throw new BadRequestException('Payment method is not enabled for this restaurant');
}
// Verify the payment method itself is active
if (!restaurantPaymentMethod.paymentMethod.isActive) {
throw new BadRequestException('Payment method is not active');
} }
cart.paymentMethodId = setPaymentMethodDto.paymentMethodId; cart.paymentMethodId = setPaymentMethodDto.paymentMethodId;
// cart.shipmentFee = Number(restaurantPaymentMethod.price) || 0;
// Recalculate cart totals to include delivery fee // Recalculate cart totals
await this.recalculateCartTotals(cart); await this.recalculateCartTotals(cart);
await this.saveCart(cart); await this.saveCart(cart);
@@ -505,22 +499,12 @@ export class CartService {
cart.tax = tax; cart.tax = tax;
// Get shipment fee if payment method is set // Shipment fee is calculated separately via delivery method
let shipmentFee = 0; // For now, it's set to 0. It should be set when a delivery method is selected
// if (cart.paymentMethodId) { cart.shipmentFee = 0;
// const restaurantPaymentMethod = await this.em.findOne(RestaurantPaymentMethod, {
// restaurant: { id: cart.restaurantId },
// paymentMethod: { id: cart.paymentMethodId },
// });
// if (restaurantPaymentMethod) {
// shipmentFee = Number(restaurantPaymentMethod.price) || 0;
// shipmentFee = 1;
// }
// }
cart.shipmentFee = shipmentFee;
// Calculate total: total = subtotal totalDiscount + tax + shipmentFee // Calculate total: total = subtotal totalDiscount + tax + shipmentFee
cart.total = subTotal - cart.totalDiscount + tax + shipmentFee; cart.total = subTotal - cart.totalDiscount + tax + cart.shipmentFee;
cart.totalItems = totalItems; cart.totalItems = totalItems;
cart.updatedAt = new Date().toISOString(); cart.updatedAt = new Date().toISOString();
} }
+3 -3
View File
@@ -5,7 +5,7 @@ import { OrderStatus } from '../interface/order-status';
import { User } from '../../users/entities/user.entity'; import { User } from '../../users/entities/user.entity';
import { Restaurant } from '../../restaurants/entities/restaurant.entity'; import { Restaurant } from '../../restaurants/entities/restaurant.entity';
import { UserAddress } from '../../users/entities/user-address.entity'; import { UserAddress } from '../../users/entities/user-address.entity';
import { RestaurantPaymentMethod } from '../../payments/entities/restaurant-payment-method.entity'; import { PaymentMethod } from '../../payments/entities/payment-method.entity';
import { OrderItem } from './order-item.entity'; import { OrderItem } from './order-item.entity';
@Entity({ tableName: 'orders' }) @Entity({ tableName: 'orders' })
@@ -25,8 +25,8 @@ export class Order extends BaseEntity {
@ManyToOne(() => UserAddress, { nullable: true }) @ManyToOne(() => UserAddress, { nullable: true })
address?: UserAddress; address?: UserAddress;
@ManyToOne(() => RestaurantPaymentMethod, { nullable: true }) @ManyToOne(() => PaymentMethod, { nullable: true })
paymentMethod?: RestaurantPaymentMethod; paymentMethod?: PaymentMethod;
@Property({ type: 'decimal', precision: 10, scale: 0, default: 0 }) @Property({ type: 'decimal', precision: 10, scale: 0, default: 0 })
couponDiscount: number = 0; couponDiscount: number = 0;
+2 -2
View File
@@ -8,7 +8,7 @@ import { User } from '../users/entities/user.entity';
import { Restaurant } from '../restaurants/entities/restaurant.entity'; import { Restaurant } from '../restaurants/entities/restaurant.entity';
import { Food } from '../foods/entities/food.entity'; import { Food } from '../foods/entities/food.entity';
import { UserAddress } from '../users/entities/user-address.entity'; import { UserAddress } from '../users/entities/user-address.entity';
import { RestaurantPaymentMethod } from '../payments/entities/restaurant-payment-method.entity'; import { PaymentMethod } from '../payments/entities/payment-method.entity';
import { CartModule } from '../cart/cart.module'; import { CartModule } from '../cart/cart.module';
import { UtilsModule } from '../utils/utils.module'; import { UtilsModule } from '../utils/utils.module';
import { AuthModule } from '../auth/auth.module'; import { AuthModule } from '../auth/auth.module';
@@ -17,7 +17,7 @@ import { JwtModule } from '@nestjs/jwt';
@Module({ @Module({
imports: [ imports: [
MikroOrmModule.forFeature([Order, OrderItem, User, Restaurant, Food, UserAddress, RestaurantPaymentMethod]), MikroOrmModule.forFeature([Order, OrderItem, User, Restaurant, Food, UserAddress, PaymentMethod]),
CartModule, CartModule,
UtilsModule, UtilsModule,
AuthModule, AuthModule,
+9 -11
View File
@@ -6,12 +6,11 @@ import { User } from '../users/entities/user.entity';
import { Restaurant } from '../restaurants/entities/restaurant.entity'; import { Restaurant } from '../restaurants/entities/restaurant.entity';
import { Food } from '../foods/entities/food.entity'; import { Food } from '../foods/entities/food.entity';
import { UserAddress } from '../users/entities/user-address.entity'; import { UserAddress } from '../users/entities/user-address.entity';
import { RestaurantPaymentMethod } from '../payments/entities/restaurant-payment-method.entity';
import { CartService } from '../cart/providers/cart.service'; import { CartService } from '../cart/providers/cart.service';
import { OrderStatus } from './interface/order-status'; import { OrderStatus } from './interface/order-status';
import { PaymentStatusEnum } from '../payments/interface/payment'; import { PaymentStatusEnum } from '../payments/interface/payment';
import { Cart } from '../cart/interfaces/cart.interface'; import { Cart } from '../cart/interfaces/cart.interface';
import { RestaurantPaymentMethodRepository } from '../payments/repositories/restaurant-payment-method.repository'; import { PaymentMethod } from '../payments/entities/payment-method.entity';
// import { PaymentGatewayService } from '../payments/services/payment-gateway.service.tss'; // import { PaymentGatewayService } from '../payments/services/payment-gateway.service.tss';
import { PaymentsService } from '../payments/services/payments.service'; import { PaymentsService } from '../payments/services/payments.service';
@@ -21,14 +20,13 @@ export class OrdersService {
private readonly em: EntityManager, private readonly em: EntityManager,
private readonly cartService: CartService, private readonly cartService: CartService,
private readonly paymentsService: PaymentsService, private readonly paymentsService: PaymentsService,
private readonly RestaurantPaymentMethodRepository: RestaurantPaymentMethodRepository,
// private readonly paymentGatewayService: PaymentGatewayService, // private readonly paymentGatewayService: PaymentGatewayService,
) {} ) {}
async checkout(userId: string, restaurantId: string) { async checkout(userId: string, restaurantId: string) {
const cart = await this.cartService.findOne(userId, restaurantId); const cart = await this.cartService.findOne(userId, restaurantId);
const { order } = await this.create(userId, restaurantId, cart); const { order } = await this.createOrder(userId, restaurantId, cart);
await this.cartService.clearCart(userId, restaurantId); await this.cartService.clearCart(userId, restaurantId);
@@ -40,7 +38,7 @@ export class OrdersService {
return { order, paymentUrl }; return { order, paymentUrl };
} }
async create(userId: string, restaurantId: string, cart: Cart) { async createOrder(userId: string, restaurantId: string, cart: Cart) {
const validationResult = await this.validateCartForOrder(userId, restaurantId, cart); const validationResult = await this.validateCartForOrder(userId, restaurantId, cart);
// Create order within a transaction // Create order within a transaction
return this.em.transactional(async em => { return this.em.transactional(async em => {
@@ -108,7 +106,7 @@ export class OrdersService {
user: User; user: User;
restaurant: Restaurant; restaurant: Restaurant;
address: UserAddress; address: UserAddress;
paymentMethod: RestaurantPaymentMethod; paymentMethod: PaymentMethod;
orderItemsData: Array<{ food: Food; quantity: number; unitPrice: number; discount: number }>; orderItemsData: Array<{ food: Food; quantity: number; unitPrice: number; discount: number }>;
}> { }> {
// Validate cart has items // Validate cart has items
@@ -150,12 +148,12 @@ export class OrdersService {
} }
const paymentMethod = await this.em.findOne( const paymentMethod = await this.em.findOne(
RestaurantPaymentMethod, PaymentMethod,
{ {
id: cart.paymentMethodId,
restaurant: { id: restaurantId }, restaurant: { id: restaurantId },
paymentMethod: { id: cart.paymentMethodId },
}, },
{ populate: ['restaurant', 'paymentMethod'] }, { populate: ['restaurant'] },
); );
if (!paymentMethod) { if (!paymentMethod) {
@@ -164,8 +162,8 @@ export class OrdersService {
); );
} }
if (!paymentMethod.isActive) { if (!paymentMethod.enabled) {
throw new BadRequestException('Payment method is not active for this restaurant'); throw new BadRequestException('Payment method is not enabled for this restaurant');
} }
// Validate stock and prepare order items data // Validate stock and prepare order items data