Skip to content

Commit

Permalink
Fes 28 update cart (#36)
Browse files Browse the repository at this point in the history
* create controller and service handling method

* check if updated items are empty

* verify sku_id

---------

Co-authored-by: NHT <[email protected]>
  • Loading branch information
nfesta2023 and hoangtuan910 authored Jan 11, 2024
1 parent 238807f commit e50c38d
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 2 deletions.
39 changes: 39 additions & 0 deletions src/feature/cart/cart.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { FlagsmithService } from 'src/dependency/flagsmith/flagsmith.service';
import { MessagePattern } from '@nestjs/microservices';
import { AddToCartRequest } from './dto/add-to-cart-request.dto';
import { AddToCartResponse } from './dto/add-to-cart-response.dto';
import { UpdateCartRequest } from './dto/update-cart-request.dto';
import { UpdateCartResponse } from './dto/update-cart-response.dto';
import { GetCartDetailResponse } from './dto/get-cart-detail-response.dto';
import { CartItem } from 'src/entity/cart-item.entity';

Expand Down Expand Up @@ -86,4 +88,41 @@ export class CartController {
return res;
}
}

@MessagePattern({ cmd: 'update_cart' })
async updateCart(data: UpdateCartRequest): Promise<UpdateCartResponse> {
if (this.flagService.isFeatureEnabled('fes-28-update-cart')) {
const { customer_id, updated_items, lang = 'vie' } = data;
const res = new UpdateCartResponse(200, '');
try {
if (updated_items.length <= 0) {
throw new HttpException('Updated Items cannot be empty', 400);
}
const cartItems: CartItem[] =
await this.cartService.updateCartFromEndPoint(
customer_id,
updated_items,
lang,
);
res.statusCode = 200;
res.message = 'Update cart successfully';
res.data = {
customer_id: data.customer_id,
cart_info: cartItems,
};
} catch (error) {
if (error instanceof HttpException) {
res.statusCode = error.getStatus();
res.message = error.getResponse();
res.data = null;
} else {
res.statusCode = 500;
res.message = error.toString();
res.data = null;
}
}

return res;
}
}
}
60 changes: 59 additions & 1 deletion src/feature/cart/cart.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { EntityManager } from 'typeorm';
import { CartItem } from 'src/entity/cart-item.entity';
import { CommonService } from '../common/common.service';
import { SKU } from 'src/entity/sku.entity';
import { BasicTasteSelection, OptionSelection } from 'src/type';
import {
BasicTasteSelection,
OptionSelection,
UpdatedCartItem,
} from 'src/type';

@Injectable()
export class CartService {
Expand Down Expand Up @@ -229,4 +233,58 @@ export class CartService {
.execute();
}
}

async updateCartFromEndPoint(
customer_id: number,
updated_cart_items: UpdatedCartItem[],
lang: string,
): Promise<CartItem[]> {
if (this.flagService.isFeatureEnabled('fes-28-update-cart')) {
const mentionedCartItems = await this.getCartByItemId(
updated_cart_items.map((i) => i.item_id),
customer_id,
);

if (mentionedCartItems.length < updated_cart_items.length) {
throw new HttpException(
'There are some of updated items which do not belong to the customer',
400,
);
}

//build new cart
const fullUpdatedItems: CartItem[] = [];
for (const mentionedCartItem of mentionedCartItems) {
const updatedCartItem = updated_cart_items.find(
(i) => i.item_id === mentionedCartItem.item_id,
);

if (updatedCartItem.sku_id != mentionedCartItem.sku_id) {
const isAllowedSku =
await this.commonService.checkIfSkuHasSameMenuItem([
updatedCartItem.sku_id,
mentionedCartItem.sku_id,
]);

if (!isAllowedSku) {
throw new HttpException(
`Updated sku_id ${updatedCartItem.sku_id} does not have the same Menu Item as the current mentioning sku_id`,
400,
);
}
}
}

return await this.getCart(customer_id);
}
}
async getCartByItemId(item_ids: number[], customer_id) {
if (this.flagService.isFeatureEnabled('fes-28-update-cart')) {
return await this.entityManager
.createQueryBuilder(CartItem, 'cart')
.where('cart.customer_id = :customer_id', { customer_id })
.andWhere('cart.item_id IN (:...item_ids)', { item_ids })
.getMany();
}
}
}
23 changes: 23 additions & 0 deletions src/feature/cart/dto/update-cart-request.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export class UpdateCartRequest {
customer_id: number;
updated_items: UpdatedCartItem[];
lang?: string;
}

interface UpdatedCartItem {
item_id: number;
sku_id: number;
qty_ordered: number;
advanced_taste_customization_obj: OptionSelection[];
basic_taste_customization_obj: BasicTasteSelection[];
notes: string;
}

interface OptionSelection {
option_id: string;
value_id: string;
}

interface BasicTasteSelection {
no_adding_id: string;
}
25 changes: 25 additions & 0 deletions src/feature/cart/dto/update-cart-response.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { GeneralResponse } from 'src/dto/general-response.dto';

export class UpdateCartResponse extends GeneralResponse {
data: CartDetail;
}

interface CartDetail {
customer_id: number;
cart_info: CartItem[];
}

interface CartItem {
item_id: number;
sku_id: number;
customer_id: number;
qty_ordered: number;
advanced_taste_customization: string;
basic_taste_customization: string;
portion_customization: string;
advanced_taste_customization_obj: string;
basic_taste_customization_obj: string;
notes: string;
restaurant_id: number;
created_at: Date;
}
24 changes: 23 additions & 1 deletion src/feature/common/common.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { HttpException, Inject, Injectable } from '@nestjs/common';
import {
BasicTasteSelection,
DeliveryRestaurant,
Expand Down Expand Up @@ -430,4 +430,26 @@ export class CommonService {
return result;
}
}

async checkIfSkuHasSameMenuItem(sku_ids: number[]): Promise<boolean> {
if (this.flagService.isFeatureEnabled('fes-28-update-cart')) {
const skuList = await this.entityManager
.createQueryBuilder(SKU, 'sku')
.where('sku.sku_id IN (:...sku_ids)', { sku_ids })
.getMany();

if (skuList.length != sku_ids.length) {
throw new HttpException(
'There are some sku_id which does not exist',
404,
);
}
const menuItems = skuList.map((i) => i.menu_item_id);
const uniqueMenuItems = [...new Set(menuItems)];
if (uniqueMenuItems.length != 1) {
return false;
}
return true;
}
}
}
9 changes: 9 additions & 0 deletions src/type/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,12 @@ export interface ValidationResult {
message: string;
data?: any;
}

export interface UpdatedCartItem {
item_id: number;
sku_id: number;
qty_ordered: number;
advanced_taste_customization_obj: OptionSelection[];
basic_taste_customization_obj: BasicTasteSelection[];
notes: string;
}

0 comments on commit e50c38d

Please sign in to comment.