def get_board_list(self, board_info): engine = get_db_connection() try: Session = sessionmaker(bind=engine) session = Session() filter_list = [ {'model': 'Board', 'field': 'is_deleted', 'op': '==', 'value': False}, ] if board_info.get('name', None): filter_list.append({'model': 'Board', 'field': 'name', 'op': 'like', 'value': '%'+board_info['name']+'%'}) board_query = (session .query(Board.id, Board.name, Board.uploader, Board.create_at)) board_list = apply_filters(board_query, filter_list).slice(board_info['offset'], board_info['limit']).all() boards = [{ 'id': board[0], 'name': board[1], 'uploader': board[2], 'created_at': board[3] } for board in board_list] return boards except Exception as e: print(e) return jsonify({'message': e}), 500 finally: try: session.close() except Exception as e: print(e) return jsonify({'message': 'SESSION_CLOSE_ERROR'}), 500
def make_article(self, article_info): article = Article() engine = get_db_connection() try: Session = sessionmaker(bind=engine) session = Session() if session.query(Board.is_deleted).filter(Board.id == article_info['board_id']).one()[0]: return jsonify({'message': 'BOARD_NOT_EXISTS'}), 404 article.board_id = article_info['board_id'] article.uploader = article_info['uploader'] article.title = article_info['title'] article.content = article_info['content'] session.add(article) session.commit() return jsonify({'message': 'SUCCESS'}), 200 except Exception as e: print(e) return jsonify({'message': e}), 500 finally: try: session.close() except Exception as e: print(e) return jsonify({'message': 'SESSION_CLOSE_ERROR'}), 500
def get_color_filters(): """ 상품 등록시 컬러 필터 표출 엔드포인트 Returns: 200: 상품 등록시 선택할 수 있는 색상 필터 500: 데이터 베이스 에러 Authors: [email protected] (이소헌) History: 2020-04-09 ([email protected]): 초기 생성 """ try: db_connection = get_db_connection() if db_connection: product_service = ProductService() get_color_result = product_service.get_color_filters( db_connection) return get_color_result else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def delete_article(self, article_info): engine = get_db_connection() try: Session = sessionmaker(bind=engine) session = Session() uploader_db = session.query(Article.uploader).filter(Article.id == article_info['article_id']).one()[0] if (uploader_db != article_info['modifier']) and (article_info['auth_type_id'] != 1): return jsonify({'message': 'UNAUTHORIZED_ACTION'}), 403 if session.query(Board.is_deleted).filter(Board.id == article_info['board_id']).one()[0]: return jsonify({'message': 'BOARD_NOT_EXISTS'}), 404 if session.query(Article.is_deleted).filter(Article.id == article_info['article_id']).one()[0]: return jsonify({'message': 'ARTICLE_NOT_EXISTS'}), 404 (session .query(Article) .filter(Article.id == article_info['article_id']) .update({'is_deleted': article_info['is_deleted'], 'modifier': article_info['modifier']})) session.commit() return jsonify({'message': 'SUCCESS'}), 200 except Exception as e: print(e) return jsonify({'message': e}), 500 finally: try: session.close() except Exception as e: print(e) return jsonify({'message': 'SESSION_CLOSE_ERROR'}), 500
def delete_board(self, board_info): engine = get_db_connection() try: Session = sessionmaker(bind=engine) session = Session() if session.query(Board.is_deleted).filter(Board.id == board_info['board_id']).one()[0]: return jsonify({'message': 'BOARD_NOT_EXISTS'}), 404 (session .query(Board) .filter(Board.id == board_info['board_id']) .update({'is_deleted': board_info['is_deleted'], 'modifier': board_info['modifier']})) (session .query(Article) .filter(Article.board_id == board_info['board_id']) .update({'is_deleted': board_info['is_deleted'], 'modifier': board_info['modifier']})) session.commit() return jsonify({'message': 'SUCCESS'}), 200 except Exception as e: print(e) return jsonify({'message': e}), 500 finally: try: session.close() except Exception as e: print(e) return jsonify({'message': 'SESSION_CLOSE_ERROR'}), 500
def get_all_events(*args): """ 등록된 모든 이벤트 목록 표출 엔드포인트 Args: *args: 이벤트 정보 event_type_id: 이벤트 타입 event_name: 검색어에 포함되는 이벤트 이름 event_start_time: 검색할 이벤트 등록 날짜 시작 지점 event_end_time: 검색할 이벤트 등록 날짜 끝 지점 Returns: 200: 검색 조건에 맞는 이벤트 목록 400: 유효하지 않은 검색 날짜 조건 500: 데이터베이스 에러 Authors: [email protected] (이소헌) History: 2020-04-12 ([email protected]): 초기 생성 """ event_info = { 'auth_type_id': g.account_info['auth_type_id'], 'event_type_id': args[0], 'event_name': args[1], 'event_start_time': args[2], 'event_end_time': args[3], 'offset': args[4] if args[4] else 0, 'limit': args[5] if args[5] else 10 } if event_info['event_start_time'] and event_info['event_end_time']: if (datetime.strptime(event_info['event_start_time'], "%Y-%m-%d") \ > datetime.strptime(event_info['event_end_time'], "%Y-%m-%d")): return jsonify({'message': 'INVALID_EVENT_DATE'}), 400 db_connection = None try: db_connection = get_db_connection() if db_connection: event_service = EventService() events = event_service.get_all_events(event_info, db_connection) return events else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: if db_connection: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def login(*args): """ 셀러 로그인 엔드포인트 셀러 로그인 엔드포인트 입니다. login_id 와 password 를 받습니다. request.body: login_id: 로그인 아이디 password: 로그인 비밀번호 Args: *args: 유효성 검사를 통과한 request.body 의 인자 Returns: 200: SUCCESS 로그인 성공 401: INVALID_PASSWORD, STATUS_1_CANT_LOGIN 500: NO_DATABASE_CONNECTION Authors: [email protected] (최예지) History: 2020-04-04 ([email protected]): 초기 생성 2020-04-04 ([email protected]): account_info 에 필요한 정보 담음, DB 열림닫힘 여부에 따라 실행되는 함수 작성 """ # validation 확인이 된 data 를 account_info 로 재정의 account_info = {'login_id': args[0], 'password': args[1]} try: # DB에 연결 db_connection = get_db_connection() if db_connection: # service 에 있는 SellerService 를 가져와서 seller_service 라는 인스턴스를 만듦 seller_service = SellerService() # 로그인 함수를 실행한 결과값을 login_result 에 저장 login_result = seller_service.login(account_info, db_connection) return login_result # DB가 열리지 않았을 경우 else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 # 정의하지 않은 모든 error 를 잡아줌 except Exception as e: return jsonify({'message': f'{e}'}), 500 # try 랑 except 에 상관없이 무조건 실행 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def get_my_page(): """ 계정 셀러정보 표출 엔드포인트(my_page) mypage 셀러정보를 표출하는 엔드포인트 입니다. 로그인 데코레이터로 셀러의 계정 번호를 확인합니다. 확인된 계정 정보를 service 로 넘겨줍니다. g.account_info: 데코레이터에서 넘겨받은 계정 정보 auth_type_id: 계정의 권한정보 account_no: 데코레이터에서 확인된 계정번호 Returns: http 응답코드 200: SUCCESS 셀러정보 겟 완료 400: INVALID_ACCOUNT_NO, INVALID_AUTH_TYPE_ID 403: NO_AUTHORIZATION 500: NO_DATABASE_CONNECTION, DB_CURSOR_ERROR, INVALID_KEY Authors: [email protected] (이종민) History: 2020-04-08 ([email protected]): 초기 생성 """ # get_seller_info dao 를 같이 쓰기 위해 account_no를 아래와 같이 저장 account_info = { 'parameter_account_no': g.account_info['account_no'], 'auth_type_id': g.account_info['auth_type_id'] } try: db_connection = get_db_connection() if db_connection: seller_service = SellerService() getting_seller_info_result = seller_service.get_my_page( account_info, db_connection) return getting_seller_info_result else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def get_article_list(self, article_info): engine = get_db_connection() try: Session = sessionmaker(bind=engine) session = Session() if session.query(Board.is_deleted).filter(Board.id == article_info['board_id']).one()[0]: return jsonify({'message': 'BOARD_NOT_EXISTS'}), 404 filter_list = [ {'model': 'Article', 'field': 'is_deleted', 'op': '==', 'value': False}, {'model': 'Article', 'field': 'board_id', 'op': '==', 'value': article_info['board_id']} ] if article_info.get('title', None): filter_list.append( {'model': 'Article', 'field': 'title', 'op': 'like', 'value': '%' + article_info['title'] + '%'}) if article_info.get('uploader', None): filter_list.append( {'model': 'Article', 'field': 'uploader', 'op': 'like', 'value': '%' + article_info['uploader'] + '%'}) article_query = (session .query(Article.id, Article.title, User.full_name, Article.create_at, Article.updated_at, Article.is_deleted) .join(User, User.id == Article.uploader)) article_list = apply_filters(article_query, filter_list).order_by(Article.create_at.desc()).slice(article_info['offset'], article_info['limit']).all() articles = [{ 'id': article[0], 'title': article[1], 'author': article[2], 'created_at': article[3], 'updated_at': article[4], 'is_deleted': article[5] } for article in article_list] return articles except Exception as e: print(e) return jsonify({'message': e}), 500 finally: try: session.close() except Exception as e: print(e) return jsonify({'message': 'SESSION_CLOSE_ERROR'}), 500
def get_event_sorts(*args): """ 기획전 타입별 종류 표출 엔드포인트 기획전 타입별 종류 표출 엔드포인트 입니다. 기획전 등록페이지에서 기획전 타입 별 목록을 표출할때 사됩니다. Args: *args: 유효성 검사를 통과한 파라미터 url Parameter: event_type_id: 기획전 타입 아이디 Returns: 200: 기획전 타입별 종류 목록 500: DB_CURSOR_ERROR, INVALID_KEY, NO_DATABASE_CONNECTION Authors: [email protected] (이종민) History: 2020-04-09 ([email protected]): 초기 생성 """ # event_type_id 저장 event_type_info = {"event_type_id": args[0]} try: db_connection = get_db_connection() if db_connection: event_service = EventService() sorts = event_service.get_event_sorts(event_type_info, db_connection) return sorts else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def sigh_up(self, user_info): engine = get_db_connection() redis_connection = get_redis_connection() user = User() random_key = RandomKey() try: Session = sessionmaker(bind=engine) session = Session() if session.query(exists().where(User.email == user_info['email'])).one()[0]: return jsonify({'message': 'USER_EXISTS'}), 400 hashed_password = bcrypt.hashpw(user_info.get('password', None).encode('utf-8'), bcrypt.gensalt()).decode() user.full_name = user_info['full_name'] user.email = user_info['email'] user.password = hashed_password user.auth_type_id = user_info['auth_type_id'] session.add(user) # store redis key in db random_name = str(uuid.uuid4()) random_key.key = random_name session.add(random_key) token = jwt.encode({'id': user.id, 'exp': datetime.utcnow() + timedelta(days=6)}, SECRET['secret_key'], algorithm=SECRET['algorithm']) # store key and token in redis redis_connection.set(random_name, token) # commit session after all tasks done session.commit() return jsonify({random_name: token}), 200 except Exception as e: print(e) return jsonify({'message': e}), 500 finally: try: session.close() except Exception as e: print(e) return jsonify({'message': 'SESSION_CLOSE_ERROR'}), 500
def get_event_infos(event_no): """ 기획전 정보 표출 엔드포인트 기획전 정보 표출 엔드포인트 입니다. url parameter 로 받은 기획전 번호에 해당하는 정보를 표출합니다. Args: event_no: 기획전 번호 Returns: 200: 기획전 정보 400: INVALID_EVENT_NO 500: DB_CURSOR_ERROR, INVALID_KEY, NO_DATABASE_CONNECTION Authors: [email protected] (이종민) [email protected] (윤희철) History: 2020-04-10 ([email protected]): 초기 생성 2020-04-14 ([email protected]): 데이터베이스 커넥션 호출 시 try-catch 추가 """ # 마스터 권한이 아니면 반려 if g.account_info['auth_type_id'] != 1: return jsonify({'message': 'NO_AUTHORIZATION'}), 403 try: db_connection = get_db_connection() if db_connection: event_service = EventService() info = event_service.get_event_infos(event_no, db_connection) return info else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def get_second_categories(*args): """ 상품 2차 카테고리 목록 표출 선택된 상품 1차 카테고릭에 따라 해당하는 2차카테고리 목록 표출 Args: *args: first_category_no(integer): 1차 카테고리 인덱스 번호 Returns: 200: 1차 카테고리에 해당하는 2차 카테고리 목록 400: 데이터베이스 연결 에러 500: server error Authors: [email protected] (이소헌) History: 2020-04-02 ([email protected]): 초기 생성 2020-04-07 ([email protected]): URL 구조 변경 """ first_category_no = args[0] try: db_connection = get_db_connection() if db_connection: product_service = ProductService() categories = product_service.get_second_categories( db_connection, first_category_no) return categories else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 400 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def get_room_list(): try: db_connection = get_db_connection() if db_connection: room_service = RoomService() room_list = room_service.get_room_list(db_connection) return room_list return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def get_product_detail(product_no): """ 상품 등록/수정시 나타나는 개별 상품의 기존 정보 표출 엔드포인트 상품의 번호를 path parameter 로 받아 해당하는 상품의 기존 상세 정보를 표출. Args: product_no(integer): 상품 id Returns: 200: 상품별 상세 정보 500: 데이터베이스 에러 Authors: [email protected] (이소헌) History: 2020-04-03 ([email protected]): 초기 생성 2020-04-07 ([email protected]): 파라미터 변수를 product_info_no -> product_no로 변경 2020-04-16 ([email protected]): 사용하지 않는 parameter validator 삭제 """ try: db_connection = get_db_connection() if db_connection: product_service = ProductService() product_infos = product_service.get_product_detail( product_no, db_connection) return product_infos else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def sign_in(self, user_info): engine = get_db_connection() redis_connection = get_redis_connection() random_key = RandomKey() try: Session = sessionmaker(bind=engine) session = Session() user_info_db = session.query(User.password, User.id).filter(User.email == user_info['email']).all() if len(user_info_db) == 0: return jsonify({'message': 'USER_NOT_EXISTS'}), 400 elif bcrypt.checkpw(user_info['password'].encode('utf-8'), user_info_db[0][0].encode('utf-8')): token = jwt.encode({'id': user_info_db[0][1], 'exp': datetime.utcnow() + timedelta(days=6)}, SECRET['secret_key'], algorithm=SECRET['algorithm']) # store redis key in db random_name = str(uuid.uuid4()) random_key.key = random_name session.add(random_key) # store key and token in redis redis_connection.set(random_name, token) # commit session after all tasks done session.commit() return jsonify({random_name: token}), 200 return jsonify({'message': 'INVALID_REQUEST'}), 401 except Exception as e: print(e) return jsonify({'message': e}), 500 finally: try: session.close() except Exception as e: print(e) return jsonify({'message': 'SESSION_CLOSE_ERROR'}), 500
def make_board(self, board_info): board = Board() engine = get_db_connection() try: Session = sessionmaker(bind=engine) session = Session() board.uploader = board_info['uploader'] board.name = board_info['name'] session.add(board) session.commit() return jsonify({'message': 'SUCCESS'}), 200 except Exception as e: print(e) return jsonify({'message': e}), 500 finally: try: session.close() except Exception as e: print(e) return jsonify({'message': 'SESSION_CLOSE_ERROR'}), 500
def get_first_categories(*args): """ 상품 분류별 1차 카테고리 표출 엔드포인트 Returns: 200: 셀러가 속한 상품 분류에 따른 1차 카테고리 400: 데이터베이스 연결 에러 500: server error Authors: [email protected] (이소헌) History: 2020-04-02 ([email protected]): 초기 생성 2020-04-13 ([email protected]): 셀러 정보 얻어오는 경로를 token 내부 데이터에서 query string 으로 변경 """ account_info = {'account_no': args[0]} try: db_connection = get_db_connection() if db_connection: product_service = ProductService() categories = product_service.get_first_categories( account_info, db_connection) return categories else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 400 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def get_article_detail(self, article_info): engine = get_db_connection() try: Session = sessionmaker(bind=engine) session = Session() if session.query(Board.is_deleted).filter(Board.id == article_info['board_id']).one()[0]: return jsonify({'message': 'BOARD_NOT_EXISTS'}), 404 if session.query(Article.is_deleted).filter(Article.id == article_info['article_id']).one()[0]: return jsonify({'message': 'ARTICLE_NOT_EXISTS'}), 404 article_detail = (session .query(Article.title, Article.content, Article.create_at, Article.updated_at, User.full_name) .join(User, User.id == Article.uploader) .filter(Article.id == article_info['article_id'], Article.board_id == article_info['board_id'], Article.is_deleted == False) .one()) article_detail = { 'title': article_detail[0], 'content': article_detail[1], 'author': article_detail[4], 'created_at': article_detail[2], 'updated_at': article_detail[3], } return jsonify({'boards': article_detail}), 200 except Exception as e: print(e) return jsonify({'message': e}), 500 finally: try: session.close() except Exception as e: print(e) return jsonify({'message': 'SESSION_CLOSE_ERROR'}), 500
def get_event_types(): """ 기획전 타입 표출 엔드포인트 기획전 타입 표출 엔드포인트 입니다. 기획전 등록페이지에서 기획전 타입 목록을 표출할때 사용됩니다. Returns: 200: 기획전 타입 목록 500: DB_CURSOR_ERROR, INVALID_KEY, NO_DATABASE_CONNECTION Authors: [email protected] (이종민) History: 2020-04-09 ([email protected]): 초기 생성 """ try: db_connection = get_db_connection() if db_connection: event_service = EventService() types = event_service.get_event_types(db_connection) return types else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def insert_new_product(*args): """ 상품 등록 엔드포인트 새로운 상품을 등록하는 엔드포인트. 등록하려는 셀러의 정보에 따라 내부 내용이 달라지므로, 데코레이터에서 셀러 정보를 먼저 읽어옴. 등록 상세 정보는 form 에 존재함. 유효성 검사를 위한 조건 통과 후 product_info 변수에 내용을 담아 product_service 로 전달. Args: *args: 등록할 제품의 상세 정보 g.account_info: 데코레이터에서 넘겨받은 수정을 수행하는 계정 정보 auth_type_id: 계정의 권한정보 account_no: 데코레이터에서 확인된 계정번호 Returns: Http 응답코드 200: 신규 상품 등록 성공 500: 데이터베이스 에러 Authors: [email protected] (이소헌) History: 2020-04-06 ([email protected]): 초기 생성 2020-04-14 ([email protected]): 이미지 순서 문제 캐치 2020-04-15 ([email protected]): form data 형태로 받을 수 있도록 tags 자료형 변경 (str -> list) """ image_uploader = ImageUpload() uploaded_images = image_uploader.upload_product_image(request) if (400 in uploaded_images) or (500 in uploaded_images): return uploaded_images # 상품 등록시 대표 사진인 1번 사진부터 들어와야함 if not uploaded_images['image_file_1']: return jsonify({'message': 'REPRESENTATIVE_IMAGE_DOES_NOT_EXIST'}), 400 # 1번 사진부터 순서대로 들어와야함 for i in range(2, 6): if uploaded_images[f'image_file_{i}']: if not uploaded_images[f'image_file_{i-1}']: return jsonify({'message': 'IMAGES_SHOULD_BE_IN_ORDER'}), 400 product_info = { 'auth_type_id': g.account_info['auth_type_id'], 'account_no': g.account_info['account_no'], 'uploader': g.account_info['account_no'], 'modifier': g.account_info['account_no'], 'is_available': args[0], 'is_on_display': args[1], 'first_category_id': args[2], 'second_category_id': args[3], 'name': args[4], 'short_description': args[5], 'color_filter_id': args[6], 'style_filter_id': args[7], 'long_description': args[8], 'youtube_url': args[9], 'stock': args[10], 'price': args[11], 'discount_rate': args[12] / 100, 'discount_start_time': str( datetime.strptime(args[13][:args[13].index('G') - 1], "%a %b %d %Y %H:%M:%S")), 'discount_end_time': str( datetime.strptime(args[14][:args[14].index('G') - 1], "%a %b %d %Y %H:%M:%S")), 'min_unit': args[15], 'max_unit': args[16], 'tags': args[17], 'selected_account_no': args[18], 'images': uploaded_images, } print(product_info) try: db_connection = get_db_connection() if db_connection: product_service = ProductService() product_insert_result = product_service.insert_new_product( product_info, db_connection) return product_insert_result else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def change_password(*args): """ 계정 비밀번호 변경 엔드포인트 계정 비밀번호 변경 엔드포인트 입니다. 계정이 가진 권한에 따라 지정된 인자를 받아 비밀번호를 변경합니다. url 에 비밀번호를 바꿔야할 계정 번호를 받습니다. Args: *args: 유효성 검사를 통과한 파라미터 url parameter: parameter_account_no: 비밀번호가 바뀌어야할 계정 번호 g.account_info: 데코레이터에서 넘겨받은 계정 정보(비밀번호 변경을 수행하려는 계정) auth_type_id: 계정의 권한정보 account_no: 계정번호 request.body: request 로 전달 받은 정보 original_password: 기존 비밀번호(비밀번호 변경을 수행하는자가 셀러 권한일 경우에만 전달 받음) new_password: 변경하려는 새로운 비밀번호 Returns: http 응답코드 200: SUCCESS 비밀번호 변경 완료 400: VALIDATION_ERROR, INVALID_AUTH_TYPE_ID, NO_ORIGINAL_PASSWORD TOO_SHORT_PASSWORD, INVALID_PARAMETER_ACCOUNT_NO 401: INVALID_PASSWORD 403: NO_AUTHORIZATION 500: DB_CURSOR_ERROR, NO_DATABASE_CONNECTION Authors: [email protected] (이종민) History: 2020-03-31 ([email protected]): 초기 생성 2020-04-02 ([email protected]): 파라미터 validation 추가, 데코레이터 적용 2020-04-06 ([email protected]): url path 변경('/<int:parameter_account_no>' -> '/<int:parameter_account_no>/password') 2020-04-12 ([email protected]): 리팩토링 - 주석 수정 : 비밀번호 변경을 수행하려는 주체에 대해 명확히 명시 - 변경할 비밀번호 길이 제한 추가(4글자 이상) - 전달 인자 명칭을 명확히 하기 위해 변경(account_info -> change_info) """ # validation 확인이 된 data 를 change_info 로 재정의 change_info = { 'parameter_account_no': args[0], 'original_password': args[1], 'new_password': args[2], 'auth_type_id': g.account_info['auth_type_id'], 'decorator_account_no': g.account_info['account_no'] } # 셀러 권한일 때 original_password 가 없으면 에러반환 if change_info['auth_type_id'] == 2: if change_info['original_password'] is None: return jsonify({"message": "NO_ORIGINAL_PASSWORD"}), 400 # 변경할 비밀번호 길이가 4글자 미만이면 에러 반환 if len(change_info['new_password']) < 4: return jsonify({'message': 'TOO_SHORT_PASSWORD'}), 400 try: db_connection = get_db_connection() if db_connection: seller_service = SellerService() changing_password_result = seller_service.change_password( change_info, db_connection) return changing_password_result else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def sign_up(*args): """ 계정 회원가입 엔드포인트 회원가입 엔드포인트 입니다. request.body 로 회원가입에 필요한 정보를 받고, 유효성 검사를 마친 정보를 account_info 에 담아 service 에 전달합니다. Args: *args: 유효성 검사를 통과한 파라미터 request.body: login_id 로그인 아이디 str password 비밀번호 str contact_number 담당자 번호 str seller_type_id 셀러 속성 아이디 int name_kr 셀러명 str name_en 셀러 영문명 str center_number 고객센터 번호 str site_url 사이트 URL str kakao_id 카카오 아이디 str required=False insta_id 인스타 아이디 str required=False Returns: http 응답코드 200: SUCCESS 셀러 회원가입 완료 400: EXISTING_LOGIN_ID, EXISTING_NAME_KR, EXISTING_NAME_EN, INVALID_KEY 500: NO_DATABASE_CONNECTION Authors: [email protected] (이종민) History: 2020-04-06 ([email protected]): 초기 생성 2020-04-07 ([email protected]): 'center_number'의 중간부분 유효성검사 허용 범위를 4글자->3~4글자로 변경 """ # validation 확인이 된 data 를 account_info 로 재정의 account_info = { 'login_id': args[0], 'password': args[1], 'contact_number': args[3], 'seller_type_id': args[4], 'name_kr': args[5], 'name_en': args[6], 'center_number': args[7], 'site_url': args[8], 'kakao_id': args[10], 'insta_id': args[11] } # 데이터베이스 연결 try: db_connection = get_db_connection() if db_connection: seller_service = SellerService() sign_up_result = seller_service.sign_up( account_info, db_connection) return sign_up_result else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def change_seller_info(*args): """ 계정 셀러정보 수정 엔드포인트 셀러정보를 수정하는 엔드포인트 입니다. url 로 셀러정보를 수정하고 싶은 계정 번호를 받습니다. 셀러정보 수정을 수행하려는 계정의 정보를 데코레이터로부터 받습니다. 수정하려는 내용은 form 으로 받습니다. 받은 정보를 유효성 검사를 거친 후 account_info 로 저장해 service 로 넘겨줍니다. Args: *args: 유효성 검사를 통과한 파라미터 url parameter: parameter_account_no: 저장할 셀러정보의 계정 번호 g.account_info: 데코레이터에서 넘겨받은 수정을 수행하는 계정 정보 auth_type_id: 계정의 권한정보 account_no: 데코레이터에서 확인된 계정번호 form: seller_status_no 셀러 상태번호 int seller_type_no 셀러 속성번호 int name_kr 셀러 한글명 str 한글,영문,숫자 name_en 셀러 영문명 str required False 영문 소문자 brandi_app_user_app_id 브랜디앱 유저 아이디 str ceo_name 대표자명 str company_name 사업자명 str business_number 사업자번호 str 12자리 online_business_number 통신판매업번호 str short_description 셀러 한줄 소개 str long_description 셀러 상세 소개 str required False 10글자 이상 site_url 사이트 URL str manager_info: 담당자 정보 list [ { name 담당자명 str contact_number 담당자 핸드폰번호 str email 담당자 이메일 str } ] insta_id 인스타그램 아이디 str center_number 고객센터 전화번호 str kakao_id 카카오톡 아이디 str required False yellow_id 옐로우 아이디 str required False zip_code 우편번호 str address 주소 int detail_address 상세주소 str weekday_start_time 고객센터 운영 시작시간(주중) str weekday_end_time 고객센터 운영 종료시간(주중) str weekend_start_time 고객센터 운영 시작시간(주말) str required False weekend_end_time 고객센터 운영 종료시간(주말) str required False bank_name 정산은행 str bank_holder_name 계좌주 str account_number 계좌번호 str previous_seller_status_no 이전 셀러정보의 상태번호 int (상태변경이력 체크용) Returns: http 응답코드 200: SUCCESS 셀러정보 수정(새로운 이력 생성) 완료 400: INVALID_APP_ID (존재하지 않는 브랜디 앱 아이디 입력) 400: VALIDATION_ERROR_MANAGER_INFO, NO_SPECIFIC_MANAGER_INFO, INVALID_AUTH_TYPE_ID, NO_PROFILE_IMAGE, NO_CERTIFICATE_IMAGE NO_CHANGEABLE_STATUS, EXISTING_NAME_KR, EXISTING_NAME_EN 403: NO_AUTHORIZATION, NO_AUTHORIZATION_FOR_STATUS_CHANGE, NO_ONLINE_BUSINESS_IMAGE 500: INVALID_KEY, DB_CURSOR_ERROR, NO_DATABASE_CONNECTION Authors: [email protected] (이종민) [email protected] (윤희철) History: 2020-04-03 ([email protected]): 초기 생성 2020-04-04 ([email protected]): 이전 셀러 정보번호, 이전 셀러 정보 상태정보, 셀러 계정번호 추가 2020-04-06 ([email protected]): url path 변경('/<int:parameter_account_no>/info' -> '/<int:parameter_account_no>') 2020-04-08 ([email protected]): 마스터가 아닐 때 셀러 상태(입점 등)를 변경하려고 하면 에러 처리하는 내용 추가 2020-04-09 ([email protected]): 이미지 업로더 적용. 2020-04-09 ([email protected]): 이미지 파일을 새로 업로드하면, 이 파일을 저장한 s3 url 을 저장하고, 수정을 안해서 기존에 DB에 저장된 url 을 보내주면, 해당 url 을 저장함 필수값인 셀러 프로필, 등록증 2개가 들어오지 않으면 에러처리 2020-04-12 ([email protected]): 셀러용 이미지 업로더를 사용하는 것에서 공통 업로더를 사용하도록 변경 """ # manager_infos 유효성 확인을 확인하기 위해 따로 저장 manager_info_list = json.loads(args[16]) # manger_infos 리스트를 돌면서 각각의 유효성을 충족하는지 체크 for info in manager_info_list: name_validation = r'^[가-힣a-zA-Z0-9\ ]{1,45}$' contact_number_validation = r'^[0-9-]{1,14}$' email_validation = r'^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$' ranking_validation = r'^[1-3]{1}$' # 각 키가 들어왔는지 먼저 확인 if (info.get('name', None) and info.get('contact_number', None) and info.get('email', None) and info.get('ranking', None)): # 키가 모두 들어왔으면, 유효성을 만족하는지 확인 if (re.match(name_validation, info['name']) and re.match( contact_number_validation, info['contact_number']) and re.match(email_validation, info['email']) and re.match(ranking_validation, str(info['ranking']))): pass # 유효성을 만족시키지 못하면 에러 반환 else: return jsonify( {"message": "VALIDATION_ERROR_MANAGER_INFO"}), 400 # 키가 안들어오면 에러 반환 else: return jsonify({"message": "NO_SPECIFIC_MANAGER_INFO"}), 400 # 이미지 업로드 함수를 호출해서 이미지를 업로드하고 url 을 딕셔너리로 가져옴. image_upload = ImageUpload() seller_image = image_upload.upload_images(request) if (400 in seller_image) or (500 in seller_image): return seller_image # validation 확인이 된 data 를 account_info 로 재정의 account_info = { 'auth_type_id': g.account_info['auth_type_id'], 'decorator_account_no': g.account_info['account_no'], 'parameter_account_no': args[0], 'profile_image_url': seller_image.get('seller_profile_image', None), 'seller_status_no': args[1], 'seller_type_no': args[2], 'name_kr': args[3], 'name_en': args[4], 'brandi_app_user_app_id': args[6], 'ceo_name': args[7], 'company_name': args[8], 'business_number': args[9], 'certificate_image_url': seller_image.get('certificate_image', None), 'online_business_number': args[10], 'online_business_image_url': seller_image.get('online_business_image', None), 'background_image_url': seller_image.get('background_image', None), 'short_description': args[11], 'long_description': args[12], 'site_url': args[14], 'manager_infos': manager_info_list, 'insta_id': args[17], 'center_number': args[18], 'kakao_id': args[19], 'yellow_id': args[20], 'zip_code': args[21], 'address': args[22], 'detail_address': args[23], 'weekday_start_time': args[24], 'weekday_end_time': args[25], 'weekend_start_time': args[26], 'weekend_end_time': args[27], 'bank_name': args[28], 'bank_holder_name': args[29], 'account_number': args[30], } # file 로 이미지가 안들어올 경우, FORM 으로 받은 이미지 url 로 대체 if not account_info['profile_image_url']: account_info['profile_image_url'] = args[33] if not account_info['certificate_image_url']: account_info['certificate_image_url'] = args[34] if not account_info['online_business_image_url']: account_info['online_business_image_url'] = args[35] if not account_info['background_image_url']: account_info['background_image_url'] = args[36] # 이미지 url 필수값 3개가 안들어오면 에러 리턴 if not account_info['profile_image_url']: return jsonify({'message': 'NO_PROFILE_IMAGE'}), 400 if not account_info['certificate_image_url']: return jsonify({'message': 'NO_CERTIFICATE_IMAGE'}), 400 if not account_info['online_business_image_url']: return jsonify({'message': 'NO_ONLINE_BUSINESS_IMAGE'}), 400 # 데이터베이스 연결 try: db_connection = get_db_connection() if db_connection: seller_service = SellerService() changing_seller_info_result = seller_service.change_seller_info( account_info, db_connection) return changing_seller_info_result else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def change_event_infos(*args): """ 기획전 정보 수정 엔드포인트 기획전 정보 수정 엔드포인트 입니다. form 과 url parameter 로 등록 정보를 받고, 유효성을 확인합니다. 기획전 전 타입 공통 필수 파라미터는 먼저 확인하고, 각 타입별 필수 파라미터는 function 내에서 확인합니다. 확인이 끝나면 event_info 에 모든 파라미터를 저장합니다. 등록을 수행하는 계정의 정보를 데코레이터에서 받아와 event_info 에 저장합니다. function 진입 후 마스터 권한이 없으면 에러를 리턴하고, 마스터 권한이면 서비스로 값을 넘깁니다. Args: *args: 유효성 검사를 통과한 파라미터 request.form: event_no: 기획전 번호 event_type_id 기획전 타입 외래키 event_sort_id 기획전 종류 외래키 is_on_main 메인 노출여부 is_on_event 기획전 진열여부 name 기획전명 event_start_time 기획전 시작시간 (ex) 2020-04-10 23:59 event_end_time 기획전 종료시간 short_description 기획전 간략설명 long_description 기획전 상세설명 banner_image_url 배너 이미지 url detail_image_url 상세 이미지 url button_name 이벤트 버튼 이름 button_link_type_id 이벤트 버튼 링크타입 외래키 button_link_description 이벤트 버튼링크 내용 product 연결 상품 정보 youtube_url 유튜브 url g.account_info: 데코레이터에서 넘겨받은 수정을 수행하는 계정 정보 auth_type_id: 계정의 권한정보 account_no: 데코레이터에서 확인된 계정번호 Returns: http 응답코드 200: SUCCESS 수정(새로운 이력 생성) 완료 400: NOT_ALLOWED_TO_CHANGE_EVENT_TYPE_OR_SORT, INVALID_EVENT_NO NO_SHORT_DESCRIPTION, NO_BANNER_IMAGE, NO_DETAIL_IMAGE, INVALID_EVENT_SORT, NO_YOUTUBE_URL, NO_BUTTON_NAME, NO_BUTTON_LINK_DESCRIPTION 500: DB_CURSOR_ERROR, INVALID_KEY, NO_DATABASE_CONNECTION Authors: [email protected] (이종민) [email protected] (윤희철) History: 2020-04-10 ([email protected]): 초기 생성 2020-04-11 ([email protected]): - utils.py(이미지 업로더) 에서 나오는 결과값에 애러코드 400이있으면 애러메세지를 그대로 리턴하는 코드 추가 - 기획전 상품이 validation 을 통과하면 json loads 를 통해서 array 자료형으로 파싱하는 코드 추가. - 기획전 상품이 들어오면 따로 변수처리해서 service 로 넘기는 코드 추가 - 데이터베이스 커넥션을 호출 할 때 try/except 방식 추가 2020-04-12 ([email protected]): - 기획전용 이미지 업로더를 사용하는 것에서 공통 업로더를 사용하도록 변경 - 기획전 상품 정보를 json loads 로 파싱하는 과정을 try/except 방식에서 if 문 방식으로 변경 - 기획전 타입이 상품(텍스트), 유튜브 일 경우 기획전 종류 유효성 확인 추가 2020-04-15 ([email protected]: - button_link_type_id 를 str 로 받던 것에서 int 로 받기로 변경 """ # 마스터 권한이 아니면 반려 if g.account_info['auth_type_id'] != 1: return jsonify({'message': 'NO_AUTHORIZATION'}), 403 # 이미지 업로드 함수를 호출해서 이미지를 업로드하고 url 을 딕셔너리로 가져옴. image_upload = ImageUpload() event_image = image_upload.upload_images(request) # 함수의 실행결과에 400이 포함된 경우 애러메세지를 그대로 리턴함. if (400 in event_image) or (500 in event_image): return event_image # validation(형식) 확인된 데이터 저장 event_info = { 'event_no': args[0], 'event_type_id': args[1], 'event_sort_id': args[2], 'is_on_main': args[3], 'is_on_event': args[4], 'name': args[5], 'event_start_time': args[6], 'event_end_time': args[7], 'short_description': args[8], 'long_description': args[9], 'banner_image_url': event_image.get('banner_image', None), 'detail_image_url': event_image.get('detail_image', None), 'button_name': args[14], 'button_link_type_id': args[15], 'button_link_description': args[16], 'youtube_url': args[18], 'auth_type_id': g.account_info['auth_type_id'], 'account_no': g.account_info['account_no'] } # file 로 이미지가 안들어올 경우, FORM 으로 받은 이미지 url 로 대체 if not event_info['banner_image_url']: event_info['banner_image_url'] = args[10] if not event_info['detail_image_url']: event_info['detail_image_url'] = args[12] # 딕셔너리를 품은 리스트인 product 정보를 따로 저장 (dao 에서 에러를 막기 위해) event_product_info = args[17] # form 데이터로 값을 받으면 str 처리가 되기 때문에 json.loads 로 읽을 수 있게 파싱 if event_product_info: event_product_info = json.loads(event_product_info) # 기획전 기간 밸리데이션 now = datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M') # 시작시간이 현재 시간보다 전이거나 시작시간이 종료시간보다 늦으면 에러 반환 if event_info['event_start_time'] < now or event_info[ 'event_start_time'] > event_info['event_end_time']: return jsonify({'message': 'INVALID_EVENT_TIME'}), 400 # 기획전 타입이 이벤트일 경우 필수값과 기획전 종류 범위 확인 if event_info['event_type_id'] == 1: if not event_info['short_description']: return jsonify({'message': 'NO_SHORT_DESCRIPTION'}), 400 if not event_info['banner_image_url']: return jsonify({'message': 'NO_BANNER_IMAGE'}), 400 if not event_info['detail_image_url']: return jsonify({'message': 'NO_DETAIL_IMAGE'}), 400 # 기획전 종류 범위 확인 if event_info['event_sort_id'] not in range(1, 3): return jsonify({'message': 'INVALID_EVENT_SORT'}), 400 # 기획전 타입이 쿠폰일 경우 필수값 확인 if event_info['event_type_id'] == 2: if not event_info['short_description']: return jsonify({'message': 'NO_SHORT_DESCRIPTION'}), 400 # 기획전 종류 범위 확인 if event_info['event_sort_id'] not in range(3, 9): return jsonify({'message': 'INVALID_EVENT_SORT'}), 400 # 기획전 타입이 상품(이미지)일 경우 필수값과 기획전 종류 범위 확인 if event_info['event_type_id'] == 3: if not event_info['banner_image_url']: return jsonify({'message': 'NO_BANNER_IMAGE'}), 400 if not event_info['detail_image_url']: return jsonify({'message': 'NO_DETAIL_IMAGE'}), 400 # 기획전 종류 범위 확인 if event_info['event_sort_id'] not in range(9, 11): return jsonify({'message': 'INVALID_EVENT_SORT'}), 400 # 기획전 타입이 상품(텍스트)일 경우 필수값과 기획전 종류 범위 확인 if event_info['event_type_id'] == 4: if not event_info['short_description']: return jsonify({'message': 'NO_SHORT_DESCRIPTION'}), 400 if not event_info['banner_image_url']: return jsonify({'message': 'NO_BANNER_IMAGE'}), 400 # 기획전 종류 범위 확인 if event_info['event_sort_id'] not in range(11, 13): return jsonify({'message': 'INVALID_EVENT_SORT'}), 400 # 기획전 타입이 유튜브일 경우 필수값 확인과 기획전 종류 범위 확인 if event_info['event_type_id'] == 5: if not event_info['short_description']: return jsonify({'message': 'NO_SHORT_DESCRIPTION'}), 400 if not event_info['banner_image_url']: return jsonify({'message': 'NO_BANNER_IMAGE'}), 400 if not event_info['youtube_url']: return jsonify({'message': 'NO_YOUTUBE_URL'}), 400 # 기획전 종류 범위 확인 if event_info['event_sort_id'] not in range(13, 15): return jsonify({'message': 'INVALID_EVENT_SORT'}), 400 # 입력 인자 관계에 따른 필수값 확인 if event_info['button_link_type_id']: if not event_info['button_name']: return jsonify({'message': 'NO_BUTTON_NAME'}), 400 if event_info['button_link_type_id'] in range(4, 7): if not event_info['button_link_description']: return jsonify({'message': 'NO_BUTTON_LINK_DESCRIPTION'}), 400 try: db_connection = get_db_connection() if db_connection: event_service = EventService() info = event_service.change_event_infos( event_info, event_product_info, db_connection) return info else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def get_seller_info(*args): """ 계정 셀러정보 표출 엔드포인트 셀러정보를 표출하는 엔드포인트 입니다. url 로 셀러정보를 확인하고 싶은 계정 번호를 받습니다. 셀러정보를 열람을 수행하려는 계정의 번호를 데코레이터로부터 받습니다. 열람 대상 셀러정보의 계정의 번호를 url parameter 로 받습니다. 받은 정보를 유효성 검사를 거친 후 account_info 로 저장해 service 로 넘겨줍니다. Args: *args: 유효성 검사를 통과한 파라미터 url parameter: parameter_account_no: 열람하고자 하는 셀러정보의 계정 번호 g.account_info: 데코레이터에서 넘겨받은(셀러정보를 열람을 수행하려는) 계정 정보 auth_type_id: 계정의 권한정보 account_no: 데코레이터에서 확인된 계정번호 Returns: http 응답코드 200: SUCCESS 셀러정보 겟 완료 400: INVALID_ACCOUNT_NO, INVALID_AUTH_TYPE_ID 403: NO_AUTHORIZATION 500: NO_DATABASE_CONNECTION, DB_CURSOR_ERROR, INVALID_KEY Authors: [email protected] (이종민) History: 2020-04-01 ([email protected]): 초기 생성 2020-04-02 ([email protected]): 파라미터 validation 추가, 데코레이터 적용 2020-04-03 ([email protected]): 주석 수정(메인문구, url parameter 수정) 2020-04-06 ([email protected]): url path 변경('/<int:parameter_account_no>/info' -> '/<int:parameter_account_no>') """ # validation 확인이 된 data 를 account_info 로 재정의 account_info = { 'parameter_account_no': args[0], 'auth_type_id': g.account_info['auth_type_id'], 'decorator_account_no': g.account_info['account_no'], } db_connection = get_db_connection() try: if db_connection: seller_service = SellerService() getting_seller_info_result = seller_service.get_seller_info( account_info, db_connection) return getting_seller_info_result else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def update_product_info(*args): """ 상품 정보 수정 엔드포인트 상품의 정보를 수정하는 엔드포인트. 등록하려는 셀러의 정보에 따라 내부 내용이 달라지므로, 데코레이터에서 셀러 정보를 먼저 읽어옴. 수정 상세 정보는 form 에 존재함. 유효성 검사를 위한 조건 통과 후 product_info 변수에 내용을 담아 product_service로 전달. Args: *args: 등록할 제품의 상세 정보 g.account_info: 데코레이터에서 넘겨받은 수정을 수행하는 계정 정보 auth_type_id: 계정의 권한정보 account_no: 데코레이터에서 확인된 계정번호 Returns: Http 응답코드 200: 상품 정보 수정 성공 500: 데이터베이스 에러 Authors: [email protected] (이소헌) History: 2020-04-08 ([email protected]): 초기 생성 """ image_uploader = ImageUpload() uploaded_images = image_uploader.upload_product_image(request) # 이미지 업로더를 호출한 결과값에 애러코드 400이 포함되어있으면 utils.py 에서 발생한 에러메세지를 그대로 리턴 if (400 in uploaded_images) or (500 in uploaded_images): return uploaded_images product_info = { 'auth_type_id': g.account_info['auth_type_id'], 'token_account_no': g.account_info['account_no'], 'modifier': g.account_info['account_no'], 'is_available': args[0], 'is_on_display': args[1], 'product_sort_id': args[2], 'first_category_id': args[3], 'second_category_id': args[4], 'name': args[5], 'short_description': args[6], 'color_filter_id': args[7], 'style_filter_id': args[8], 'long_description': args[9], 'youtube_url': args[10], 'stock': args[11], 'price': args[12], 'discount_rate': args[13] / 100, 'discount_start_time': args[14], 'discount_end_time': args[15], 'min_unit': args[16], 'max_unit': args[17], 'tags': json.loads(args[18]), 'product_id': args[19], 'seller_account_id': args[20], 'images': uploaded_images, } try: db_connection = get_db_connection() if db_connection: product_service = ProductService() product_update_result = product_service.update_product_info( product_info, db_connection) return product_update_result else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def get_product_list(*args): """ 상품 리스트 표출 엔드포인트 상품 관리 페이지에서 표출되는 필터링된 상품 리스트를 표출합니다. 쿼리 파라미터로 필터링에 사용할 파라미터 값을 받습니다. Returns: 200: 상품 리스트 403: NO_AUTHORIZATION 500: NO_DATABASE_CONNECTION, DB_CURSOR_ERROR NO_DATABASE_CONNECTION Authors: [email protected] (김승준) [email protected] (이종민) History: 2020-04-09 ([email protected]): 초기 생성 2020-04-13 ([email protected]): 수정 - 주석 내용 보완 - 쿼리파라미터 유효성 검사 추가 - 마스터 권한이 아니면 접근 불가 처리(NO_AUTHORIZATION) - db connection try/except 추가 - 셀러속성 쿼리 값을 리스트 형태로 받도록 변경 """ # 마스터 권한이 아니면 에러 반환 if g.account_info['auth_type_id'] != 1: return jsonify({'message': 'NO_AUTHORIZATION'}), 403 # 유효성 확인 위해 기간 데이터 먼저 정의 period_start, period_end = args[0], args[1] # 두 값이 모두 들어왔을 때, 시작 기간이 종료 기간보다 늦으면 시작기간 = 종료기간 if period_start and period_end: if period_end < period_start: period_start = period_end # 두 값이 각각 안들어왔을 경우 default 값 설정 if not period_start: period_start = '2016-07-01' if not period_end: period_end = '2037-12-31' # seller_type_id 보정(아이디가 하나만 들어올 경우 튜플로 만들 때 오류가 생겨서 보정) seller_type_id = args[5] if seller_type_id: seller_type_id.append(0) # 유효성 검사를 통과한 쿼리 값을 filter_info 에 저장 filter_info = { # '2020-04-14' 형식으로 들어오는 기간 데이터 변환 'period_start': period_start + ' 00:00:00', 'period_end': period_end + ' 23:59:59', 'seller_name': args[2], 'product_name': args[3], 'product_number': args[4], 'seller_type_id': seller_type_id, 'is_available': args[6], 'is_on_display': args[7], 'is_on_discount': args[8], 'offset': args[9], 'limit': args[10] } # offset 과 limit 에 음수가 들어오면 default 값 지정 if filter_info['offset'] < 0: filter_info['offset'] = 0 if filter_info['limit'] < 0: filter_info['limit'] = 10 try: db_connection = get_db_connection() if db_connection: product_service = ProductService() product_list_result = product_service.get_product_list( filter_info, db_connection) return product_list_result else: return jsonify({'message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500
def register_event_info(*args): """ 기획전 등록 엔드포인트 기획전을 신규 등록하는 엔드포인트 입니다. request.body 로 등록 정보를 받고, 유효성을 확인합니다. 기획전 전 타입 공통 필수 파라미터는 먼저 확인하고, 각 타입별 필수 파라미터는 function 내에서 확인합니다. 확인이 끝나면 event_info 에 모든 파라미터를 저장합니다. 등록을 수행하는 계정의 정보를 데코레이터에서 받아와 event_info 에 저장합니다. function 진입 후 마스터 권한이 없으면 에러를 리턴하고, 마스터 권한이면 서비스로 값을 넘깁니다. Args: *args: 유효성 검사를 통과한 파라미터 request.body: event_type_id 기획전 타입 외래키 event_sort_id 기획전 종류 외래키 is_on_main 메인 노출여부 is_on_event 기획전 진열여부 name 기획전명 event_start_time 기획전 시작시간 (ex) 2020-04-10 23:59 event_end_time 기획전 종료시간 short_description 기획전 간략설명 long_description 기획전 상세설명 banner_image_url 배너 이미지 url detail_image_url 상세 이미지 url button_name 이벤트 버튼 이름 button_link_type_id 이벤트 버튼 링크타입 외래키 button_link_description 이벤트 버튼링크 내용 product_order 상품 진열 순서 product_id 상품 외래키 youtube_url 유튜브 url Returns: http 응답코드 200: SUCCESS 기획전 신규 등록 완료 400: NO_SHORT_DESCRIPTION, BANNER_IMAGE_URL, NO_DETAIL_IMAGE_URL, NO_BUTTON_NAME, NO_BUTTON_LINK_DESCRIPTION, INVALID_EVENT_SORT 403: NO_AUTHORIZATION 500: NO_DATABASE_CONNECTION Authors: [email protected] (이종민) [email protected] (윤희철) History: 2020-04-07 ([email protected]): 초기생성 / 이벤트 기획전 부분 작성 2020-04-08 ([email protected]): 기획전 기간 밸리데이션 추가 2020-04-10 ([email protected]): - 상품(이미지), 상품(텍스트), 유튜브 기획전 작성 - request form 형태로 오는 매니저 정보 list 를 parsing 해서 사용하는 로직 추가 - 데이터베이스 커넥션을 호출 할 때 try/except 방식으로 변경 2020-04-12 ([email protected]): - event_type_id 를 int 로 받아오도록 validator 변경 - 기획전용 이미지 업로더를 사용하는 것에서 공통 업로더를 사용하도록 변경 - 기획전 상품 정보를 json loads로 파싱하는 과정을 try/except 방식에서 if 문 방식으로 변경 """ if g.account_info['auth_type_id'] != 1: return jsonify({'message': 'NO_AUTHORIZATION'}), 403 # 이미지 업로드 함수를 호출해서 이미지를 업로드하고 url 을 딕셔너리로 가져옴. image_upload = ImageUpload() event_image = image_upload.upload_images(request) # 함수의 실행결과에 400이 포함된 경우 애러메세지를 그대로 리턴함. if (400 in event_image) or (500 in event_image): return event_image # validation(형식) 확인된 데이터 저장 event_info = { 'event_type_id': args[0], 'event_sort_id': args[1], 'is_on_main': args[2], 'is_on_event': args[3], 'name': args[4], 'event_start_time': args[5], 'event_end_time': args[6], 'short_description': args[7], 'long_description': args[8], 'banner_image_url': event_image.get('banner_image', None), 'detail_image_url': event_image.get('detail_image', None), 'button_name': args[13], 'button_link_type_id': args[14], 'button_link_description': args[15], 'youtube_url': args[17], 'auth_type_id': g.account_info['auth_type_id'], 'account_no': g.account_info['account_no'] } # file 로 이미지가 안들어올 경우, FORM 으로 받은 이미지 url 로 대체 if not event_info['banner_image_url']: event_info['banner_image_url'] = args[10] if not event_info['detail_image_url']: event_info['detail_image_url'] = args[12] # 딕셔너리를 품은 리스트인 product 정보를 따로 저장 (dao 에서 에러를 막기 위해) event_product_info = args[16] # form 데이터로 값을 받으면 str 처리가 되기 때문에 json.loads 로 읽을 수 있게 파싱 if event_product_info: event_product_info = json.loads(event_product_info) # 기획전 기간 밸리데이션 now = datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M') # 시작시간이 현재 시간보다 전이거나 시작시간이 종료시간보다 늦으면 에러 반환 if event_info['event_start_time'] < now or event_info[ 'event_start_time'] > event_info['event_end_time']: return jsonify({'message': 'INVALID_EVENT_TIME'}), 400 # 기획전 타입이 이벤트일 경우 필수값과 기획전 종류 범위 확인 if event_info['event_type_id'] == 1: if not event_info['short_description']: return jsonify({'message': 'NO_SHORT_DESCRIPTION'}), 400 if not event_info['banner_image_url']: return jsonify({'message': 'NO_BANNER_IMAGE'}), 400 if not event_info['detail_image_url']: return jsonify({'message': 'NO_DETAIL_IMAGE'}), 400 # 기획전 종류 범위 확인 if event_info['event_sort_id'] not in range(1, 3): return jsonify({'message': 'INVALID_EVENT_SORT'}), 400 # 기획전 타입이 쿠폰일 경우 필수값 확인 if event_info['event_type_id'] == 2: if not event_info['short_description']: return jsonify({'message': 'NO_SHORT_DESCRIPTION'}), 400 # 기획전 종류 범위 확인 if event_info['event_sort_id'] not in range(3, 9): return jsonify({'message': 'INVALID_EVENT_SORT'}), 400 # 기획전 타입이 상품(이미지)일 경우 필수값과 기획전 종류 범위 확인 if event_info['event_type_id'] == 3: if not event_info['banner_image_url']: return jsonify({'message': 'NO_BANNER_IMAGE'}), 400 if not event_info['detail_image_url']: return jsonify({'message': 'NO_DETAIL_IMAGE'}), 400 # 기획전 종류 범위 확인 if event_info['event_sort_id'] not in range(9, 11): return jsonify({'message': 'INVALID_EVENT_SORT'}), 400 # 기획전 타입이 상품(텍스트)일 경우 필수값과 기획전 종류 범위 확인 if event_info['event_type_id'] == 4: if not event_info['short_description']: return jsonify({'message': 'NO_SHORT_DESCRIPTION'}), 400 if not event_info['banner_image_url']: return jsonify({'message': 'NO_BANNER_IMAGE'}), 400 # 기획전 종류 범위 확인 if event_info['event_sort_id'] not in range(11, 13): return jsonify({'message': 'INVALID_EVENT_SORT'}), 400 # 기획전 타입이 유튜브일 경우 필수값 확인과 기획전 종류 범위 확인 if event_info['event_type_id'] == 5: if not event_info['short_description']: return jsonify({'message': 'NO_SHORT_DESCRIPTION'}), 400 if not event_info['banner_image_url']: return jsonify({'message': 'NO_BANNER_IMAGE'}), 400 if not event_info['youtube_url']: return jsonify({'message': 'NO_YOUTUBE_URL'}), 400 # 기획전 종류 범위 확인 if event_info['event_sort_id'] not in range(13, 15): return jsonify({'message': 'INVALID_EVENT_SORT'}), 400 # 입력 인자 관계에 따른 필수값 확인 if event_info['button_link_type_id']: # button_link_type_id 가 있을 때 button_name 은 무조건 있어야 함 if not event_info['button_name']: return jsonify({'message': 'NO_BUTTON_NAME'}), 400 if event_info['button_link_type_id'] in range(4, 7): # button_link_type_id가 4~6이면 description 이 있어야 함 if not event_info['button_link_description']: return jsonify({'message': 'NO_BUTTON_LINK_DESCRIPTION'}), 400 try: # 데이터베이스 연결 db_connection = get_db_connection() if db_connection: event_service = EventService() registering_event_result = event_service.register_event( event_info, db_connection, event_product_info) return registering_event_result else: return jsonify({'view_message': 'NO_DATABASE_CONNECTION'}), 500 except Exception as e: return jsonify({'message': f'{e}'}), 500 finally: try: db_connection.close() except Exception as e: return jsonify({'message': f'{e}'}), 500