|
|
@ -1,30 +1,26 @@ |
|
|
|
import { Injectable } from "@nestjs/common"; |
|
|
|
import { Injectable, HttpException, HttpStatus } from "@nestjs/common"; |
|
|
|
import { InjectModel } from "@nestjs/sequelize"; |
|
|
|
import { InjectModel } from "@nestjs/sequelize"; |
|
|
|
import { Cart } from "./entities/cart.entity"; |
|
|
|
import { Cart } from "./entities/cart.entity"; |
|
|
|
import { HttpException, HttpStatus } from "@nestjs/common"; |
|
|
|
|
|
|
|
import { CartResponse } from "./cart.response"; |
|
|
|
import { CartResponse } from "./cart.response"; |
|
|
|
import { User } from "src/users/entities/user.entity"; |
|
|
|
import { User } from "src/users/entities/user.entity"; |
|
|
|
import { Product } from "src/products/entities/product.entity"; |
|
|
|
import { Product } from "src/products/entities/product.entity"; |
|
|
|
|
|
|
|
import { console } from "inspector"; |
|
|
|
|
|
|
|
|
|
|
|
@Injectable() |
|
|
|
@Injectable() |
|
|
|
export class CartService { |
|
|
|
export class CartService { |
|
|
|
constructor( |
|
|
|
constructor( |
|
|
|
@InjectModel(Cart) private readonly cartModel: typeof Cart, |
|
|
|
@InjectModel(Cart) private readonly cartModel: typeof Cart, |
|
|
|
@InjectModel(User) private readonly userModel: typeof User, |
|
|
|
|
|
|
|
@InjectModel(Product) private readonly productModel: typeof Product, |
|
|
|
@InjectModel(Product) private readonly productModel: typeof Product, |
|
|
|
) {} |
|
|
|
) {} |
|
|
|
|
|
|
|
|
|
|
|
async addToCart(userId: number, productId: number, quantity: number): Promise<CartResponse> { |
|
|
|
// Add product to cart
|
|
|
|
try { |
|
|
|
async addToCart(addToCartDto: { userId: number; productId: number; quantity: number }): Promise<{ message: string; cartItem: Cart }> { |
|
|
|
|
|
|
|
const { userId, productId, quantity } = addToCartDto; |
|
|
|
|
|
|
|
|
|
|
|
if (!userId || !productId || !quantity) { |
|
|
|
if (!userId || !productId || !quantity) { |
|
|
|
throw new HttpException("Missing required parameters: userId, productId, and quantity are required.", HttpStatus.BAD_REQUEST); |
|
|
|
throw new HttpException("Missing required parameters: userId, productId, and quantity are required.", HttpStatus.BAD_REQUEST); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const user = await this.userModel.findByPk(userId); |
|
|
|
|
|
|
|
if (!user) { |
|
|
|
|
|
|
|
throw new HttpException("User not found!", HttpStatus.NOT_FOUND); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const product = await this.productModel.findByPk(productId); |
|
|
|
const product = await this.productModel.findByPk(productId); |
|
|
|
if (!product) { |
|
|
|
if (!product) { |
|
|
|
throw new HttpException("Product not found!", HttpStatus.NOT_FOUND); |
|
|
|
throw new HttpException("Product not found!", HttpStatus.NOT_FOUND); |
|
|
@ -36,66 +32,67 @@ export class CartService { |
|
|
|
|
|
|
|
|
|
|
|
if (existingCartItem) { |
|
|
|
if (existingCartItem) { |
|
|
|
existingCartItem.quantity += Number(quantity); |
|
|
|
existingCartItem.quantity += Number(quantity); |
|
|
|
|
|
|
|
existingCartItem.totalPrice = existingCartItem.quantity * existingCartItem.productPrice; |
|
|
|
await existingCartItem.save(); |
|
|
|
await existingCartItem.save(); |
|
|
|
|
|
|
|
|
|
|
|
return { |
|
|
|
return { |
|
|
|
message: "Product quantity updated in cart successfully!", |
|
|
|
message: "Product quantity updated in cart successfully!", |
|
|
|
cartItem: existingCartItem, |
|
|
|
cartItem: existingCartItem, |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const newCartItem = await this.cartModel.create({ userId, productId, quantity }); |
|
|
|
const newCartItem = await this.cartModel.create({ userId, productId, quantity, productPrice: product.price, totalPrice: product.price * quantity, productName: product.name }); |
|
|
|
|
|
|
|
|
|
|
|
return { |
|
|
|
return { |
|
|
|
message: "Product added to cart successfully!", |
|
|
|
message: "Product added to cart successfully!", |
|
|
|
cartItem: newCartItem, |
|
|
|
cartItem: newCartItem, |
|
|
|
}; |
|
|
|
}; |
|
|
|
} catch (error) { |
|
|
|
|
|
|
|
// Enhanced error handling
|
|
|
|
|
|
|
|
if (error instanceof HttpException) { |
|
|
|
|
|
|
|
throw error; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
throw new HttpException(`An error occurred while adding the product to the cart: ${error.message}`, HttpStatus.INTERNAL_SERVER_ERROR); |
|
|
|
|
|
|
|
} |
|
|
|
// Get user's cart
|
|
|
|
} |
|
|
|
async getUserCart(userId: number): Promise<{ cartItems: Cart[]; totalPrice: number }> { |
|
|
|
async getUserCart(userId: number): Promise<Cart[]> { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
const cartItems = await this.cartModel.findAll({ |
|
|
|
const cartItems = await this.cartModel.findAll({ |
|
|
|
where: { userId }, |
|
|
|
where: { userId }, |
|
|
|
include: ["product"], |
|
|
|
include: [ |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
model: Product, |
|
|
|
|
|
|
|
attributes: ["id", "name", "price", "description", "imageUrl"], |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
], |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
if (!cartItems || cartItems.length === 0) { |
|
|
|
if (!cartItems || cartItems.length === 0) { |
|
|
|
throw new HttpException("No cart items found for the specified user.", HttpStatus.NOT_FOUND); |
|
|
|
throw new HttpException("No cart items found for the specified user.", HttpStatus.NOT_FOUND); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return cartItems; |
|
|
|
const totalPrice = cartItems.reduce((sum, item) => sum + Number(item.totalPrice), 0); |
|
|
|
} catch (error) { |
|
|
|
|
|
|
|
if (error instanceof HttpException) { |
|
|
|
return { cartItems, totalPrice }; |
|
|
|
throw error; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
throw new HttpException("An error occurred while retrieving the cart.", HttpStatus.INTERNAL_SERVER_ERROR); |
|
|
|
// Update cart item quantity
|
|
|
|
|
|
|
|
async updateCart(userId: number, productId: number, quantity: number): Promise<Cart> { |
|
|
|
|
|
|
|
const cartItem = await this.cartModel.findOne({ where: { userId, productId } }); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!cartItem) { |
|
|
|
|
|
|
|
throw new HttpException("Product not found in the cart.", HttpStatus.NOT_FOUND); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cartItem.quantity = quantity; |
|
|
|
|
|
|
|
cartItem.totalPrice = cartItem.quantity * cartItem.productPrice; |
|
|
|
|
|
|
|
await cartItem.save(); |
|
|
|
|
|
|
|
return cartItem; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Remove product from cart
|
|
|
|
async removeFromCart(userId: number, productId: number): Promise<{ message: string }> { |
|
|
|
async removeFromCart(userId: number, productId: number): Promise<{ message: string }> { |
|
|
|
try { |
|
|
|
|
|
|
|
const cartItem = await this.cartModel.findOne({ where: { userId, productId } }); |
|
|
|
const cartItem = await this.cartModel.findOne({ where: { userId, productId } }); |
|
|
|
|
|
|
|
|
|
|
|
if (!cartItem) { |
|
|
|
if (!cartItem) { |
|
|
|
throw new HttpException('Product not found in the cart.', HttpStatus.NOT_FOUND); |
|
|
|
throw new HttpException("Product not found in the cart.", HttpStatus.NOT_FOUND); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
await cartItem.destroy(); |
|
|
|
await cartItem.destroy(); |
|
|
|
return { message: 'Item deleted from your cart successfully.' }; |
|
|
|
return { message: "Item deleted from your cart successfully." }; |
|
|
|
} catch (error) { |
|
|
|
|
|
|
|
if (error instanceof HttpException) { |
|
|
|
|
|
|
|
throw error; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
throw new HttpException( |
|
|
|
|
|
|
|
'An error occurred while removing the product from the cart.', |
|
|
|
|
|
|
|
HttpStatus.INTERNAL_SERVER_ERROR, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|