Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion server/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# Ignore the workspace folder
workspace/
workspace/
__pycache__
Binary file removed server/farmapp/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file removed server/farmapp/__pycache__/__init__.cpython-313.pyc
Binary file not shown.
Binary file removed server/farmapp/__pycache__/admin.cpython-312.pyc
Binary file not shown.
Binary file removed server/farmapp/__pycache__/admin.cpython-313.pyc
Binary file not shown.
Binary file removed server/farmapp/__pycache__/apps.cpython-312.pyc
Binary file not shown.
Binary file removed server/farmapp/__pycache__/apps.cpython-313.pyc
Binary file not shown.
Binary file removed server/farmapp/__pycache__/models.cpython-312.pyc
Binary file not shown.
Binary file removed server/farmapp/__pycache__/models.cpython-313.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed server/farmapp/__pycache__/urls.cpython-312.pyc
Binary file not shown.
Binary file removed server/farmapp/__pycache__/urls.cpython-313.pyc
Binary file not shown.
Binary file removed server/farmapp/__pycache__/views.cpython-312.pyc
Binary file not shown.
Binary file removed server/farmapp/__pycache__/views.cpython-313.pyc
Binary file not shown.
7 changes: 4 additions & 3 deletions server/farmapp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,15 @@ class Meta:
class Review(models.Model):
reviewId = models.AutoField(primary_key=True)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
customer = models.ForeignKey(User, on_delete=models.CASCADE, limit_choices_to={'role': 'customer'})
customerId = models.ForeignKey(User, on_delete=models.CASCADE, limit_choices_to={'role': 'customer'})
rating = models.IntegerField()
comment = models.TextField(null=True, blank=True)
createdAt = models.DateTimeField(auto_now_add=True)
updatedAt = models.DateTimeField(auto_now=True)

def __str__(self):
return self.reviewId
return f"Review {self.reviewId}"

class Meta:
db_table = 'Review'
managed = False
Expand All @@ -163,3 +163,4 @@ def __str__(self):
class Meta:
db_table = 'AdminActivityLog'
managed = False

43 changes: 42 additions & 1 deletion server/farmapp/serializers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,46 @@
from rest_framework import serializers
from .models import Order, Product
from .models import Product, Farmer, Review, User

class ProductSerializer(serializers.ModelSerializer):
productId = serializers.IntegerField()
productName = serializers.CharField()
quantity = serializers.IntegerField(source='stockQuantity')
price = serializers.DecimalField(source='unitPrice', max_digits=10, decimal_places=2)
description = serializers.CharField()
imageUrl = serializers.ImageField(source='productImage', required=False)
status = serializers.CharField()
dateAdded = serializers.DateTimeField(source='createdAt')

class Meta:
model = Product
fields = ['productId', 'productName', 'quantity', 'price', 'description', 'imageUrl', 'status', 'dateAdded']


class ProductCreateUpdateSerializer(serializers.ModelSerializer):
productName = serializers.CharField()
quantity = serializers.IntegerField(source='stockQuantity')
price = serializers.DecimalField(source='unitPrice', max_digits=10, decimal_places=2)
description = serializers.CharField()
imageUrl = serializers.ImageField(source='productImage', required=False)
status = serializers.CharField()

class Meta:
model = Product
fields = ['productName', 'quantity', 'price', 'description', 'imageUrl', 'status']


class ReviewSerializer(serializers.ModelSerializer):
class Meta:
model = Review
fields = ['reviewId', 'product', 'customerId', 'rating', 'comment', 'createdAt', 'updatedAt']
read_only_fields = ['reviewId', 'createdAt', 'updatedAt']

def validate_rating(self, value):
if not (1 <= value <= 5):
raise serializers.ValidationError("Rating must be between 1 and 5.")
return value


class OrderDetailSerializer(serializers.ModelSerializer):
"""
Expand Down Expand Up @@ -80,4 +121,4 @@ def validate_status(self, value):

class Meta:
model = Order
fields = ['status']
fields = ['status']
19 changes: 17 additions & 2 deletions server/farmapp/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
from django.urls import path
from .views import DeleteReviewView, OrderDetailView, UpdateOrderStatusView, DeleteOrderView
from . import views

urlpatterns = [
# URL for retrieving order details
# For listing products for a specific farmer
path('api/farmer/<int:farmerId>/products/', views.FarmerProductsListView.as_view(), name='farmer-products-list'),

# For creating a product for a specific farmer
path('api/farmer/<int:farmerId>/products', views.ProductCreateView.as_view(), name='product-create'),

# For updating a product for a specific farmer
path('api/farmer/<int:farmerId>/products/<int:productId>', views.ProductUpdateView.as_view(), name='product-update'),

#For making a product review
path('api/product/<int:productId>/reviews', views.ProductReviewCreateView.as_view(), name='add-review'),

# URL for retrieving order details
path("api/farmer/<int:farmerId>/orders/<int:orderId>", OrderDetailView.as_view(), name="order-detail"),

# URL for updating order status
Expand All @@ -13,4 +25,7 @@

# URL for deleting a review
path("api/product/<int:productId>/reviews/<int:reviewId>", DeleteReviewView.as_view(), name="delete-review"),

]


87 changes: 82 additions & 5 deletions server/farmapp/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,87 @@
from django.db import DatabaseError
from django.shortcuts import get_object_or_404
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.exceptions import ValidationError
from rest_framework.generics import UpdateAPIView
from django.shortcuts import get_object_or_404
from rest_framework.permissions import IsAuthenticated
from .serializers import ReviewSerializer, ProductSerializer, ProductCreateUpdateSerializer
from django.db import DatabaseError
from rest_framework import status, views
from .serializers import OrderDetailSerializer, OrderStatusUpdateSerializer
from .models import Farmer, Order, Product, Review, User
from rest_framework.views import APIView
from .models import Farmer, Order, Product, Review, User,Farmer


class ProductReviewCreateView(APIView):
permission_classes = [IsAuthenticated]

def post(self, request, productId):
# Ensure the product exists
try:
product = Product.objects.get(productId=productId)
except Product.DoesNotExist:
return Response({"error": "Product not found"}, status=status.HTTP_404_NOT_FOUND)

# Prepare review data
review_data = request.data
review_data['product'] = productId # Link the review to the product
review_data['customerId'] = request.user.userId # Set the customer to the current user

# Validate and save the review
serializer = ReviewSerializer(data=review_data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class FarmerProductsListView(APIView):
def get(self, request, farmerId):
# Fetch the Farmer instance by farmerId
farmer = get_object_or_404(Farmer, pk=farmerId)
# Retrieve all products for this farmer
products = Product.objects.filter(farmer=farmer)
serializer = ProductSerializer(products, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)


class ProductCreateView(APIView):
def post(self, request, farmerId):
# Fetch the Farmer instance
farmer = get_object_or_404(Farmer, pk=farmerId)
# Add farmer to the incoming data
data = request.data
data['farmer'] = farmer.farmerId # Associate the product with the farmer

# Serialize and validate the data
serializer = ProductCreateUpdateSerializer(data=data)
if serializer.is_valid():
serializer.save(farmer=farmer)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ProductUpdateView(UpdateAPIView):
serializer_class = ProductCreateUpdateSerializer

# Override lookup_field to use 'productId' instead of 'pk'
lookup_field = 'productId'

def get_queryset(self):
# Get the queryset by filtering products by farmerId and productId
farmerId = self.kwargs['farmerId']
productId = self.kwargs['productId'] # Now we can use 'productId' instead of 'pk'
return Product.objects.filter(farmer_id=farmerId, productId=productId)

def update(self, request, *args, **kwargs):
# Override update method to perform validation and save updated product
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)




class OrderDetailView(APIView):
Expand Down Expand Up @@ -179,4 +256,4 @@ def delete(self, request, productId, reviewId):
except DatabaseError:
# Step 4: Handle potential database errors during deletion
return Response({"error": "An error occurred while attempting to delete the review."},
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Binary file removed server/farmsales/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file removed server/farmsales/__pycache__/__init__.cpython-313.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed server/farmsales/__pycache__/urls.cpython-312.pyc
Binary file not shown.
Binary file removed server/farmsales/__pycache__/urls.cpython-313.pyc
Binary file not shown.
Binary file removed server/farmsales/__pycache__/wsgi.cpython-312.pyc
Binary file not shown.
Binary file removed server/farmsales/__pycache__/wsgi.cpython-313.pyc
Binary file not shown.
7 changes: 4 additions & 3 deletions server/farmsales/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
AUTH_USER_MODEL = 'farmapp.User' # Replace 'yourapp' with the actual name of your app


# Quick-start development settings - unsuitable for production
Expand Down Expand Up @@ -79,10 +80,10 @@
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'CropCircle',
'USER': 'backend_team',
'PASSWORD': 'Akogo660221.',
# 'USER': 'root',
# 'PASSWORD': '2005',
'HOST': 'localhost',
'PORT': '3306',
# 'PORT': '3308',
}
}

Expand Down
2 changes: 1 addition & 1 deletion server/farmsales/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
urlpatterns = [
path('admin/', admin.site.urls),
path('farmapp/', include('farmapp.urls'))
]
]
Binary file added server/product_images/spinach.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added server/product_images/spinach_MVlPCwO.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added server/product_images/spinach_lmtbPMJ.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.