address
This commit is contained in:
@@ -9,12 +9,7 @@ import { JwtModule } from '@nestjs/jwt';
|
|||||||
import { UtilsModule } from '../utils/utils.module';
|
import { UtilsModule } from '../utils/utils.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [MikroOrmModule.forFeature([Food, Restaurant]), AuthModule, JwtModule, UtilsModule],
|
||||||
MikroOrmModule.forFeature([Food, Restaurant]),
|
|
||||||
AuthModule,
|
|
||||||
JwtModule,
|
|
||||||
UtilsModule,
|
|
||||||
],
|
|
||||||
controllers: [CartController],
|
controllers: [CartController],
|
||||||
providers: [CartService],
|
providers: [CartService],
|
||||||
exports: [CartService],
|
exports: [CartService],
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { CartService } from '../providers/cart.service';
|
|||||||
import { AddItemToCartDto } from '../dto/add-item.dto';
|
import { AddItemToCartDto } from '../dto/add-item.dto';
|
||||||
import { UpdateItemQuantityDto } from '../dto/update-item.dto';
|
import { UpdateItemQuantityDto } from '../dto/update-item.dto';
|
||||||
import { ApplyCouponDto } from '../dto/apply-coupon.dto';
|
import { ApplyCouponDto } from '../dto/apply-coupon.dto';
|
||||||
|
import { SetAddressDto } from '../dto/set-address.dto';
|
||||||
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiBody, ApiParam } from '@nestjs/swagger';
|
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiBody, ApiParam } from '@nestjs/swagger';
|
||||||
import { AuthGuard } from '../../auth/guards/auth.guard';
|
import { AuthGuard } from '../../auth/guards/auth.guard';
|
||||||
import { UserId } from 'src/common/decorators/user-id.decorator';
|
import { UserId } from 'src/common/decorators/user-id.decorator';
|
||||||
@@ -73,4 +74,14 @@ export class CartController {
|
|||||||
async removeCoupon(@UserId() userId: string, @RestId() restaurantId: string) {
|
async removeCoupon(@UserId() userId: string, @RestId() restaurantId: string) {
|
||||||
return this.cartService.removeCoupon(userId, restaurantId);
|
return this.cartService.removeCoupon(userId, restaurantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Patch('address')
|
||||||
|
@ApiOperation({ summary: 'Set address for cart' })
|
||||||
|
@ApiBody({ type: SetAddressDto })
|
||||||
|
@ApiResponse({ status: 200, description: 'Address set successfully' })
|
||||||
|
@ApiResponse({ status: 400, description: 'Bad request (e.g., address does not belong to user)' })
|
||||||
|
@ApiResponse({ status: 404, description: 'Address not found' })
|
||||||
|
async setAddress(@UserId() userId: string, @RestId() restaurantId: string, @Body() setAddressDto: SetAddressDto) {
|
||||||
|
return this.cartService.setAddress(userId, restaurantId, setAddressDto);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
|
export class SetAddressDto {
|
||||||
|
@ApiProperty({ description: 'User address ID', example: '01ARZ3NDEKTSV4RRFFQ69G5FAV' })
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsString()
|
||||||
|
addressId!: string;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
export interface CartItem {
|
||||||
|
itemId: string;
|
||||||
|
foodId: string;
|
||||||
|
foodTitle?: string;
|
||||||
|
quantity: number;
|
||||||
|
price: number;
|
||||||
|
discount: number;
|
||||||
|
totalPrice: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CartCoupon {
|
||||||
|
code: string;
|
||||||
|
discount: number;
|
||||||
|
discountType: 'amount' | 'percentage';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Cart {
|
||||||
|
userId: string;
|
||||||
|
restaurantId: string;
|
||||||
|
restaurantName?: string;
|
||||||
|
items: CartItem[];
|
||||||
|
coupon?: CartCoupon;
|
||||||
|
addressId?: string;
|
||||||
|
totalPrice: number;
|
||||||
|
totalDiscount: number;
|
||||||
|
couponDiscount: number;
|
||||||
|
vatAmount: number;
|
||||||
|
finalPrice: number;
|
||||||
|
totalItems: number;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
}
|
||||||
@@ -7,38 +7,10 @@ import { ulid } from 'ulid';
|
|||||||
import { AddItemToCartDto } from '../dto/add-item.dto';
|
import { AddItemToCartDto } from '../dto/add-item.dto';
|
||||||
import { UpdateItemQuantityDto } from '../dto/update-item.dto';
|
import { UpdateItemQuantityDto } from '../dto/update-item.dto';
|
||||||
import { ApplyCouponDto } from '../dto/apply-coupon.dto';
|
import { ApplyCouponDto } from '../dto/apply-coupon.dto';
|
||||||
|
import { SetAddressDto } from '../dto/set-address.dto';
|
||||||
|
import { UserAddress } from '../../users/entities/user-address.entity';
|
||||||
|
import { Cart, CartItem, CartCoupon } from '../interfaces/cart.interface';
|
||||||
|
|
||||||
export interface CartItem {
|
|
||||||
itemId: string;
|
|
||||||
foodId: string;
|
|
||||||
foodTitle?: string;
|
|
||||||
quantity: number;
|
|
||||||
price: number;
|
|
||||||
discount: number;
|
|
||||||
totalPrice: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CartCoupon {
|
|
||||||
code: string;
|
|
||||||
discount: number;
|
|
||||||
discountType: 'amount' | 'percentage';
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Cart {
|
|
||||||
userId: string;
|
|
||||||
restaurantId: string;
|
|
||||||
restaurantName?: string;
|
|
||||||
items: CartItem[];
|
|
||||||
coupon?: CartCoupon;
|
|
||||||
totalPrice: number;
|
|
||||||
totalDiscount: number;
|
|
||||||
couponDiscount: number;
|
|
||||||
vatAmount: number;
|
|
||||||
finalPrice: number;
|
|
||||||
totalItems: number;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CartService {
|
export class CartService {
|
||||||
@@ -282,6 +254,31 @@ export class CartService {
|
|||||||
return cart;
|
return cart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set address for cart
|
||||||
|
*/
|
||||||
|
async setAddress(userId: string, restaurantId: string, setAddressDto: SetAddressDto): Promise<Cart> {
|
||||||
|
const cart = await this.findOne(userId, restaurantId);
|
||||||
|
|
||||||
|
// Find and validate address belongs to user
|
||||||
|
const address = await this.em.findOne(UserAddress, { id: setAddressDto.addressId }, { populate: ['user'] });
|
||||||
|
if (!address) {
|
||||||
|
throw new NotFoundException(`Address with ID ${setAddressDto.addressId} not found`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify address belongs to the user
|
||||||
|
if (address.user.id !== userId) {
|
||||||
|
throw new BadRequestException('Address does not belong to the current user');
|
||||||
|
}
|
||||||
|
|
||||||
|
cart.addressId = setAddressDto.addressId;
|
||||||
|
cart.updatedAt = new Date().toISOString();
|
||||||
|
|
||||||
|
await this.saveCart(cart);
|
||||||
|
|
||||||
|
return cart;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recalculate cart totals (including coupon discount and VAT)
|
* Recalculate cart totals (including coupon discount and VAT)
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user