This commit is contained in:
2026-02-09 15:47:17 +03:30
parent 65b937d662
commit 8c9e7053f5
10 changed files with 90 additions and 123 deletions
+45 -45
View File
@@ -5,7 +5,7 @@ import { OrderCouponDetail } from 'src/modules/orders/interface/order.interface'
import { Cart } from '../interfaces/cart.interface';
import { BulkAddItemsToCartDto } from '../dto/bulk-add-items.dto';
import { ApplyCouponDto } from '../dto/apply-coupon.dto';
import { SetAllCartParmsDto } from '../dto/set-all-cart-params.dto';
import { SetAllCartParmsDto } from '../dto/set-all-cart-params.dto';
import { CouponService } from 'src/modules/coupons/providers/coupon.service';
import { CartRepository } from '../repositories/cart.repository';
import { CartValidationService } from './cart-validation.service';
@@ -32,15 +32,15 @@ export class CartService {
/**
* Set all cart parameters at once
*/
async setAllCartParams(userId: string, restaurantId: string, params: SetAllCartParmsDto): Promise<Cart> {
const { deliveryMethodId, paymentMethodId, addressId, carAddress, description, tableNumber } = params;
async setAllCartParams(userId: string, shopId: string, params: SetAllCartParmsDto): Promise<Cart> {
const { deliveryMethodId, paymentMethodId, addressId, description } = params;
// get existing cart (or throw)
const cart = await this.findOneOrFail(userId, restaurantId);
const cart = await this.findOneOrFail(userId, shopId);
// Validate and get delivery method
const deliveryMethod = await this.validationService.getEnabledDeliveryMethodOrFail(
restaurantId,
shopId,
deliveryMethodId,
);
cart.deliveryMethodId = deliveryMethodId;
@@ -65,7 +65,7 @@ export class CartService {
// ensure address is within shop service area
await this.validationService.assertAddressInsideServiceArea(
restaurantId,
shopId,
address.latitude,
address.longitude,
);
@@ -85,7 +85,7 @@ export class CartService {
// Validate and set payment method
const paymentMethod = await this.validationService.getEnabledPaymentMethodOrFail(
restaurantId,
shopId,
paymentMethodId,
);
@@ -93,7 +93,7 @@ export class CartService {
await this.calculationService.recalculateCartTotals(cart);
if (paymentMethod.method === PaymentMethodEnum.Wallet) {
await this.validationService.assertWalletHasEnoughBalance(userId, restaurantId, cart.total);
await this.validationService.assertWalletHasEnoughBalance(userId, shopId, cart.total);
}
cart.paymentMethodId = paymentMethodId;
@@ -110,21 +110,21 @@ export class CartService {
/**
* Get or create cart for user and shop
*/
async getOrCreateCart(userId: string, restaurantId: string): Promise<Cart> {
const existingCart = await this.cartRepository.findByUserAndRestaurant(userId, restaurantId);
async getOrCreateCart(userId: string, shopId: string): Promise<Cart> {
const existingCart = await this.cartRepository.findByUserAndShop(userId, shopId);
if (existingCart) {
return existingCart;
}
// Find shop
const shop = await this.shopService.findOrFail(restaurantId);
const shop = await this.shopService.findOrFail(shopId);
// Create new cart
const now = this.nowIso();
const cart: Cart = {
userId,
restaurantId,
restaurantName: shop.name,
shopId: shop.id,
shopName: shop.name,
items: [],
deliveryFee: 0,
subTotal: 0,
@@ -145,8 +145,8 @@ export class CartService {
/**
* Find cart by user and shop
*/
async findOneOrFail(userId: string, restaurantId: string): Promise<Cart> {
const cart = await this.cartRepository.findByUserAndRestaurant(userId, restaurantId);
async findOneOrFail(userId: string, shopId: string): Promise<Cart> {
const cart = await this.cartRepository.findByUserAndShop(userId, shopId);
if (!cart) {
throw new NotFoundException(CartMessage.NOT_FOUND);
}
@@ -156,17 +156,17 @@ export class CartService {
/**
* Increment item quantity in cart
*/
async incrementItem(userId: string, restaurantId: string, foodId: string, quantity: number): Promise<Cart> {
const cart = await this.getOrCreateCart(userId, restaurantId);
await this.itemService.addOrIncrementItem(cart, foodId, restaurantId, quantity);
async incrementItem(userId: string, shopId: string, foodId: string, quantity: number): Promise<Cart> {
const cart = await this.getOrCreateCart(userId, shopId);
await this.itemService.addOrIncrementItem(cart, foodId, shopId, quantity);
return this.recalculateAndSaveCart(cart);
}
/**
* Decrement item quantity in cart by 1 (removes item if quantity reaches 0)
*/
async decrementItem(userId: string, restaurantId: string, foodId: string): Promise<Cart> {
const cart = await this.findOneOrFail(userId, restaurantId);
async decrementItem(userId: string, shopId: string, foodId: string): Promise<Cart> {
const cart = await this.findOneOrFail(userId, shopId);
await this.itemService.decrementOrRemoveItem(cart, foodId);
return this.recalculateAndSaveCart(cart);
}
@@ -174,11 +174,11 @@ export class CartService {
/**
* Bulk add items to cart (increments quantity if items exist)
*/
async bulkAddItems(userId: string, restaurantId: string, bulkAddItemsDto: BulkAddItemsToCartDto): Promise<Cart> {
const cart = await this.getOrCreateCart(userId, restaurantId);
async bulkAddItems(userId: string, shopId: string, bulkAddItemsDto: BulkAddItemsToCartDto): Promise<Cart> {
const cart = await this.getOrCreateCart(userId, shopId);
for (const addItemDto of bulkAddItemsDto.items) {
await this.itemService.addOrIncrementItem(cart, addItemDto.foodId, restaurantId, addItemDto.quantity);
await this.itemService.addOrIncrementItem(cart, addItemDto.productId, shopId, addItemDto.quantity);
}
return this.recalculateAndSaveCart(cart);
@@ -187,8 +187,8 @@ export class CartService {
/**
* Remove item from cart
*/
async removeItem(userId: string, restaurantId: string, foodId: string): Promise<Cart> {
const cart = await this.findOneOrFail(userId, restaurantId);
async removeItem(userId: string, shopId: string, foodId: string): Promise<Cart> {
const cart = await this.findOneOrFail(userId, shopId);
this.itemService.removeItemOrFail(cart, foodId);
return this.recalculateAndSaveCart(cart);
}
@@ -196,15 +196,15 @@ export class CartService {
/**
* Apply coupon to cart
*/
async applyCoupon(userId: string, restaurantId: string, applyCouponDto: ApplyCouponDto): Promise<Cart> {
const cart = await this.findOneOrFail(userId, restaurantId);
async applyCoupon(userId: string, shopId: string, applyCouponDto: ApplyCouponDto): Promise<Cart> {
const cart = await this.findOneOrFail(userId, shopId);
const orderAmount = cart.subTotal - cart.itemsDiscount;
const user = await this.userService.findOneOrFail(userId);
// check if coupon is valid and belong to the shop
const { valid, coupon, message } = await this.couponService.validateCoupon(
applyCouponDto.code,
restaurantId,
shopId,
Number(orderAmount),
user.phone,
);
@@ -241,8 +241,8 @@ export class CartService {
/**
* Remove coupon from cart
*/
async removeCoupon(userId: string, restaurantId: string): Promise<Cart> {
const cart = await this.findOneOrFail(userId, restaurantId);
async removeCoupon(userId: string, shopId: string): Promise<Cart> {
const cart = await this.findOneOrFail(userId, shopId);
cart.coupon = undefined;
return this.recalculateAndSaveCart(cart);
@@ -251,14 +251,14 @@ export class CartService {
/**
* Set address for cart
*/
async setAddress(userId: string, restaurantId: string, addressId: string): Promise<Cart> {
const cart = await this.findOneOrFail(userId, restaurantId);
async setAddress(userId: string, shopId: string, addressId: string): Promise<Cart> {
const cart = await this.findOneOrFail(userId, shopId);
const deliveryMethodId = this.validationService.requireDeliveryMethodId(
cart,
'Delivery method must be set before setting address',
);
const deliveryMethod = await this.deliveryService.findOrFail(restaurantId, deliveryMethodId);
const deliveryMethod = await this.deliveryService.findOrFail(shopId, deliveryMethodId);
this.validationService.assertDeliveryMethod(
deliveryMethod.method,
@@ -274,7 +274,7 @@ export class CartService {
// ensure address is within shop service area
await this.validationService.assertAddressInsideServiceArea(
restaurantId,
shopId,
address.latitude,
address.longitude,
);
@@ -298,17 +298,17 @@ export class CartService {
*/
async setPaymentMethod(
userId: string,
restaurantId: string,
shopId: string,
paymentMethodId: string,
): Promise<Cart> {
const cart = await this.findOneOrFail(userId, restaurantId);
const cart = await this.findOneOrFail(userId, shopId);
const paymentMethod = await this.validationService.getEnabledPaymentMethodOrFail(
restaurantId,
shopId,
paymentMethodId,
);
if (paymentMethod.method === PaymentMethodEnum.Wallet) {
await this.validationService.assertWalletHasEnoughBalance(userId, restaurantId, cart.total);
await this.validationService.assertWalletHasEnoughBalance(userId, shopId, cart.total);
}
cart.paymentMethodId = paymentMethodId;
return this.recalculateAndSaveCart(cart);
@@ -319,13 +319,13 @@ export class CartService {
*/
async setDeliveryMethod(
userId: string,
restaurantId: string,
shopId: string,
deliveryMethodId: string,
): Promise<Cart> {
const cart = await this.findOneOrFail(userId, restaurantId);
const cart = await this.findOneOrFail(userId, shopId);
const deliveryMethod = await this.validationService.getEnabledDeliveryMethodOrFail(
restaurantId,
shopId,
deliveryMethodId,
);
@@ -338,8 +338,8 @@ export class CartService {
/**
* Set description for cart
*/
async setDescription(userId: string, restaurantId: string, description: string): Promise<Cart> {
const cart = await this.findOneOrFail(userId, restaurantId);
async setDescription(userId: string, shopId: string, description: string): Promise<Cart> {
const cart = await this.findOneOrFail(userId, shopId);
cart.description = description;
return this.saveTouchedCart(cart);
@@ -349,8 +349,8 @@ export class CartService {
/**
* Clear cart from cache
*/
async clearCart(userId: string, restaurantId: string): Promise<void> {
return this.cartRepository.delete(userId, restaurantId);
async clearCart(userId: string, shopId: string): Promise<void> {
return this.cartRepository.delete(userId, shopId);
}
/**