address
This commit is contained in:
@@ -9,12 +9,7 @@ import { JwtModule } from '@nestjs/jwt';
|
||||
import { UtilsModule } from '../utils/utils.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
MikroOrmModule.forFeature([Food, Restaurant]),
|
||||
AuthModule,
|
||||
JwtModule,
|
||||
UtilsModule,
|
||||
],
|
||||
imports: [MikroOrmModule.forFeature([Food, Restaurant]), AuthModule, JwtModule, UtilsModule],
|
||||
controllers: [CartController],
|
||||
providers: [CartService],
|
||||
exports: [CartService],
|
||||
|
||||
@@ -3,6 +3,7 @@ import { CartService } from '../providers/cart.service';
|
||||
import { AddItemToCartDto } from '../dto/add-item.dto';
|
||||
import { UpdateItemQuantityDto } from '../dto/update-item.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 { AuthGuard } from '../../auth/guards/auth.guard';
|
||||
import { UserId } from 'src/common/decorators/user-id.decorator';
|
||||
@@ -73,4 +74,14 @@ export class CartController {
|
||||
async removeCoupon(@UserId() userId: string, @RestId() restaurantId: string) {
|
||||
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 { UpdateItemQuantityDto } from '../dto/update-item.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()
|
||||
export class CartService {
|
||||
@@ -282,6 +254,31 @@ export class CartService {
|
||||
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)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user