class ProductSearchView(MethodView):
    def __init__(self, service, database):
        self.service = service
        self.database = database

    @validate_params(
            Param('q', GET, str, required=True),
            Param('limit', GET, str, required=True, rules=[NumberRule()]),
            Param('sort_type', GET, str, required=True, rules=[SortTypeRule()])
            )
    def get(self, *args):
        """ GET 메소드: 상품 검색 

        사용자가 입력한 검색 키워드로 해당하는 상품이름,
        셀러이름을 조회해서반환해준다.

        Args:
            search   : 검색키워드
            limit    : 표시할 상품 개수
            sort_type: 정렬 종류(최신순, 판매순, 추천순)

        Author: 김기용

        Returns:
            200, {'message': 'success', 'result': 상품정보들}   
        
        Raises:
            400, {'message': 'key error', 'errorMessage': '키 값이 일치하지 않습니다.'}
            400, {'message': 'invalid_parameter', 'error_message': '[데이터]가(이) 유효하지 않습니다.'}
            500, {'message': 'unable to close database', 'errorMessage': '커넥션 종료 실패'}: 커넥션 종료 실패
            500, {'message': 'internal server error', 'errorMessage': format(e)}): 서버 에러
        History:

                2020-12-31(김기용): 초기 생성
                2021-01-01(김기용): 북마크에 대한 정보 추가
                2021-01-02(김기용): Param 값에대한 Rule 을 정의해주었다.
        """

        connection = None

        try:
            data = {
                    'search': args[0],
                    'limit': int(args[1]),
                    'sort_type': args[2] 
                    }

            connection = get_connection(self.database)
            result = self.service.product_search_service(connection, data)
            return jsonify({'message': 'success', 'result': result})
        finally:
            try:
                if connection is not None:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('서버에 알 수 없는 에러가 발생했습니다.')
class ProductManageSearchView(MethodView):
    """ Presentation Layer

        Attributes:
            service  : MainCategoryListService 클래스
            database : app.config['DB']에 담겨있는 정보(데이터베이스 관련 정보)

        Author: 심원두

        History:
            2020-12-31(심원두): 초기 작성
            2021-01-03(심원두): 상품 리스트 검색 기능 구현
    """
    def __init__(self, service, database):
        self.service = service
        self.database = database

    @signin_decorator()
    @validate_params(
        Param('lookup_start_date',
              GET,
              str,
              required=False,
              rules=[DateRule(), NotEmpty()]),
        Param('lookup_end_date',
              GET,
              str,
              required=False,
              rules=[DateRule(), NotEmpty()]),
        Param('seller_name',
              GET,
              str,
              required=False,
              rules=[DefaultRule(), NotEmpty(),
                     MaxLength(20)]),
        Param('product_name',
              GET,
              str,
              required=False,
              rules=[DefaultRule(), NotEmpty(),
                     MaxLength(100)]),
        Param('product_id',
              GET,
              str,
              required=False,
              rules=[NumberRule(), NotEmpty()]),
        Param('product_code',
              GET,
              str,
              required=False,
              rules=[DefaultRule(), NotEmpty(),
                     MaxLength(20)]),
        Param('is_sale', GET, int, required=False, rules=[Enum(1, 2)]),
        Param('is_display', GET, int, required=False, rules=[Enum(1, 2)]),
        Param('is_discount', GET, int, required=False, rules=[Enum(1, 2)]),
        Param('page_number', GET, int, required=True, rules=[PageRule()]),
        Param('limit', GET, int, required=True, rules=[Enum(10, 20, 50)]))
    def get(self, *args):
        """GET 메소드: 특정 조건에 해당하는 상품 리스트를 조회한다.
            
            Args:
                'lookup_start_date'       : 조회 시작 기간
                'lookup_end_date'         : 조회 종료 기간
                'seller_name'             : 셀러명
                'product_name'            : 상품명
                'product_id'              : 상품 아이디
                'product_code'            : 상품 코드
                'seller_attribute_type_id : 셀러 속성
                'is_sale'                 : 할인 여부
                'is_display'              : 진열 여부
                'is_discount'             : 할인 여부
                'page_number'             : 페이지 번호
                'limit'                   : 한 화면에 보여줄 상품의 갯수
                
            Author: 심원두
            
            Returns:
                return {"message": "success", "result": result}
            
            Raises:
                400, {'message': 'key error',
                      'errorMessage': 'key_error' + format(e)} : 잘못 입력된 키값
                      
                400, {'message': 'both date field required',
                      'errorMessage': 'both_date_field_required'}: 필수 값 유효성 체크 에러
                      
                400, {'message': 'start date is greater than end date',
                      'errorMessage': 'start_date_is_greater_than_end_date'}: 날짜 비교 유효성 체크 에러
                
                400, {'message': 'invalid seller attribute type',
                      'errorMessage': 'invalid_seller_attribute_type'}: 셀러 타입 유효성 체크 에러
            
            History:
                2020-12-31(심원두): 초기생성
                2021-01-03(심원두): 상품 리스트 검색 기능 구현, Login Decorator 구현 예정
        """

        try:
            search_condition = {
                'seller_id':
                g.account_id if g.permission_type_id == 2 else None,
                'lookup_start_date':
                request.args.get('lookup_start_date', None),
                'lookup_end_date':
                request.args.get('lookup_end_date', None),
                'seller_name':
                request.args.get('seller_name', None),
                'product_name':
                request.args.get('product_name', None),
                'product_id':
                request.args.get('product_id', None),
                'product_code':
                request.args.get('product_code', None),
                'seller_attribute_type_ids':
                json.loads(request.args.get('seller_attribute_type_id'))
                if request.args.get('seller_attribute_type_id') else None,
                'is_sale':
                request.args.get('is_sale', None),
                'is_display':
                request.args.get('is_display', None),
                'is_discount':
                request.args.get('is_discount', None),
                'page_number':
                request.args.get('page_number'),
                'limit':
                request.args.get('limit')
            }

            search_condition_back_to_front = {
                'lookup_start_date':
                search_condition['lookup_start_date'],
                'lookup_end_date':
                search_condition['lookup_end_date'],
                'seller_name':
                search_condition['seller_name'],
                'product_name':
                search_condition['product_name'],
                'product_id':
                search_condition['product_id'],
                'product_code':
                search_condition['product_code'],
                'seller_attribute_type':
                search_condition['seller_attribute_type_ids'],
                'is_sale':
                0 if search_condition['is_sale'] is None else int(
                    search_condition['is_sale']),
                'is_display':
                0 if search_condition['is_display'] is None else int(
                    search_condition['is_display']),
                'is_discount':
                0 if search_condition['is_discount'] is None else int(
                    search_condition['is_discount']),
                'page_number':
                int(search_condition['page_number']),
                'limit':
                int(search_condition['limit'])
            }

            connection = get_connection(self.database)
            result = self.service.search_product_service(
                connection, search_condition)
            result['search_condition'] = search_condition_back_to_front

            return jsonify({'message': 'success', 'result': result})

        except KeyError as e:
            traceback.print_exc()
            raise e

        except Exception as e:
            traceback.print_exc()
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')
Esempio n. 3
0
class EventProductsToAddView(MethodView):
    """ Presentation Layer

        Attributes:
            service  : EventService 클래스
            database : app.config['DB']에 담겨있는 정보(데이터베이스 관련 정보)

        Author: 강두연

        History:
            2020-12-31(강두연): 초기 생성, 기획전 상품추가 페이지 상품 조회 기능 작성
    """
    def __init__(self, service, database):
        self.service = service
        self.database = database

    @signin_decorator()
    @validate_params(Param('product_name', GET, str, required=False),
                     Param('product_number',
                           GET,
                           str,
                           required=False,
                           rules=[NumberRule()]),
                     Param('seller_name', GET, str, required=False),
                     Param('seller_number',
                           GET,
                           str,
                           required=False,
                           rules=[NumberRule()]),
                     Param('menu_id',
                           JSON,
                           int,
                           required=False,
                           rules=[ProductMenuRule()]),
                     Param('main_category_id', JSON, int, required=False),
                     Param('sub_category_id', JSON, int, required=False),
                     Param('page', GET, int, required=True,
                           rules=[PageRule()]),
                     Param('length', GET, int, required=True),
                     Param('start_date',
                           JSON,
                           str,
                           required=False,
                           rules=[DateRule()]),
                     Param('end_date',
                           JSON,
                           str,
                           required=False,
                           rules=[DateRule()]))
    def get(self, *args):
        """ 기획전에 추가할 상품 조회

            Args:
                args[0](product_name): 상품이름
                args[1](product_number): 상품번호
                args[2](seller_name): 셀러명
                args[3](seller_number): 셀러번호
                args[4](menu_id): 메뉴 아이디 - 트렌드 4, 브렌드 5, 뷰티 6
                args[5](main_category_id): 1차 카테고리 아이디
                args[6](sub_category_id): 2차 카테고리 아이디
                args[7](page): 페이지 번호
                args[8](length): 페이지네이션 리미트
                args[9](start_date): 등록일 기준 검색할 때 시작날짜
                args[10](end_date): 등록일 기준 검색할 때 끝나는날짜

            Returns: {
                "message": "success",
                "result": {
                    "products": [
                        {
                            "discount_rate": 0.1,
                            "discounted_price": 9000.0,
                            "id": 99,
                            "is_display": 1,
                            "is_sale": 1,
                            "original_price": 10000.0,
                            "product.discounted_price": 9000.0,
                            "product_name": "성보의하루99",
                            "product_number": "P0000000000000000099",
                            "seller_name": "나는셀러5",
                            "thumbnail_image_url": "https://img.freepik.com"
                        },
                        {
                            "discount_rate": 0.1,
                            "discounted_price": 9000.0,
                            "id": 98,
                            "is_display": 1,
                            "is_sale": 1,
                            "original_price": 10000.0,
                            "product.discounted_price": 9000.0,
                            "product_name": "성보의하루98",
                            "product_number": "P0000000000000000098",
                            "seller_name": "나는셀러5",
                            "thumbnail_image_url": "https://img.freepik.com"
                        }
                    ],
                    "total_count": 31
                }
            }

            Raises:
                400, {'message': 'filter must be at least one',
                'errorMessage': 'search filter must be at least one'} : 검색 필터가 하나도 없을 때

                400, {'message': 'search inputs must be only one',
                'errorMessage': 'search value accept only one of name or number'} : 동시에 사용할수 없는 필터가 들어왔을 때

                400, {'message': 'filter does not match',
                'errorMessage': 'upper category is required'} : 상품 분류로 검색할 때 하위카테고리만 있고 상위카테고리는 없는경우

                400, {'message': 'date inputs should be start_date and end_date',
                'errorMessage': 'start_date or end_date is missing'} : 등록일로 검색할 때 시작일 또는 종료일이 하나만 있는경우

            History:
                    2020-12-31(강두연): 초기 작성
        """
        if g.permission_type_id != 1:
            raise NoPermission('마스터 이용자만 사용 가능합니다')

        data = {
            'product_name': args[0],
            'product_number': args[1],
            'seller_name': args[2],
            'seller_number': args[3],
            'menu_id': args[4],
            'main_category_id': args[5],
            'sub_category_id': args[6],
            'page': args[7],
            'length': args[8],
            'start_date': args[9],
            'end_date': args[10]
        }
        if not data['product_name'] \
                and not data['product_number'] \
                and not data['seller_number'] \
                and not data['seller_name'] \
                and not data['menu_id'] \
                and not (data['start_date'] and data['end_date']):
            raise SearchFilterRequired('search filter must be at least one')

        if (data['product_number']
                and data['product_name']) or (data['seller_number']
                                              and data['seller_name']):
            raise SearchTwoInput(
                'search value accept only one of name or number')

        if not data['menu_id'] and (data['main_category_id']
                                    or data['sub_category_id']):
            raise FilterDoesNotMatch('upper category is required')

        if not data['main_category_id'] and data['sub_category_id']:
            raise FilterDoesNotMatch('upper category is required')

        if (data['start_date']
                and not data['end_date']) or (not data['start_date']
                                              and data['end_date']):
            raise DateMissingOne('start_date or end_date is missing')

        try:
            connection = get_connection(self.database)
            products = self.service.get_products_to_post_service(
                connection, data)
            return jsonify({'message': 'success', 'result': products})

        except Exception as e:
            traceback.print_exc()
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')
Esempio n. 4
0
class EventView(MethodView):
    """ Presentation Layer

        Attributes:
            self.service  : EventService 클래스
            self.database : app.config['DB']에 담겨있는 정보(데이터베이스 관련 정보)

        Author: 강두연

        History:
            2020-12-28(강두연): 초기 생성, 기획전 조회 기능 작성
            2020-12-29(강두연): 기획전 조회 검색 필터링 기능 작성
            2021-01-02(강두연): 기획전 생성기능 작성
    """
    def __init__(self, service, database):
        self.service = service
        self.database = database

    @signin_decorator()
    @validate_params(Param('name', GET, str, required=False),
                     Param('number',
                           GET,
                           str,
                           required=False,
                           rules=[NumberRule()]),
                     Param('status',
                           GET,
                           str,
                           required=False,
                           rules=[EventStatusRule()]),
                     Param('exposure',
                           GET,
                           int,
                           required=False,
                           rules=[BooleanRule()]),
                     Param('page', GET, int, required=True,
                           rules=[PageRule()]),
                     Param('length', GET, int, required=True),
                     Param('start_date',
                           JSON,
                           str,
                           required=False,
                           rules=[DateRule()]),
                     Param('end_date',
                           JSON,
                           str,
                           required=False,
                           rules=[DateRule()]))
    def get(self, *args):
        """ GET 메소드: 이벤트 리스트 조회

            Args:
                args[0](name): 기획전 이름
                args[1](number): 기획전 번호
                args[2](status): 기획전 상태
                args[3](exposure): 노출 여부
                args[4](page): 페이지 번호
                args[5](length): 페이지네이션 리미트
                args[6](start_date): 등록일 기준 검색할 때 시작날짜
                args[7](end_date): 등록일 기준 검색할 때 끝나는날짜

            Author: 강두연

            Returns:
                {
                    "message": success,
                    "events": [
                        {
                            "created_at": "2020-12-28 16:40:41",
                            "end_date": "2021-03-01 00:00:00",
                            "event_kind": "버튼",
                            "event_name": "성보의 하루 시리즈2(버튼형)",
                            "event_number": 2,
                            "event_status": "진행중",
                            "event_type": "상품(이미지)",
                            "is_display": "노출",
                            "product_count": 59,
                            "start_date": "2020-10-19 00:00:00"
                        },
                        {
                            "created_at": "2020-12-28 16:40:41",
                            "end_date": "2021-03-01 00:00:00",
                            "event_kind": "상품",
                            "event_name": "성보의 하루 시리즈",
                            "event_number": 1,
                            "event_status": "진행중",
                            "event_type": "상품(이미지)",
                            "is_display": "노출",
                            "product_count": 40,
                            "start_date": "2020-10-19 00:00:00"
                        }
                    ],
                    "total_count": 2
                }

            Raises:
                400, {'message': 'search inputs must be only one',
                'errorMessage': 'search value accept only one of name or number'} : 동시에 사용할수 없는 필터가 들어왔을 때

                400, {'message': 'date inputs should be start_date and end_date',
                'errorMessage': 'start_date or end_date is missing'} : 등록일로 검색할 때 시작일 또는 종료일이 하나만 있는경우

            History:
                2020-12-28(강두연): 초기 생성
                2020-12-29(강두연): 검색 조건에 맞게 필터링 기능 작성
        """
        if g.permission_type_id != 1:
            raise NoPermission('마스터 이용자만 사용 가능합니다')

        data = {
            'name': args[0],
            'number': args[1],
            'status': args[2],
            'exposure': args[3],
            'page': args[4],
            'length': args[5],
            'start_date': args[6],
            'end_date': args[7]
        }
        if (data['start_date']
                and not data['end_date']) or (not data['start_date']
                                              and data['end_date']):
            raise DateMissingOne('start_date or end_date is missing')

        if data['name'] and data['number']:
            raise SearchTwoInput(
                'search value accept only one of name or number')

        try:
            connection = get_connection(self.database)
            events = self.service.get_events_service(connection, data)
            return jsonify({'message': 'success', 'result': events})

        except Exception as e:
            traceback.print_exc()
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')

    @signin_decorator()
    @validate_params(Param('name', FORM, str, required=True),
                     Param('start_datetime',
                           FORM,
                           str,
                           required=True,
                           rules=[DateTimeRule()]),
                     Param('end_datetime',
                           FORM,
                           str,
                           required=True,
                           rules=[DateTimeRule()]),
                     Param('event_type_id', FORM, int, required=True),
                     Param('event_kind_id', FORM, int, required=True),
                     Param('is_display',
                           FORM,
                           int,
                           required=True,
                           rules=[BooleanRule()]),
                     Param('buttons', FORM, list, required=False),
                     Param('products', FORM, list, required=False))
    def post(self, *args):
        """ 기획전 등록

            Args:
                name: 기획전 이름
                start_datetime: 기획전 시작날짜시간
                end_datetime: 기획전 종료날짜시간
                event_type_id: 기획전 타입
                event_kind_id: 기획전 종류
                is_display: 노출여부
                buttons: 기획전에 추가할 버튼
                products: 기획전에 추가할 상품
                banner_image: 배너이미지 파일
                detail_image: 상세이미지 파일

            Returns: {
                'message': 'success',
                'event_id': 생성된 기획전 아이디
            }

            Raises:
                400, {'message': 'at least two buttons should be created',
                      'errorMessage': 'button is required'} : 기획전 종류가 버튼형일때 버튼이 없을 때

                400, {'message': 'at least two buttons should be created',
                      'errorMessage': 'at least two buttons are required'} : 기획전 종류가 버튼인데 2개 미만의 버튼이 들어왔을 때

                400, {
                    'message': 'button name is required in each product',
                    'errorMessage': 'button name is required in each product'
                } : 기획전 종류가 버튼인데 상품에 버튼이름 키,값이 없을 때

                400, {'message': 'Event kind does not match',
                      'errorMessage': 'event kind is not buttons'} : 기획전 종류가 버튼형이 아닌데 버튼들에 대한 정보가 들어왔을 때

                400, {'message': 'image files are required',
                      'errorMessage': 'image is required'} : 이미지가 필요함

                400, {'message': 'start date and end date context error',
                      'errorMessage': 'start and end datetime context error'} : 시작날짜가 종료날짜보다 미래일 때

            History:
                    2021-01-02(강두연): 초기 작성
        """
        if g.permission_type_id != 1:
            raise NoPermission('마스터 이용자만 사용 가능합니다')

        data = {
            'name': request.form.get('name'),
            'start_datetime': request.form.get('start_datetime'),
            'end_datetime': request.form.get('end_datetime'),
            'event_type_id': request.form.get('event_type_id'),
            'event_kind_id': request.form.get('event_kind_id'),
            'is_display': request.form.get('is_display')
        }

        banner_image = request.files.get('banner_image')
        detail_image = request.files.get('detail_image')

        buttons = request.form.get('buttons')
        products = request.form.get('products')

        if products:
            products = json.loads(products)

        if data['event_kind_id'] == '2':
            # 기획전 종류가 버튼인데 버튼이 없을 때
            if not buttons:
                raise ButtonsMinimumCount('button is required')

            buttons = json.loads(buttons)

            # 기획전 종류가 버튼인데 2개 미만의 버튼이 들어왔을 때
            if len(buttons) < 2:
                raise ButtonsMinimumCount('at least two buttons are required')

            # 기획전 종류가 버튼인데 상품에 버튼이름 키,값이 없을 때
            if products:
                for product in products:
                    if 'button_name' not in product or not product[
                            'button_name']:
                        raise ProductButtonNameRequired(
                            'button name is required in each product')

        # 기획전 종류가 버튼형이 아닌데 버튼들에 대한 정보가 들어왔을 때
        elif data['event_kind_id'] != '2' and buttons:
            raise EventKindDoesNotMatch('event kind is not buttons')

        # 이미지 파일 존재 유무 확인
        if not banner_image or not detail_image or not banner_image.filename or not detail_image.filename:
            raise ImageIsRequired('image is required')

        data['banner_image'] = banner_image
        data['detail_image'] = detail_image

        # 시작 날짜가 종료날짜보다 미래일 때
        start = datetime.strptime(data['start_datetime'], "%Y-%m-%d %H:%M")
        end = datetime.strptime(data['end_datetime'], "%Y-%m-%d %H:%M")

        if start >= end:
            raise StartAndEndDateContext(
                'start and end datetime context error')

        try:
            connection = get_connection(self.database)
            result = self.service.create_event_service(connection, data,
                                                       buttons, products)

            connection.commit()

            return jsonify({'message': 'success', 'event_id': result}), 201

        except Exception as e:
            connection.rollback()
            traceback.print_exc()
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')
class OrderDetailView(MethodView):
    def __init__(self, service, database):
        self.service = service
        self.database = database

    @signin_decorator
    @validate_params(Param('order_item_id', PATH, int))
    def get(self, *args):
        data = {"permission": g.permission_type_id, "order_item_id": args[0]}
        """GET 메소드: 주문 상세 정보 조회     

        Args: 
            args = ('order_item_id')

        Author: 김민서

        Returns: 
            {
                "message": "success",
                "result": {
                    "order_detail_info": [
                        {
                            "customer_phone": "12345667890",
                            "order_detail_number": "oidt00001",
                            "order_item_id": 1,
                            "order_item_purchased_date": "2020-12-31 13:25:03",
                            "status": "배송중"
                        }
                    ],
                    "order_info": [
                        {
                            "order_id": 1,
                            "order_number": "20201225000000001",
                            "order_purchased_date": "2020-12-31 13:25:03",
                            "total_price": 18000.0
                        }
                    ],
                    "order_status_history": [
                        {
                            "date": "2021-01-03 01:26:05",
                            "status": "배송중"
                        },
                        {
                            "date": "2020-12-31 13:25:01",
                            "status": "상품준비"
                        }
                    ],
                    "product_info": [
                        {
                            "brand_name": "나는셀러3",
                            "discount_rate": 0.1,
                            "option_information": "Black/Free",
                            "price": "10000 원 (할인가 9000원)",
                            "product_name": "성보의하루1",
                            "product_number": "P0000000000000000001",
                            "qauntity": 1
                        }
                    ],
                    "recipient_info": [
                        {
                            "customer_name": "user1",
                            "delivery_memo": "문 앞에 놓아주세요",
                            "destination": "서울시 강남 위코드 아파 (123321)",
                            "recipient_name": "둘리",
                            "recipient_phone": "01022222222",
                            "user_id": 102
                        }
                    ],
                    "updated_at_time": "2021-01-03 00:42:12"
                }
            }
            
        Raises:
            400, {'message': 'key_error',
                    'errorMessage': 'key error'} : 잘못 입력된 키값
                    
            400, {
                    "error_message:": "order_item_id이 유효하지 않습니다.",
                    "message": {
                        "order_item_id": [
                            "Value is required"
                        ]
                    }
                } : 필수 입력값 없음
                    
            400, {'message': 'does_not_exist_order_detail',
                    'errorMessage': '주문 상세 정보가 존재하지 않습니다.'} : 주문 상세 정보 없음
                    
            403, {'message': 'no_permission',
                     'errorMessage': '권한이 없습니다.'} : 권한 없음
                        
            400, {'message': 'unable_to_close_database',
                    'errorMessage': 'unable to close database'}: 커넥션 종료 실패
                    
            500, {'message': 'internal_server_error',
                     'errorMessage': 'internal server error'} : 알 수 없는 에러
            
        History:
            2021-01-01(김민서): 초기 생성    
        """

        try:
            connection = get_connection(self.database)
            result = self.service.get_order_detail_service(connection, data)
            return jsonify({"message": "success", "result": result}), 200
        except Exception as e:
            raise e
        finally:
            try:
                connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')

    @signin_decorator
    @validate_params(Param('order_item_id', GET, str, rules=[NumberRule()]),
                     Param("updated_at_time",
                           GET,
                           str,
                           rules=[SecondDateTimeRule()]),
                     Param("sender_phone",
                           GET,
                           str,
                           required=False,
                           rules=[PhoneRule()]),
                     Param("recipient_phone",
                           GET,
                           str,
                           required=False,
                           rules=[PhoneRule()]),
                     Param("address1", GET, str, required=False),
                     Param("address2", GET, str, required=False))
    def patch(self, *args):
        data = {
            "permission": g.permission_type_id,
            "order_item_id": args[0],
            "updated_at_time": args[1],
            "sender_phone": args[2],
            "recipient_phone": args[3],
            "address1": args[4],
            "address2": args[5]
        }
        """PATCH 메소드: 주문 상세 정보 수정     

        Args: 
            args = ('order_item_id', 'updated_at_time', 'sender_phone', 'recipient_phone', 'address1', 'address2')

        Author: 김민서

        Returns: {'message': 'success'}

        Raises:
            400, {'message': 'key_error', 
                    'errorMessage': 'key error'} : 잘못 입력된 키값
                    
            400, {'message': 'unable_to_close_database', 
                    'errorMessage': 'unable to close database'}: 커넥션 종료 실패
                    
            403, {'message': 'no_permission', 
                    'errorMessage': '권한이 없습니다.'} : 권한 없음
                    
            400, {'message': input_does_not_exist, 
                    'errorMessage': '수정 정보가 없습니다.'} : 수정 정보 존재하지 않음
                    
            400, {'message': 'one_of_address_inputs_does_not_exist', 
                    'errorMessage': '수정 주소 정보가 누락되었습니다.'} : 수정할 주소 정보 부족
                    
            400, {'message': 'unable_to_update', 
                    'errorMessage': '업데이트가 불가합니다.'} : 수정 불가   
                    
            400, {'message': 'denied_to_update', 
                    'errorMessage': '업데이트가 실행되지 않았습니다.'} : 수정 실패
                    
            500, {'message': 'internal_server_error',
                     'errorMessage': 'internal server error'} : 알 수 없는 에러
                    

        History:
            2021-01-01(김민서): 초기 생성    
        """

        try:
            connection = get_connection(self.database)
            self.service.update_order_detail_service(connection, data)
            connection.commit()
            return jsonify({"message": "success"}), 200
        except Exception as e:
            connection.rollback()
            raise e
        finally:
            try:
                connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')
class OrderView(MethodView):
    def __init__(self, service, database):
        self.service = service
        self.database = database

    @signin_decorator
    @validate_params(Param('status', GET, int),
                     Param('number', GET, str, required=False),
                     Param('detail_number', GET, str, required=False),
                     Param('sender_name', GET, str, required=False),
                     Param('sender_phone',
                           GET,
                           str,
                           required=False,
                           rules=[NumberRule()]),
                     Param('seller_name', GET, str, required=False),
                     Param('product_name', GET, str, required=False),
                     Param('start_date',
                           GET,
                           str,
                           required=False,
                           rules=[DateRule()]),
                     Param('end_date',
                           GET,
                           str,
                           required=False,
                           rules=[DateRule()]),
                     Param('attributes', GET, list, required=False),
                     Param('order_by', GET, str, required=False),
                     Param('page', GET, int, rules=[PageRule()]),
                     Param('length', GET, str, rules=[NumberRule()]))
    def get(self, *args):
        data = {
            'permission': g.permission_type_id,
            'account': g.acount_id,
            'permission': 2,
            'account': 1,
            'status': args[0],
            'number': args[1],
            'detail_number': args[2],
            'sender_name': args[3],
            'sender_phone': args[4],
            'seller_name': args[5],
            'product_name': args[6],
            'start_date': args[7],
            'end_date': args[8],
            'attributes': args[9],
            'order_by': args[10],
            'page': args[11],
            'length': args[12]
        }
        """GET 메소드: 주문 정보 조회
        
        Args: 
            args = ('status', 'number', 'detail_number', 'sender_name', 'sender_phone', 'seller_name', 
                'product_name', 'start_date', 'end_date', 'seller_attributes', 'order_by', 'page', 'length')

        Author: 김민서

        Returns:
            {
                "message": "success",
                "results": [
                    {
                        "created_at_date": "2020-12-30 10:05:19",
                        "customer_name": "user2",
                        "customer_phone": "01099990103",
                        "id": 3,
                        "option_extra_cost": "0",
                        "option_information": "Black/Free",
                        "order_detail_number": "oidt00003",
                        "order_number": "20201225000000002",
                        "product_name": "성보의하루1",
                        "quantity": 1,
                        "seller_name": "나는셀러9",
                        "status": "상품준비",
                        "total_price": "9000",
                        "updated_at_date": "2020-12-30 10:05:19"
                    },
                    {
                        "created_at_date": "2020-12-30 10:05:19",
                        "customer_name": "user1",
                        "customer_phone": "01099990102",
                        "id": 4,
                        "option_extra_cost": "0",
                        "option_information": "Black/Free",
                        "order_detail_number": "oidt00004",
                        "order_number": "20201225000000003",
                        "product_name": "성보의하루1",
                        "quantity": 4,
                        "seller_name": "나는셀러9",
                        "status": "상품준비",
                        "total_price": "36000",
                        "updated_at_date": "2020-12-30 10:05:19"
                    }
                ],
                "totalCount": 2
            }

        Raises:
            400, {'message': 'key_error', 
                'errorMessage': 'key error'} : 잘못 입력된 키값
                
            400, {'message': 'must_be_date_inputs_or_filter_inputs', 
                'errorMessage': '검색어 조건과 날짜 조건 둘 중에 하나는 반드시 포함되어야 합니다.'}: 필터 조건 없음
                
            400, {'message': 'must_be_other_date_input', 
                'errorMessage': '시작일과 마지막일이 모두 포함되어야 합니다.'} : 날짜 조건 없음
                
            400, {'message': 'end_date_is_invalid', 
                'errorMessage': '시작일이 마지막일보다 늦습니다.'} : 시작일이 마지막일보다 늦음

            400, {'message': 'unable_to_close_database', 
                'errorMessage': 'unable to close database'}: 커넥션 종료 실패
                
            403, {'message': 'no_permission', 
                'errorMessage': '권한이 없습니다.'} : 주문 리스트 조회 권한 없음
                
            400, {'message': 'order_does_not_exist', 
                'errorMessage': '주문 내역이 없습니다.'} : 주문 리스트 없음
                
            500, {'message': 'internal_server_error',
                     'errorMessage': 'internal server error'} : 알 수 없는 에러
            

        History:
            2020-12-29(김민서): 초기 생성
            2020-01-03(김민서): 1차 수정
        """

        try:
            connection = get_connection(self.database)
            result = self.service.get_orders_service(connection, data)
            return jsonify({
                'message': 'success',
                'totalCount': result['total_count'],
                'results': result['order_lists']
            }), 200
        except Exception as e:
            raise e
        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')

    @signin_decorator
    @validate_params(Param('status_id', GET, int), Param('id', GET, list))
    def patch(self, *args):
        data = {
            'permission': g.permission_type_id,
            'account': g.acount_id,
            "status": args[0],
            "ids": args[1]
        }
        """PATCH 메소드: 주문 상태 변경

        Args: 
            args = ('status', 'ids')

        Author: 김민서

        Returns: { "message": "success" }

        Raises:
            400, {'message': 'key error', 
                    'errorMessage': 'key_error'} : 잘못 입력된 키값
                            
            400, {'message': 'unable to close database', 
                    'errorMessage': 'unable_to_close_database'}: 커넥션 종료 실패
                    
            400, {'message': 'now order status is not allowed to update status', 
                    'errorMessage': '현재 상태는 업데이트가 불가합니다.'}: 주문 상태 변경 불가능 상태
                    
            400, {'message': 'unable_to_update_status', 
                    'errorMessage': '업데이트가 불가합니다.'}: 수정 불가
                    
            403, {'message': 'no_permission', 
                    'errorMessage': '권한이 없습니다.'} : 권한 없음
                    
            500, {'message': 'internal_server_error',
                     'errorMessage': 'internal server error'} : 알 수 없는 에러

        History:
            2021-01-01(김민서): 초기 생성    
        """

        try:
            connection = get_connection(self.database)
            self.service.update_order_status_service(connection, data)
            connection.commit()
            return {'message': 'success'}

        except Exception as e:
            connection.rollback()
            raise e
        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')
class CreateProductView(MethodView):
    """ Presentation Layer

        Attributes:
            service  : CreateProductService 클래스
            database : app.config['DB']에 담겨있는 정보(데이터베이스 관련 정보)

        Author: 심원두

        History:
            2020-12-29(심원두): 초기 생성. products insert, product_code updated, product_histories 생성 기능 작성
            2020-12-30(심원두): 각 Param rules 추가, stock insert 기능 작성.
            2020-01-03(심원두): 상품 등록 Param rules 추가
    """
    def __init__(self, service, database):
        self.service = service
        self.database = database

    @signin_decorator()
    @validate_params(
        Param('seller_name', GET, str, required=False, rules=[MaxLength(20)]),
        Param('main_category_id',
              GET,
              str,
              required=False,
              rules=[NumberRule()]))
    def get(self, *args):
        """POST 메소드: 상품 정보 등록 초기 화면

            Args:
                'seller_name'      : 사용자가 입력한 셀러명
                'main_category_id' : 사용자가 선택한 메인 카테고리 아이디

            Author: 심원두

            Returns:
                return {"message": "success", "result": [{}]}

            Raises:
                400, {'message': 'key error',
                      'errorMessage': 'key_error' + format(e)}: 잘못 입력된 키값

                500, {'message': 'fail to get sub category list',
                      'errorMessage': 'fail_to_get_sub_category_list'}: 색상 정보 취득 실패

                500, {'message': 'fail to get product origin types',
                      'errorMessage': 'fail_to_get_product_origin_types'} : 원산지 정보 취득 실패

                500, {'message': 'fail to get color list',
                      'errorMessage': 'fail_to_get_color_list'}: 색상 정보 취득 실패

                500, {'message': 'fail to get color list',
                      'errorMessage': 'fail_to_get_color_list'}: 색상 정보 취득 실패

            History:
                2020-12-30(심원두): 초기생성
                2021-01-06(심원두): 로그인 데코레이터 처리 추가. 관리자일 경우에만 셀러 검색 허용하도록 수정
        """

        try:
            data = {
                'seller_name': request.args.get('seller_name', None),
                'main_category_id': request.args.get('main_category_id', None)
            }

            connection = get_connection(self.database)

            if data['seller_name'] and g.permission_type_id == 1:
                sellers = self.service.search_seller_list_service(
                    connection, data)

                return jsonify({'message': 'success', 'result': sellers})

            if data['main_category_id']:
                sub_categories = self.service.get_sub_category_list_service(
                    connection, data)

                return jsonify({
                    'message': 'success',
                    'result': sub_categories
                })

            result = dict()

            result['product_origin_types'] = \
                self.service.get_product_origin_types_service(
                    connection
                )

            result['color_list'] = \
                self.service.get_color_list_service(
                    connection
                )

            result['size_list'] = \
                self.service.get_size_list_service(
                    connection
                )

            return jsonify({'message': 'success', 'result': result})

        except KeyError as e:
            traceback.print_exc()
            raise e

        except Exception as e:
            traceback.print_exc()
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')

    @signin_decorator()
    @validate_params(
        Param('seller_id', FORM, str, required=True, rules=[NumberRule()]),
        Param('is_sale', FORM, int, required=True, rules=[Enum(0, 1)]),
        Param('is_display', FORM, int, required=True, rules=[Enum(0, 1)]),
        Param('main_category_id',
              FORM,
              str,
              required=True,
              rules=[NumberRule()]),
        Param('sub_category_id',
              FORM,
              str,
              required=True,
              rules=[NumberRule()]),
        Param('is_product_notice',
              FORM,
              int,
              required=True,
              rules=[Enum(0, 1)]),
        Param('manufacturer', FORM, str, required=False,
              rules=[MaxLength(30)]),
        Param('manufacturing_date', FORM, str, required=False),
        Param('product_origin_type_id', FORM, str, required=False),
        Param('product_name',
              FORM,
              str,
              required=True,
              rules=[NotEmpty(), MaxLength(100)]),
        Param('description', FORM, str, required=False,
              rules=[MaxLength(200)]),
        Param('detail_information',
              FORM,
              str,
              required=True,
              rules=[NotEmpty()]), Param('options', FORM, list, required=True),
        Param('minimum_quantity',
              FORM,
              str,
              required=False,
              rules=[NumberRule()]),
        Param('maximum_quantity',
              FORM,
              str,
              required=False,
              rules=[NumberRule()]),
        Param('origin_price', FORM, str, required=True, rules=[NumberRule()]),
        Param('discount_rate', FORM, str, required=True, rules=[NumberRule()]),
        Param('discounted_price',
              FORM,
              str,
              required=True,
              rules=[NumberRule()]),
        Param('discount_start_date', FORM, str, required=False),
        Param('discount_end_date', FORM, str, required=False))
    def post(self, *args):
        """ POST 메소드: 상품 정보 등록

            Args:
            - 사용자 입력 값(상품 이미지 최대 5개) : image_files
            - 사용자 입력 값(옵션 정보 리스트)    : options
            - 사용자 입력 값
            Form-Data: (
                'seller_id'
                'account_id',
                'is_sale',
                'is_display',
                'main_category_id',
                'sub_category_id',
                'is_product_notice',
                'manufacturer',
                'manufacturing_date',
                'product_origin_type_id',
                'product_name',
                'description',
                'detail_information',
                'options',
                'minimum_quantity',
                'maximum_quantity',
                'origin_price',
                'discount_rate',
                'discounted_price',
                'discount_start_date',
                'discount_end_date',
            )

            Author: 심원두

            Returns:
                200, {'message': 'success'}                                                   : 상품 정보 등록 성공

            Raises:
                400, {'message': 'key_error',
                      'errorMessage': 'key_error_' + format(e)}                               : 잘못 입력된 키값

                400, {'message': 'required field is blank',
                      'errorMessage': 'required_manufacture_information'}                     : 제조 정보 필드 없음

                400, {'message': 'required field is blank',
                      'errorMessage': 'required_discount_start_or_end_date'}                  : 필수 입력 항목 없음

                400, {'message': 'compare quantity field check error',
                      'errorMessage': 'minimum_quantity_cannot_greater_than_maximum_quantity'}: 최소 구매 수량이 최대 보다 큼

                400, {'message': 'compare price field check error',
                      'errorMessage': 'discounted_price_cannot_greater_than_origin_price'}    : 할인가가 판매가 보다 큼

                400, {'message': 'compare price field check error',
                      'errorMessage': 'wrong_discounted_price'}                               : 판매가와 할인가 일치하지 않음

                400, {'message': 'compare price field check error',
                      'errorMessage': 'required_discount_start_or_end_date'}                  : 할인 시작, 종료 일자 필드 없음

                400, {'message': 'start date is greater than end date',
                      'errorMessage': 'start_date_cannot_greater_than_end_date'}              : 할인 시작일이 종료일 보다 큼

                400, {'message': 'compare price field check error',
                      'errorMessage': 'discounted_price_have_to_same_with_origin_price'}      : 할인가, 판매가 불일치(할인율 0)

                413, {'message': 'invalid file',
                      'errorMessage': 'invalid_file'}                                         : 파일 이름이 공백, 혹은 파일을 정상적으로 받지 못함

                413, {'message': 'file size too large',
                      'errorMessage': 'file_size_too_large'}                                  : 파일 사이즈 정책 위반 (4메가 이상인 경우)

                413, {'message': 'file scale too small, 640 * 720 at least',
                      'errorMessage': 'file_scale_at_least_640*720'}                          : 파일 스케일 정책 위반 (680*720 미만인 경우)

                413, {'message': 'only allowed jpg type',
                      'errorMessage': 'only_allowed_jpg_type'}                                : 파일 확장자 정책 위반 (JPG, JPEG 아닌 경우)

                500, {'message': 'image_file_upload_to_amazon_fail',
                      'errorMessage': 'image_file_upload_fail'}                               : 이미지 업로드 실패

                500, {'message': 'product create denied',
                      'errorMessage': 'unable_to_create_product'}                             : 상품 정보 등록 실패

                500, {'message': 'product code update denied',
                      'errorMessage': 'unable_to_update_product_code'}                        : 상품 코드 갱신 실패

                500, {'message': 'product code update denied',
                      'errorMessage': 'unable_to_update_product_code'}                        : 상품 코드 갱신 실패

                500, {'message': 'product image create denied',
                      'errorMessage': 'unable_to_create_product_image'}                       : 상품 이미지 등록 실패

                500, {'message': 'stock create denied',
                      'errorMessage': 'unable_to_create_stocks'}                              : 상품 옵션 정보 등록 실패

                500, {'message': 'product history create denied',
                      'errorMessage': 'unable_to_create_product_history'}                     : 상품 이력 등록 실패

                500, {'message': 'bookmark volumes create denied',
                      'errorMessage': 'unable_to_create_bookmark_volumes'}                    : 북마크 초기 등록 실패

                500, {'message': 'database_connection_fail',
                      'errorMessage': 'database_close_fail'}                                  : 커넥션 종료 실패

                500, {'message': 'database_error',
                      'errorMessage': 'database_error_' + format(e)}                          : 데이터베이스 에러

                500, {'message': 'internal_server_error',
                      'errorMessage': format(e)})                                             : 서버 에러

            History:
                2020-12-29(심원두): 초기 생성
                2021-01-03(심원두): 파라미터 유효성 검사 추가 Enum(), NotEmpty()
                2021-01-05(심원두): -이미지 저장 처리 순서를 3번째에서 가장 마지막으로 내림. 테이블 인서트 처리에 문제가 있을 경우,
                                    S3에 올라간 이미지는 롤백을 할 수 없는 이슈 반영.
                                   -북마크 테이블 초기 등록 처리 추가.
        """

        try:
            data = {
                'seller_id':
                request.form.get('seller_id'),
                'account_id':
                g.account_id,
                'is_sale':
                request.form.get('is_sale'),
                'is_display':
                request.form.get('is_display'),
                'main_category_id':
                request.form.get('main_category_id'),
                'sub_category_id':
                request.form.get('sub_category_id'),
                'is_product_notice':
                request.form.get('is_product_notice'),
                'manufacturer':
                request.form.get('manufacturer'),
                'manufacturing_date':
                request.form.get('manufacturing_date'),
                'product_origin_type_id':
                request.form.get('product_origin_type_id'),
                'product_name':
                request.form.get('product_name'),
                'description':
                request.form.get('description'),
                'detail_information':
                request.form.get('detail_information'),
                'minimum_quantity':
                request.form.get('minimum_quantity'),
                'maximum_quantity':
                request.form.get('maximum_quantity'),
                'origin_price':
                request.form.get('origin_price'),
                'discount_rate':
                request.form.get('discount_rate'),
                'discounted_price':
                request.form.get('discounted_price'),
                'discount_start_date':
                request.form.get('discount_start_date'),
                'discount_end_date':
                request.form.get('discount_end_date')
            }

            product_images = request.files.getlist("image_files")
            stocks = json.loads(request.form.get('options'))
            connection = get_connection(self.database)

            product_id = self.service.create_product_service(connection, data)

            product_code = self.service.update_product_code_service(
                connection, product_id)

            self.service.create_stock_service(connection, product_id, stocks)

            self.service.create_product_history_service(
                connection, product_id, data)

            self.service.create_product_sales_volumes_service(
                connection, product_id)

            self.service.create_bookmark_volumes_service(
                connection, product_id)

            self.service.create_product_images_service(connection,
                                                       data['seller_id'],
                                                       product_id,
                                                       product_code,
                                                       product_images)

            connection.commit()

            return jsonify({'message': 'success'}), 200

        except KeyError as e:
            traceback.print_exc()
            connection.rollback()
            raise e

        except Exception as e:
            traceback.print_exc()
            connection.rollback()
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                traceback.print_exc()
                raise DatabaseCloseFail('database close fail')
class ProductRegistView(MethodView):
    """ Presentation Layer

        Attributes:
            service  : ProductManageService 클래스
            database : app.config['DB']에 담겨있는 정보(데이터베이스 관련 정보)

        Author: 심원두

        History:
            2021-01-13(심원두): refactoring 초기 작성
            2021-01-15(심원두):
                상품 등록 초기 화면 기능 작성 완료. 권한 타입 상수 생성. 권한에 따른 분기 처리 완료.
                파라미터 룰 설정 완료
    """
    def __init__(self, service, database):
        self.service = service
        self.database = database

    @signin_decorator()
    @validate_params(
        Param('seller_name',
              GET,
              str,
              required=False,
              rules=[NotEmpty(), MaxLength(20)]),
        Param('seller_id',
              GET,
              str,
              required=False,
              rules=[NotEmpty(), NumberRule()]),
        Param('main_category_id',
              GET,
              str,
              required=False,
              rules=[NotEmpty(), NumberRule()]),
    )
    def get(self, *args):
        """ GET 메소드: 상품 등록 초기 화면
            
            Args:
                'seller_name'      : 셀러명
                'seller_id'        : 셀러 아이디
                'main_category_id' : 메인 카테고리 아이디
            
            Author: 심원두
            
            Returns:
                result - 아래의 조건에 따라 분기 처리
                    1. 관리자 권한 초기 화면            - 원산지, 색상, 사이즈 정보 출력
                    2. 관리자 권한 셀러 검색            - 셀러 정보 리스트 출력
                    3. 관리자 권한 셀러 선택            - 메인 카테고리 리스트 출력
                    4. 관리자&셀러 권한 메인 카테고리 선택 - 서브 카테고리 출력
                    5. 셀러 권한 초기화면               - 원산지, 색상, 사이즈, 메인 카테고리 정보 출력
                    
            Raises:
                500, {'message': 'fail to get main category list',
                      'errorMessage': 'fail_to_get_main_category_list'}: 메인 카테고리 정보 취득 실패
                
                500, {'message': 'fail to get main category list',
                      'errorMessage': 'fail_to_get_main_category_list'}: 메인 카테고리 정보 취득 실패
            
            History:
                2020-12-30(심원두): 초기생성
                2021-01-15(심원두): 리펙토링 완료
        """

        connection = None

        try:
            connection = get_connection(self.database)

            data = {
                'seller_name': request.args.get('seller_name'),
                'seller_id': request.args.get('seller_id'),
                'main_category_id': request.args.get('main_category_id'),
            }

            result = dict()

            if data['seller_name']:
                result['seller_list'] = self.service.\
                    get_seller_list_by_name_service(
                        connection,
                        data,
                        g.permission_type_id
                    )

                return jsonify({'message': 'success', 'result': result}), 200

            if data['seller_id']:
                result['main_category_list'] = self.service.\
                    get_main_category_list_service(
                        connection
                    )

                if g.permission_type_id is ACCOUNT_ADMIN:
                    return jsonify({
                        'message': 'success',
                        'result': result
                    }), 200

            if data['main_category_id']:
                result['sub_category_list'] = self.service. \
                    get_sub_category_list_service(
                        connection,
                        data
                    )

                return jsonify({'message': 'success', 'result': result}), 200

            result[
                'product_origin_types'] = self.service.get_product_origin_types_service(
                    connection)
            result['color_list'] = self.service.get_color_list_service(
                connection)
            result['size_list'] = self.service.get_size_list_service(
                connection)

            return jsonify({'message': 'success', 'result': result}), 200

        except KeyError as e:
            traceback.print_exc()
            raise e

        except Exception as e:
            traceback.print_exc()
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')
Esempio n. 9
0
class OrderExcelView(MethodView):
    def __init__(self, service, database):
        self.service = service
        self.database = database

    #@signin_decorator()
    @validate_params(Param('status', GET, int),
                     Param('ids', GET, list, required=False),
                     Param('number', GET, str, required=False),
                     Param('detail_number', GET, str, required=False),
                     Param('sender_name', GET, str, required=False),
                     Param('sender_phone',
                           GET,
                           str,
                           required=False,
                           rules=[NumberRule()]),
                     Param('seller_name', GET, str, required=False),
                     Param('product_name', GET, str, required=False),
                     Param('start_date',
                           GET,
                           str,
                           required=False,
                           rules=[DateRule()]),
                     Param('end_date',
                           GET,
                           str,
                           required=False,
                           rules=[DateRule()]),
                     Param('attributes', GET, list, required=False),
                     Param('order_by', GET, str, required=False))
    def get(self, *args):
        data = {
            'permission': g.permission_type_id,
            'account': g.account_id,
            'permission': 1,
            'account': 1,
            'status': args[0],
            'ids': args[1],
            'number': args[2],
            'detail_number': args[3],
            'sender_name': args[4],
            'sender_phone': args[5],
            'seller_name': args[6],
            'product_name': args[7],
            'start_date': args[8],
            'end_date': args[9],
            'attributes': args[10],
            'order_by': args[11]
        }
        """GET 메소드: 주문 리스트 엑셀 다운로드     
            
            Args:
                args = ('status', 'ids', 'number', 'detail_number', 'sender_name', 'sender_phone', 'seller_name', 
                'product_name', 'start_date', 'end_date', 'seller_attributes', 'order_by')

            Author: 김민서

            Returns: {'message': 'success'}

            Raises:
                400, {'message': 'key_error', 
                        'errorMessage': 'key error'} : 잘못 입력된 키값

                400, {'message': 'unable_to_close_database', 
                        'errorMessage': 'unable to close database'}: 커넥션 종료 실패

                500, {'message': 'internal_server_error',
                             'errorMessage': 'internal server error'} : 알 수 없는 에러

            History:
                    2021-01-13(김민서): 초기 생성
        """

        try:
            status = data['status']
            today = date.today().strftime('%Y%m%d')

            if status == 1:
                status = '상품준비'
            if status == 2:
                status = '배송중'
            if data['ids']:
                choice = '선택'
            if not data['ids']:
                choice = '전체'

            # 파일 및 시트 이름 생성
            data['file_name'] = f"{today}_{choice}주문엑셀다운로드_{status}_브랜디.xlsx"
            data['sheet_name'] = today

            connection = get_connection(self.database)
            return self.service.create_excel_service(connection, data)
        except Exception as e:
            raise e
        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')
class DestinationView(MethodView):

    def __init__(self, service, database):
        self.service = service
        self.database = database

    @signin_decorator(False)
    def get(self):
        """GET 메소드:   해당 유저에 대한 배송지 정보 받아오기

        유저에 관련된 모든 배송지 정보를 조회 및 반환한다.

        Args:
            g.account_id        : 데코레이터에서 넘겨받은 유저 정보
            g.permission_type_id: 권한정보

        Author: 김기용

        Returns: 200, {'message': 'success', 'result': 유저 배송지 정보들}: 배송지 조회 성공

        Raises:
            400, {'message': 'key error', 'errorMessage': '키 값이 일치하지 않습니다.'}
            500, {'message': 'unable to close database', 'errorMessage': '커넥션 종료 실패'}:
            500, {'message': 'internal server error', 'errorMessage': format(e)})

        History:
            2020-12-29(김기용): 초기 생성
            2021-01-02(김기용): 데코레이터 수정
        """

        connection = None

        try:
            data = dict()
            if 'account_id' in g:
                data['account_id'] = g.account_id
            if 'permission_type_id' in g:
                data['permission_type_id'] = g.permission_type_id
            connection = get_connection(self.database)
            destination_detail = self.service.get_destination_detail_by_user_service(connection, data)
            return {'message': 'success', 'result': destination_detail}

        except Exception as e:
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('서버에서 알 수 없는 에러가 발생했습니다.')

    @signin_decorator(True)
    @validate_params(
        Param('recipient', JSON, str),
        Param('phone', JSON, str, rules=[PhoneRule()]),
        Param('address1', JSON, str),
        Param('address2', JSON, str),
        Param('post_number', JSON, str, rules=[PostalCodeRule()]),
    )
    def post(self, *args):
        """POST 메소드:  배송지 추가

        사용자가 입력한 배송지 정보를 받아 데이터베이스에 추가한다.
        최대 배송지 생성 개수는 5개이다.

        Args:
            args:
                'recipient'  : 수신자
                'phone'      : 폰번호
                'address1'   : 메인주소
                'address2'   : 상세주소
                'post_number': 우편번호

                g.account_id        : 데코레이터에서 넘겨받은 어카운트 아이디
                g.permission_type_id: 데코레이터에서 넘겨받은 권한 아이디

        Author: 김기용

        Returns: 201, {'message': 'success'}: 배송지 생성 성공

        Raises:
            400, {'message': 'invalid_parameter', 'error_message': '[데이터]가(이) 유효하지 않습니다.'}
            500, {'message': 'unable_to_close_database', 'errorMessage': '커넥션 종료 실패'}
            500, {'message': 'internal_server_error', 'errorMessage': format(e)})

        History:
            2020-12-28(김기용): 초기 생성
            2020-12-29(김기용): 데코레이터 추가
            2020-12-30(김기용): 수정된 데코레이터반영: 데코레이터에서 permission_type 을 받음
            2021-01-02(김기용): 수정된 데코레이터 반영: signin_decorator(True)
        """
        connection = None

        try:
            data = {
                'user_id': g.account_id,
                'permission_type_id': g.permission_type_id,
                'recipient': args[0],
                'phone': args[1],
                'address1': args[2],
                'address2': args[3],
                'post_number': args[4],
            }

            connection = get_connection(self.database)
            self.service.create_destination_service(connection, data)
            connection.commit()
            return {'message': 'success'}

        except Exception as e:
            connection.rollback()
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('서버에서 알 수 없는 에러가 발생했습니다.')

    @signin_decorator(True)
    @validate_params(
        Param('destination_id', JSON, str, rules=[NumberRule()]),
        Param('recipient', JSON, str),
        Param('phone', JSON, str, rules=[PhoneRule()]),
        Param('address1', JSON, str),
        Param('address2', JSON, str),
        Param('post_number', JSON, str, rules=[PostalCodeRule()]),
        Param('default_location', JSON, str, rules=[IsDeleteRule()])
    )
    def patch(self, *args):
        """ PATCH 메소드: 배송지 정보 수정

            사용자가 입력한 배송지 정보를 받아 수정한다.
            
            Args:
                'destination_id'  : 배송지 아이디
                'recipient'       : 수신자
                'phone'           : 폰번호
                'address1'        : 메인주소
                'address2'        : 상세주소
                'post_number'     : 우편번호
                'default_location': 기본 배송지

                g.account_id        : 데코레이터에서 넘겨받은 어카운트 아이디
                g.permission_type_id: 데코레이터에서 넘겨받은 권한 아이디

            Author: 김기용

            Returns: {'message':'success'}

            Raises: 
                500, {'message': 'unable to close database', 'errorMessage': '커넥션 종료 실패'}
                500, {'message': 'internal server error', 'errorMessage': format(e)})
        """
        connection = None

        try:
            data = dict()
            data['destination_id'] = args[0]
            data['recipient'] = args[1]
            data['phone'] = args[2]
            data['address1'] = args[3]
            data['address2'] = args[4]
            data['post_number'] = args[5]
            data['default_location'] = args[6]
            data['account_id'] = g.account_id
            data['permission_type_id'] = g.permission_type_id

            connection = get_connection(self.database)
            self.service.update_destination_info_service(connection, data)
            connection.commit()
            return {'message': 'success'}

        except Exception as e:
            connection.rollback()
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('서버에서 알 수 없는 에러가 발생했습니다')

    @signin_decorator(True)
    @validate_params(
        Param('destination_id', JSON, str, rules=[NumberRule()])
    )
    def delete(self, *args):
        """DELETE 메소드:  배송지 삭제

        Args:
            'destination_id': 배송지 아이디

            g.account_id           : 데코레이터에서 넘겨받은 account_id
            g.permission_type_id   : 데코레이터에서 넘겨받은 권한 아이디
        Author: 김기용

        Returns: 200, {'message': 'success'}: 배송지 삭제 성공

        Raises:
            500, {'message': 'unable_to_close_database', 'errorMessage': '커넥션 종료 실패'}
            500, {'message': 'internal_server_error', 'errorMessage': format(e)}): 서버 에러

        History:
            2020-12-29(김기용): 초기 생성
            2020-12-30(김기용): 데코레이터 추가
        """

        connection = None
        
        try:
            data = dict()
            data['destination_id'] = args[0]
            data['account_id'] = g.account_id
            data['permission_type_id'] = g.permission_type_id

            connection = get_connection(self.database)
            self.service.delete_destination_service(connection, data)
            connection.commit()
            return {'message': 'success'}

        except Exception as e:
            connection.rollback()
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('서버에서 알 수 없는 에러가 발생했습니다')
Esempio n. 11
0
class SampleUserView(MethodView):
    """ Presentation Layer

    Attributes:
        database: app.config['DB']에 담겨있는 정보(데이터베이스 관련 정보)
        service : TestUserService 클래스

    Author: 홍길동

    History:
        2020-20-20(홍길동): 초기 생성
        2020-20-21(홍길동): 1차 수정
        2020-20-22(홍길동): 2차 수정
    """
    def __init__(self, service, database):
        self.service = service
        self.database = database

    @validate_params(
        Param('user_id', JSON, str, rules=[NumberRule()]), )
    def get(self, *args):
        data = {'user_id': args[0]}
        """GET 메소드: 해당 유저의 정보를 조회.

        user_id 에 해당되는 유저를 테이블에서 조회 후 가져온다.

        Args: args = ('user_id, )

        Author: 홍길동

        Returns:
            return {"message": "success", "result": [{"age": "18", "gender": "남자", "id": 12, "name": "홍길동"}]}

        Raises:
            400, {'message': 'key error', 'errorMessage': 'key_error'}                              : 잘못 입력된 키값
            400, {'message': 'user does not exist error', 'errorMessage': 'user_does_not_exist'}    : 유저 정보 조회 실패
            400, {'message': 'unable to close database', 'errorMessage': 'unable_to_close_database'}: 커넥션 종료 실패
            500, {'message': 'internal server error', 'errorMessage': format(e)})                   : 서버 에러

        History:
            2020-20-20(홍길동): 초기 생성
            2020-20-21(홍길동): 1차 수정
            2020-20-22(홍길동): 2차 수정
        """

        try:
            connection = get_connection(self.database)
            user = self.service.get_sample_user_service(connection, data)
            return jsonify({'message': 'success', 'result': user}), 200

        except Exception as e:
            raise e
        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')

    @validate_params(Param('name', JSON, str, rules=[AlphabeticRule()]),
                     Param('gender', JSON, str, rules=[GenderRule()]),
                     Param('age', JSON, str, rules=[NumberRule()]))
    def post(self, *args):
        data = {'name': args[0], 'gender': args[1], 'age': args[2]}
        """POST 메소드: 유저생성

        Args: args = ('name', 'gender', 'age')

        Author: 홍길동

        Returns:
            200, {'message': 'success'}                                                             : 유저 생성 성공

        Raises:
            400, {'message': 'key error', 'errorMessage': 'key_error'}                              : 잘못 입력된 키값
            400, {'message': 'user create error', 'errorMessage': 'user_create_error'}              : 유저 생성 실패
            403, {'message': 'user already exist', errorMessage': 'already_exist'}                  : 중복 유저 생성 실패
            400, {'message': 'unable to close database', 'errorMessage': 'unable_to_close_database'}: 커넥션 종료 실패
            500, {'message': 'internal server error', 'errorMessage': format(e)})                   : 서버 에러

        History:
            2020-20-20(홍길동): 초기 생성
            2020-20-21(홍길동): 1차 수정
            2020-20-22(홍길동): 2차 수정
        """

        try:
            connection = get_connection(self.database)
            self.service.post_sample_user_service(connection, data)
            connection.commit()
            return {'message': 'success'}

        except Exception as e:
            connection.rollback()
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')

    @validate_params(Param('user_id', JSON, str),
                     Param('age', JSON, str, rules=[NumberRule()]))
    def patch(self, *args):
        data = {'user_id': args[0], 'age': args[1]}
        """PATCH 메소드: 유저 정보 수정

        Args: args = ('user_id', 'age')

        Author: 홍길동

        Returns:
            200, {'message': 'success'}                                                             : 유저 생성 성공

        Raises:
            400, {'message': 'key error', 'errorMessage': 'key_error'}                              : 잘못 입력된 키값
            400, {'message': 'unable to update', 'errorMessage': 'unable_to_update'}                : 유저 정보 수정 실패
            400, {'message': 'unable to close database', 'errorMessage': 'unable_to_close_database'}: 커넥션 종료 실패
            500, {'message': 'internal server error', 'errorMessage': format(e)})                   : 서버 에러

        History:
            2020-20-20(홍길동): 초기 생성
            2020-20-21(홍길동): 1차 수정
            2020-20-22(홍길동): 2차 수정
        """

        try:
            connection = get_connection(self.database)
            self.service.patch_sample_user_service(connection, data)
            connection.commit()
            return {'message': 'success'}

        except Exception as e:
            connection.rollback()
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')
Esempio n. 12
0
class SellerInfoView(MethodView):
    """ Presentation Layer

        Attributes:
            database: app.config['DB']에 담겨있는 정보(데이터베이스 관련 정보)
            service : SellerInfoService 클래스

        Author:
            이영주

        History:
            2020-12-28(이영주): 초기 생성
    """
    def __init__(self, service, database):
        self.service = service
        self.database = database

    @validate_params(
        Param('account_id', PATH, str, required=True, rules=[NumberRule()]), )
    def get(self, *args):
        """ GET 메소드: 셀러 상세정보 조회

            Args:
                account_id

            Author:
                이영주

            Returns:
                200, {'message': 'success', 'result': result}                                           : 상세정보 조회 성공

            Raises:
                400, {'message': 'key error', 'errorMessage': 'key_error'}                              : 잘못 입력된 키값
                400, {'message': 'seller does not exist error', 'errorMessage': 'seller_does_not_exist'}: 셀러 정보 조회 실패
                400, {'message': 'unable to close database', 'errorMessage': 'unable_to_close_database'}: 커넥션 종료 실패
                500, {'message': 'internal server error', 'errorMessage': format(e)})                   : 서버 에러

            History:
                2020-12-28(이영주): 초기 생성
        """

        # @ 데코레이터
        data = {
            'account_id': args[0],
        }
        try:
            connection = get_connection(self.database)
            result = self.service.get_seller_info(connection, data)
            return jsonify({'message': 'success', 'result': result}), 200

        except Exception as e:
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')

    @validate_params(
        # required True
        Param('profile_image_url',
              FORM,
              str,
              required=True,
              rules=[DefaultRule()]),
        Param('seller_title', FORM, str, required=True, rules=[DefaultRule()]),
        Param('contact_name', FORM, str, required=True, rules=[DefaultRule()]),
        Param('contact_phone', FORM, str, required=True,
              rules=[DefaultRule()]),
        Param('contact_email', FORM, str, required=True,
              rules=[DefaultRule()]),
        Param('service_center_number',
              FORM,
              str,
              required=True,
              rules=[DefaultRule()]),
        Param('post_number', FORM, str, required=True, rules=[DefaultRule()]),
        Param('address1', FORM, str, required=True, rules=[DefaultRule()]),
        Param('address2', FORM, str, required=True, rules=[DefaultRule()]),
        Param('operation_start_time', FORM, str, required=True),
        Param('operation_end_time', FORM, str, required=True),
        Param('shipping_information',
              FORM,
              str,
              required=True,
              rules=[DefaultRule()]),
        Param('exchange_information',
              FORM,
              str,
              required=True,
              rules=[DefaultRule()]),
        # required False
        Param('background_image_url',
              FORM,
              str,
              required=False,
              rules=[DefaultRule()]),
        Param('seller_discription',
              FORM,
              str,
              required=False,
              rules=[DefaultRule()]),
        Param('is_weekend', FORM, str, required=False, rules=[DefaultRule()]),
        Param('weekend_operation_start_time',
              FORM,
              str,
              required=False,
              rules=[DefaultRule()]),
        Param('weekend_operation_end_time',
              FORM,
              str,
              required=False,
              rules=[DefaultRule()]),
        # master
        Param('name', FORM, str, required=False, rules=[DefaultRule()]),
        Param('english_name', FORM, str, required=False,
              rules=[DefaultRule()]),
        # permission_type
        Param('account_id', FORM, str, required=True, rules=[DefaultRule()]),
        Param('permission_types',
              FORM,
              str,
              required=True,
              rules=[DefaultRule()]),
        # histories
        Param('seller_status_type_id',
              FORM,
              str,
              required=True,
              rules=[DefaultRule()]),
        Param('seller_id', FORM, str, required=True, rules=[DefaultRule()]),
        Param('updater_id', FORM, str, required=True, rules=[DefaultRule()]))
    # password 변경
    def patch(self, *args):
        """ PATCH 메소드: 셀러 정보 수정

            Author: 이영주

            Returns:
                200, {'message': 'success', 'result': result}                                           : 셀러 정보변경

            Raises:
                400, {'message': 'key error', 'errorMessage': 'key_error'}                              : 잘못 입력된 키값
                400, {'message': 'unable to update', 'errorMessage': 'unable_to_update'}                : 셀러 정보 수정 실패
                400, {'message': 'unable to close database', 'errorMessage': 'unable_to_close_database'}: 커넥션 종료 실패
                500, {'message': 'internal server error', 'errorMessage': format(e)})                   : 서버 에러

            History:
                2020-12-29(이영주): 초기 생성
        """
        try:
            add_contact = json.loads(request.form.get("add_contact", "1"))
            data = {
                'profile_image_url':
                request.form.get('profile_image_url'),
                'background_image_url':
                request.form.get('background_image_url'),
                'seller_title':
                request.form.get('seller_title'),
                'seller_discription':
                request.form.get('seller_discription'),
                'contact_name':
                request.form.get('contact_name'),
                'contact_phone':
                request.form.get('contact_phone'),
                'contact_email':
                request.form.get('contact_email'),
                'post_number':
                request.form.get('post_number'),
                'service_center_number':
                request.form.get('service_center_number'),
                'address1':
                request.form.get('address1'),
                'address2':
                request.form.get('address2'),
                'operation_start_time':
                request.form.get('operation_start_time'),
                'operation_end_time':
                request.form.get('operation_end_time'),
                'is_weekend':
                request.form.get('is_weekend'),
                'weekend_operation_start_time':
                request.form.get('weekend_operation_start_time'),
                'weekend_operation_end_time':
                request.form.get('weekend_operation_end_time'),
                'shipping_information':
                request.form.get('shipping_information'),
                'exchange_information':
                request.form.get('exchange_information'),
                'name':
                request.form.get('name'),
                'english_name':
                request.form.get('english_name'),
                'account_id':
                request.form.get('account_id'),
                'permission_types':
                request.form.get('permission_types'),
                'seller_status_type_id':
                request.form.get('seller_status_type_id'),
                'seller_id':
                request.form.get('account_id'),
                'updater_id':
                request.form.get('permission_types'),
                'add_contact':
                add_contact
            }
            connection = get_connection(self.database)

            # master - update seller table
            self.service.patch_master_info(connection, data)

            # update sellers table
            self.service.patch_seller_info(connection, data)

            # update additional_contacts table
            self.service.patch_add_contact(connection, data)

            # update seller_histories
            self.service.patch_seller_history(connection, data)

            connection.commit()
            return jsonify({'message': 'success', 'result': data}), 200

        except Exception as e:
            connection.rollback()
            raise e

        finally:
            try:
                if connection:
                    connection.close()
            except Exception:
                raise DatabaseCloseFail('database close fail')