def products_over_1000(request):
    if request.method == "GET":
        with sqlite3.connect(Connection.db_path) as conn:
            conn.row_factory = sqlite3.Row
            db_cursor = conn.cursor()

            cmd = """
                    SELECT 
                        p.name,
                        p.price
                    FROM bangazonapi_product p 
                    WHERE p.price >= 1000
                    ORDER BY p.price DESC
                """
            db_cursor.execute(cmd)

            dataset = db_cursor.fetchall()

            list_of_products = []

            for row in dataset:
                product = Product()
                product.name = row['name']
                product.price = row['price']
                list_of_products.append(product)

            template = 'products/expensiveproducts.html'
            context = {'expensive_products': list_of_products}

            return render(request, template, context)
    def setUp(self) -> None:
        """
        Create a new account and create sample category
        """
        url = "/register"
        data = {"username": "******", "password": "******", "email": "*****@*****.**",
                "address": "100 Infinity Way", "phone_number": "555-1212", "first_name": "Steve", "last_name": "Brownlee"}
        response = self.client.post(url, data, format='json')
        json_response = json.loads(response.content)
        self.token = json_response["token"]
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

        url = "/productcategories"
        data = {"name": "Sporting Goods"}
        self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)

        response = self.client.post(url, data, format='json')
        json_response = json.loads(response.content)

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(json_response["name"], "Sporting Goods")

        self.product = Product()
        self.product.name = "Kite"
        self.product.price = 14.99
        self.product.quantity = 60
        self.product.description = "It flies high"
        self.product.category_id = 1
        self.product.location = "Pittsburgh"
        self.product.customer_id = 1
        self.product.save()
def highproductprice_list(request):
    if request.method == 'GET':
        # Connect to project database
        with sqlite3.connect(Connection.db_path) as conn:
            conn.row_factory = sqlite3.Row
            db_cursor = conn.cursor()

            # Query for all products, with related price info.
            db_cursor.execute("""
              SELECT 
                p.name,
                p.description,
                p.price
              FROM bangazonapi_product p
              WHERE p.price >= 1000
            """)

            dataset = db_cursor.fetchall()

            products_priced_over_thousand = []

            for row in dataset:
                # Create a Product instance and set its properties. String in brackets matches the SQL results
                product = Product()
                product.name = row["name"]
                product.description = row["description"]
                product.price = row["price"]

                products_priced_over_thousand.append(product)

        # Specify the Django template and provide data context
        template = 'products/products_over_1000.html'
        context = {'highproductprice_list': products_priced_over_thousand}

        return render(request, template, context)
    def create(self, request):
        """Handle POST operations
        Returns:
            Response -- JSON serialized Product instance
        """
        new_product = Product()
        new_product.name = request.data["name"]
        new_product.customer = Customer.objects.get(user=request.auth.user)
        new_product.price = request.data["price"]
        new_product.description = request.data["description"]
        new_product.quantity = request.data["quantity"]
        new_product.created_at = request.data["created_at"]
        new_product.product_type = ProductType.objects.get(
            pk=request.data["product_type"])
        new_product.location = request.data["location"]
        new_product.save()

        serializer = ProductSerializer(new_product,
                                       context={'request': request})

        return Response(serializer.data)
    def create(self, request):
        """
        @api {POST} /products POST new product
        @apiName CreateProduct
        @apiGroup Product

        @apiHeader {String} Authorization Auth token
        @apiHeaderExample {String} Authorization
            Token 9ba45f09651c5b0c404f37a2d2572c026c146611

        @apiParam {String} name Short form name of product
        @apiParam {Number} price Cost of product
        @apiParam {String} description Long form description of product
        @apiParam {Number} quantity Number of items to sell
        @apiParam {String} location City where product is located
        @apiParam {Number} category_id Category of product
        @apiParamExample {json} Input
            {
                "name": "Kite",
                "price": 14.99,
                "description": "It flies high",
                "quantity": 60,
                "location": "Pittsburgh",
                "category_id": 4
            }

        @apiSuccess (200) {Object} product Created product
        @apiSuccess (200) {id} product.id Product Id
        @apiSuccess (200) {String} product.name Short form name of product
        @apiSuccess (200) {String} product.description Long form description of product
        @apiSuccess (200) {Number} product.price Cost of product
        @apiSuccess (200) {Number} product.quantity Number of items to sell
        @apiSuccess (200) {Date} product.created_date City where product is located
        @apiSuccess (200) {String} product.location City where product is located
        @apiSuccess (200) {String} product.image_path Path to product image
        @apiSuccess (200) {Number} product.average_rating Average customer rating of product
        @apiSuccess (200) {Number} product.number_sold How many items have been purchased
        @apiSuccess (200) {Object} product.category Category of product
        @apiSuccessExample {json} Success
            {
                "id": 101,
                "url": "http://localhost:8000/products/101",
                "name": "Kite",
                "price": 14.99,
                "number_sold": 0,
                "description": "It flies high",
                "quantity": 60,
                "created_date": "2019-10-23",
                "location": "Pittsburgh",
                "image_path": null,
                "average_rating": 0,
                "category": {
                    "url": "http://localhost:8000/productcategories/6",
                    "name": "Games/Toys"
                }
            }
        """
        new_product = Product()
        new_product.name = request.data["name"]
        new_product.price = request.data["price"]
        new_product.description = request.data["description"]
        new_product.quantity = request.data["quantity"]
        new_product.location = request.data["location"]

        customer = Customer.objects.get(user=request.auth.user)
        new_product.customer = customer

        product_category = ProductCategory.objects.get(
            pk=request.data["category_id"])
        new_product.category = product_category

        if "image_path" in request.data:
            format, imgstr = request.data["image_path"].split(';base64,')
            ext = format.split('/')[-1]
            data = ContentFile(
                base64.b64decode(imgstr),
                name=f'{new_product.id}-{request.data["name"]}.{ext}')

            new_product.image_path = data

        new_product.save()

        serializer = ProductSerializer(new_product,
                                       context={'request': request})

        return Response(serializer.data, status=status.HTTP_201_CREATED)
class ProductTests(APITestCase):
    def setUp(self) -> None:
        """
        Create a new account and create sample category
        """
        url = "/register"
        data = {"username": "******", "password": "******", "email": "*****@*****.**",
                "address": "100 Infinity Way", "phone_number": "555-1212", "first_name": "Steve", "last_name": "Brownlee"}
        response = self.client.post(url, data, format='json')
        json_response = json.loads(response.content)
        self.token = json_response["token"]
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

        url = "/productcategories"
        data = {"name": "Sporting Goods"}
        self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)

        response = self.client.post(url, data, format='json')
        json_response = json.loads(response.content)

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(json_response["name"], "Sporting Goods")

        self.product = Product()
        self.product.name = "Kite"
        self.product.price = 14.99
        self.product.quantity = 60
        self.product.description = "It flies high"
        self.product.category_id = 1
        self.product.location = "Pittsburgh"
        self.product.customer_id = 1
        self.product.save()

    def test_create_product(self):
        """
        Ensure we can create a new product.
        """
        url = "/products"
        data = {
            "name": "Kite",
            "price": 14.99,
            "quantity": 60,
            "description": "It flies high",
            "category_id": 1,
            "location": "Pittsburgh"
        }
        self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
        response = self.client.post(url, data, format='json')
        json_response = json.loads(response.content)

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(json_response["name"], "Kite")
        self.assertEqual(json_response["price"], 14.99)
        self.assertEqual(json_response["quantity"], 60)
        self.assertEqual(json_response["description"], "It flies high")
        self.assertEqual(json_response["location"], "Pittsburgh")

    def test_update_product(self):
        """
        Ensure we can update a product.
        """
        self.test_create_product()

        url = "/products/1"
        data = {
            "name": "Kite",
            "price": 24.99,
            "quantity": 40,
            "description": "It flies very high",
            "category_id": 1,
            "created_date": datetime.date.today(),
            "location": "Pittsburgh"
        }
        self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
        response = self.client.put(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

        response = self.client.get(url, data, format='json')
        json_response = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(json_response["name"], "Kite")
        self.assertEqual(json_response["price"], 24.99)
        self.assertEqual(json_response["quantity"], 40)
        self.assertEqual(json_response["description"], "It flies very high")
        self.assertEqual(json_response["location"], "Pittsburgh")

    def test_get_all_products(self):
        """
        Ensure we can get a collection of products.
        """
        self.test_create_product()
        self.test_create_product()
        self.test_create_product()

        url = "/products"

        response = self.client.get(url, None, format='json')
        json_response = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(json_response), 4)

    def test_delete_product(self):
        """
        Ensure we can delete a product.
        """
        category = ProductCategory()
        category.name =  "Toys"
        category.save()

        product = Product()
        product.customer_id = 1 
        product.name = "Nerf Gun"
        product.price = 24.99
        product.description = "High powered fun"
        product.quantity = 25
        product.category = category
        product.created_date = datetime.date.today()
        product.location = "Nashville"
        product.image_path = ""
        product.save()

        self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)

        product_url = f"/products/{product.id}"


        response = self.client.delete(product_url)
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

        response = self.client.get(product_url)
        self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
        
    def test_product_rated(self):
        """
        Ensure a product can be rated and that rating is read correctly
        """

        product_rating = ProductRating()
        product_rating.product = self.product
        product_rating.customer_id = 1
        product_rating.rating = 4
        product_rating.save()

        
        product_rating2 = ProductRating()
        product_rating2.product = self.product
        product_rating2.customer_id = 1
        product_rating2.rating = 2
        product_rating2.save()

        url = F"/products/{self.product.id}"

        response = self.client.get(url, None, format='json')
        json_response = json.loads(response.content)


        self.assertEqual(json_response["average_rating"], 3)    
    def test_delete_product(self):
        """
        Ensure we can delete a product.
        """
        category = ProductCategory()
        category.name =  "Toys"
        category.save()

        product = Product()
        product.customer_id = 1 
        product.name = "Nerf Gun"
        product.price = 24.99
        product.description = "High powered fun"
        product.quantity = 25
        product.category = category
        product.created_date = datetime.date.today()
        product.location = "Nashville"
        product.image_path = ""
        product.save()

        self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)

        product_url = f"/products/{product.id}"


        response = self.client.delete(product_url)
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

        response = self.client.get(product_url)
        self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
    def create(self, request, format=None):
        newproduct = Product()
        # product type refers to a foreign key
        product_type = ProductType.objects.get(pk=request.data["product_type"])

        # customer refers to the user
        customer = Customer.objects.get(user=request.auth.user)
        # request all other data
        newproduct.title = request.data["title"]
        newproduct.price = request.data["price"]
        newproduct.description = request.data["description"]
        newproduct.quantity = request.data["quantity"]
        newproduct.location = request.data["location"]
        newproduct.image_path = request.data["image_path"]
        newproduct.customer = customer
        newproduct.product_type = product_type
        newproduct.created_at = datetime.now()

        newproduct.save()

        serializer = SellSerializer(newproduct, context={'request': request})

        return Response(serializer.data)
    def create(self, request):
        """Handle POST operations

        Returns:
            Response -- JSON serialized Product instance
        """
        new_product = Product()
        new_product.name = request.data["name"]
        new_product.price = request.data["price"]
        new_product.description = request.data["description"]
        new_product.quantity = request.data["quantity"]
        new_product.location = request.data["location"]
        new_product.image_path = request.data["image_path"]
        new_product.customer_id = request.auth.user.customer.id
        new_product.product_type_id = request.data["product_type_id"]

        new_product.save()

        serializer = ProductsSerializer(new_product,
                                        context={'request': request})

        return Response(serializer.data)
def products_over_1000(request):
    if request.method == 'GET':

        # import pdb; pdb.set_trace()
        with sqlite3.connect(Connection.db_path) as conn:

            conn.row_factory = sqlite3.Row
            db_cursor = conn.cursor()

            db_cursor.execute("""
               SELECT
                p.id,
                p.name,
                p.price,
                p.description,
                p.quantity,
                p.created_date,
                p.location,
                c.name AS category,
                p.customer_id
                                
                FROM bangazonapi_product p 
                JOIN bangazonapi_productcategory c ON c.id = p.category_id
                WHERE p.price > 1000
                ORDER By price DESC 

            """)

        dataset = db_cursor.fetchall()

        products = []

        for row in dataset:

            category = ProductCategory.objects.get(name=row["category"])
            customer = Customer.objects.get(pk=row["customer_id"])

            product = Product()
            product.id = row["id"]
            product.category = category
            product.created_date = row["created_date"]
            product.location = row["location"]
            product.price = row["price"]
            product.quantity = row["quantity"]
            product.customer = customer
            product.name = row["name"]
            product.description = row["description"]

            products.append(product)

    template = 'products_over_1000.html'
    context = {"products_over_1000": products}

    return render(request, template, context)
    def test_delete_product(self):
        product = Product()
        product.name = "Kite"
        product.price = 24.99
        product.quantity = 40
        product.description = "It flies very high"
        product.category_id = 1
        product.created_date = datetime.date.today()
        product.location = "Pittsburgh"
        product.customer_id = 1
        product.save()

        self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
        response = self.client.delete(f"/products/{product.id}")
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
        response = self.client.get(f"/products/{product.id}")
        self.assertEqual(response.status_code,
                         status.HTTP_500_INTERNAL_SERVER_ERROR)