From a682219329f95d9ab89881d0bd6758d2a9252612 Mon Sep 17 00:00:00 2001 From: jayeblack Date: Thu, 14 Nov 2024 23:22:17 -0800 Subject: [PATCH 1/3] [Backend] added endpoints to view,create and update products of a farmer --- .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 182 bytes .../farmapp/__pycache__/admin.cpython-312.pyc | Bin 0 -> 226 bytes .../farmapp/__pycache__/apps.cpython-312.pyc | Bin 0 -> 490 bytes .../__pycache__/models.cpython-312.pyc | Bin 0 -> 9284 bytes .../__pycache__/serializers.cpython-312.pyc | Bin 0 -> 3488 bytes .../farmapp/__pycache__/urls.cpython-312.pyc | Bin 0 -> 1009 bytes .../farmapp/__pycache__/views.cpython-312.pyc | Bin 0 -> 5197 bytes server/farmapp/migrations/0001_initial.py | 127 ++++++++++++++++++ .../__pycache__/0001_initial.cpython-312.pyc | Bin 0 -> 5683 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 193 bytes server/farmapp/models.py | 29 ++-- server/farmapp/serializers.py | 43 ++++++ server/farmapp/urls.py | 17 +++ server/farmapp/views.py | 95 ++++++++++++- .../__pycache__/__init__.cpython-312.pyc | Bin 151 -> 184 bytes .../__pycache__/settings.cpython-312.pyc | Bin 2534 -> 2696 bytes .../__pycache__/urls.cpython-312.pyc | Bin 1020 -> 1138 bytes .../__pycache__/wsgi.cpython-312.pyc | Bin 643 -> 676 bytes server/farmsales/settings.py | 11 +- server/farmsales/urls.py | 5 +- server/product_images/spinach.jpeg | Bin 0 -> 7714 bytes server/product_images/spinach_Io7xRWj.jpeg | Bin 0 -> 7714 bytes server/product_images/spinach_ZqJzNmp.jpeg | Bin 0 -> 7714 bytes server/product_images/spinach_dK9pbw0.jpeg | Bin 0 -> 7714 bytes 24 files changed, 308 insertions(+), 19 deletions(-) create mode 100644 server/farmapp/__pycache__/__init__.cpython-312.pyc create mode 100644 server/farmapp/__pycache__/admin.cpython-312.pyc create mode 100644 server/farmapp/__pycache__/apps.cpython-312.pyc create mode 100644 server/farmapp/__pycache__/models.cpython-312.pyc create mode 100644 server/farmapp/__pycache__/serializers.cpython-312.pyc create mode 100644 server/farmapp/__pycache__/urls.cpython-312.pyc create mode 100644 server/farmapp/__pycache__/views.cpython-312.pyc create mode 100644 server/farmapp/migrations/0001_initial.py create mode 100644 server/farmapp/migrations/__pycache__/0001_initial.cpython-312.pyc create mode 100644 server/farmapp/migrations/__pycache__/__init__.cpython-312.pyc create mode 100644 server/farmapp/serializers.py create mode 100644 server/farmapp/urls.py create mode 100644 server/product_images/spinach.jpeg create mode 100644 server/product_images/spinach_Io7xRWj.jpeg create mode 100644 server/product_images/spinach_ZqJzNmp.jpeg create mode 100644 server/product_images/spinach_dK9pbw0.jpeg diff --git a/server/farmapp/__pycache__/__init__.cpython-312.pyc b/server/farmapp/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef61b0e7fd3cd544b664fd82c13a156ce8cb9f2b GIT binary patch literal 182 zcmX@j%ge<81Wava=^*+sh(HIQS%4zb87dhx8U0o=6fpsLpFwJVg*scsgche36~}nF z2D$orI(jHL`8$TV`nkuXq!wqFKLkdF*V-7mQTYM>5iFxVyddc~DB}JJ@Ma)12D;Yk6)cp!_wu%WYPAw{q@p27v_4Rc0 zP;l~h3~}{yk4Z@_&MwI>h)K)LOU#KcD9X=DO)iN^F3K-R&MZpKNsR$&D@!ekNlPrs tO)Myg0o$inQ2C3)CO1E&G$+-rhy!Q^BM=vZ7$2A!85!>}C={^)IRK<9JRJZ4 literal 0 HcmV?d00001 diff --git a/server/farmapp/__pycache__/apps.cpython-312.pyc b/server/farmapp/__pycache__/apps.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e77c0c45a8c753f7008cb7b28e855db514eb7918 GIT binary patch literal 490 zcmXv~ze~eF6uwJRt!*PBRd5h=5wc_y5fReb)(Tb>T|(f9xl4%VmzPASn^2tH>c1fV zDK3sB;N;{cRF_WPCFu?Ceed4)J>L7?Ww{2}6P|XR7nZ+xF@Kd3Om`R<0}L?qfDd&D zfdF~{3nPF<0^h`frwc<#seJQ7f!UH4MeQ)KUB@cgMTBKBZ89(h1n3Y0UBFNmv7k#s zQIRsaYf|5w%O5uJjTtzhimz2a#Keo$mg{I~5_VnU;cU?^*aM}KRS^nIpCFXg5Mt!i z!B~ctfnjuxJ=rF10*jFxfq!M!Ax~j)>K0NV$`FkQj(%7DiyQvG*aZ zPwLIbBg%jB{y-74dU-DwQ|@gcZ*Y_oml>K>4~qK^=?W{ktueRsM}!c5g6-c00j@pw J{{Tz5>L2KifCT^m literal 0 HcmV?d00001 diff --git a/server/farmapp/__pycache__/models.cpython-312.pyc b/server/farmapp/__pycache__/models.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be750ca8d2f21caf8d126370db0943c3a5818b26 GIT binary patch literal 9284 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 ne!#W5y2$h+MCSzOF<-m^7#{DNZBl;;3 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 literal 0 HcmV?d00001 diff --git a/server/farmapp/migrations/__pycache__/__init__.cpython-312.pyc b/server/farmapp/migrations/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5164110297d9c81261398fe4715881df4410967a GIT binary patch literal 193 zcmX@j%ge<81e?B^rGx0lAOanHW&w&!XQ*V*Wb|9fP{ah}eFmxdmEdd@6Iz^FR2<{w z8szHh>FA;0gOJll3JWyl3x&$mYJ8B6JJo2pOuAwl9``Z91|a(nU`4-AFo$X`HRCQH$SB`C)KWq6=)$N5Ep|O NADI~$8H<>KEC5>uH4p#* literal 0 HcmV?d00001 diff --git a/server/farmapp/models.py b/server/farmapp/models.py index 8a05040d..ebf372f9 100644 --- a/server/farmapp/models.py +++ b/server/farmapp/models.py @@ -16,22 +16,23 @@ class User(AbstractBaseUser): userId = models.AutoField(primary_key=True) name = models.CharField(max_length=255) email = models.EmailField(unique=True) - passwordHash = models.CharField(max_length=255) + password = models.CharField(max_length=255) # Password field role = models.CharField(max_length=10, choices=ROLE_CHOICES) phone = models.CharField(max_length=15, null=True, blank=True) address = models.CharField(max_length=255, null=True, blank=True) createdAt = models.DateTimeField(auto_now_add=True) updatedAt = models.DateTimeField(auto_now=True) - + last_login = models.DateTimeField(null=True, blank=True) + USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['name'] def __str__(self): return self.name - + class Meta: db_table = 'User' - managed = False + managed = True # Set to True or remove to allow migrations # 2. Farmer Model @@ -43,7 +44,8 @@ class Farmer(models.Model): ] farmerId = models.AutoField(primary_key=True) - user = models.OneToOneField(User, on_delete=models.CASCADE, limit_choices_to={'role': 'farmer'}) + # user = models.OneToOneField(User, on_delete=models.CASCADE, limit_choices_to={'role': 'farmer'}) + userId = models.OneToOneField(User, on_delete=models.CASCADE, limit_choices_to={'role': 'farmer'}, related_name='farmer', db_column='userId') farmName = models.CharField(max_length=255) location = models.CharField(max_length=255) farmType = models.CharField(max_length=50) @@ -68,7 +70,8 @@ class Product(models.Model): ] productId = models.AutoField(primary_key=True) - farmer = models.ForeignKey(Farmer, on_delete=models.CASCADE) + # farmer = models.ForeignKey(Farmer, on_delete=models.CASCADE) + farmer = models.ForeignKey(Farmer, on_delete=models.CASCADE, db_column='farmerId') productName = models.CharField(max_length=255) description = models.TextField() category = models.CharField(max_length=50) @@ -95,13 +98,16 @@ class Order(models.Model): ('delivered', 'Delivered'), ] - orderId = models.AutoField(primary_key=True) - customer = models.ForeignKey(User, on_delete=models.CASCADE, limit_choices_to={'role': 'customer'}) + # orderId = models.AutoField(primary_key=True) + # customer = models.ForeignKey(User, on_delete=models.CASCADE, limit_choices_to={'role': 'customer'}) + orderId = models.AutoField(primary_key=True) # Primary key field + customer = models.ForeignKey(User, on_delete=models.CASCADE, db_column='customerId') # ForeignKey to User model orderItems = models.JSONField() # Store an array of products, including productId, quantity, and price totalAmount = models.DecimalField(max_digits=10, decimal_places=2) status = models.CharField(max_length=20, choices=ORDER_STATUS_CHOICES) createdAt = models.DateTimeField(auto_now_add=True) updatedAt = models.DateTimeField(auto_now=True) + deliveryDate = models.DateTimeField(null=True, blank=True) def __str__(self): return self.orderId @@ -130,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 @@ -157,3 +163,4 @@ def __str__(self): class Meta: db_table = 'AdminActivityLog' managed = False + \ No newline at end of file diff --git a/server/farmapp/serializers.py b/server/farmapp/serializers.py new file mode 100644 index 00000000..b031cd7c --- /dev/null +++ b/server/farmapp/serializers.py @@ -0,0 +1,43 @@ +from rest_framework import serializers +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): + product = serializers.PrimaryKeyRelatedField(queryset=Product.objects.all()) + customerId = serializers.PrimaryKeyRelatedField(queryset=User.objects.filter(role='customer')) + + class Meta: + model = Review + fields = ['reviewId', 'product', 'customerId', 'rating', 'comment', 'createdAt', 'updatedAt'] + + def validate_rating(self, value): + if not (1 <= value <= 5): + raise serializers.ValidationError("Rating must be between 1 and 5.") + return value diff --git a/server/farmapp/urls.py b/server/farmapp/urls.py new file mode 100644 index 00000000..e1b6d9a5 --- /dev/null +++ b/server/farmapp/urls.py @@ -0,0 +1,17 @@ +from django.urls import path +from . import views + +urlpatterns = [ + # For listing products for a specific farmer + path('api/farmer//products/', views.FarmerProductsListView.as_view(), name='farmer-products-list'), + + # For creating a product for a specific farmer + path('api/farmer//products', views.ProductCreateView.as_view(), name='product-create'), + + # For updating a product for a specific farmer + path('api/farmer//products/', views.ProductUpdateView.as_view(), name='product-update'), + + #For making a product review + path('api/product//reviews', views.ProductReviewCreateView.as_view(), name='add-review') + +] diff --git a/server/farmapp/views.py b/server/farmapp/views.py index 91ea44a2..7af53eeb 100644 --- a/server/farmapp/views.py +++ b/server/farmapp/views.py @@ -1,3 +1,94 @@ -from django.shortcuts import render +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 .models import Product, Review, User, Farmer +from .serializers import ReviewSerializer, ProductSerializer, ProductCreateUpdateSerializer -# Create your views here. + +class ProductReviewCreateView(APIView): + def post(self, request, productId): + # Log the incoming data for debugging + print("Request Data:", request.data) + + # Extract customerId, rating, and comment from the request data + customer_id = request.data.get('customerId') # Adjust based on field name in payload + rating = request.data.get('rating') + comment = request.data.get('comment') + + # Validate required fields + if rating is None or comment is None or customer_id is None: + raise ValidationError("Missing required fields: rating, comment, or customerId.") + + # Validate rating range: 1-5 + if not (1 <= int(rating) <= 5): + raise ValidationError("Rating must be between 1 and 5.") + + # Fetch product and customer instance based on the passed IDs + product = get_object_or_404(Product, productId=productId) # Corrected this line + customer = get_object_or_404(User, userId=customer_id, role='customer') # customerId should match userId + + # Prepare data for serialization (pass the customer and product references) + review_data = { + 'product': product, # Ensure 'product' field is passed as the actual product object + 'customer': customer, # Ensure 'customer' field is passed as the actual customer object + 'rating': rating, + 'comment': comment + } + + # Use ReviewSerializer to handle review creation and validation + serializer = ReviewSerializer(data=review_data) + if serializer.is_valid(): + serializer.save() + return Response({"review": 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) diff --git a/server/farmsales/__pycache__/__init__.cpython-312.pyc b/server/farmsales/__pycache__/__init__.cpython-312.pyc index 222d460c9a86ceb5d23c887d18d3ed4a87152a36..c93a36871a62cce5e6c56d3f2a47ed6ac8a65a04 100644 GIT binary patch delta 77 zcmbQvxPy`VG%qg~0}wE^nN8$2HVb#QiU}=FEh>)jat(6z^>p-5aPoHyarJYLNl7iv fF3B&5Nz2Sj%!w~3%FjwoE{RDl$}dQs80-Q7OY|7O delta 44 ycmdnNIGvIEG%qg~0}xC*rah6{Sk%nfDkiizwWv5IH?b%)F~+$lzrcB7i3Ksuc>8Phx_y%UhS zX>jFM23!?{f?GFP`wQH-3>Q}luG_kC=}n0T&Uel|ukYORJN`bo{!Ny{0Vdbqcbva+ zAn;!(a=|$WD#}ZzHUN28*mtgVZf9-Qsc^IUHVq6&!6wE;rtaCqe-(U&ME_Ip;}TVf?G2kPV)pDeF6mHVRyf|C`x-n?!HL;- z+zcFNj!mm$_rc5b&b-qu4d;nF$hV2rwJAqjcSyNhHoHxwu4|dy*RIC`TU*&j8$9KW z()0b2LAjD%WLU2n6)GO+)#_onvPZc>xmu&#LAg>RF?PVWg&C*i_Q$*YLxfU35gw~i zyV>?(2p0)3RP;gblF0&d?n+TJ65sZ4QWg zVq3$8#kRKm&*Fn{j&UKTp5p%ybD>ErJ&O8@qzO_iI8tsje^Yw0c7LL-PE>7@Se~dW Z%(<2YmA{&kj<_tF@efXto3{V} delta 378 zcmeAWeI~4anwOW00SKlY(@vM9wn5*5+w}8A}JD4qA8M5VwF;wjMAIs7#$fW z=Q6o6vQ6I1G;MPd^Ij%Psg$h5y!3p%lq9{R#N_PMyp&?S;=-KFl2qd=E}$Tkt;uwY z&DGD{)6ex5i=U&fYZ3S6el|BoM)Aql*lj1Pa6A+>bGC{JElw>ej>%0d%1n%LF3K-( zo@~vj%cTYk21Xz*W|~~YX(aoBkAW|Uv4QIY8v`eA1M33;p$6VhT$|?5KY`|2+IystI#Vpv_Dkiiz zwWv78%QeW=*VEBM!O7n-#MRF|CMC5vyClCLCM`2BF(yx*u4X`I#EIi+F(s003ulP*(r| delta 213 zcmeyw@rPagG%qg~0}xC*rkyU#%)sy%#DM`8DC2X?M0I%uMg}H^RF)K$RHiJj7MLms zoy9XTONt|%F^avCRg-PwiYZJ&jJH?{5=%0w*b-B6GxPNQG&v^cGaF1^!mKE2C%vKQi$%vV2uwU{t)zAoG!p ift9mEVuI;(tBF?A?I+q_W>NmY%*4;s$X&z()BymKK`y5N diff --git a/server/farmsales/__pycache__/wsgi.cpython-312.pyc b/server/farmsales/__pycache__/wsgi.cpython-312.pyc index 318642ba2a682d127747dda9e6569d1000d2b6c2..30d857f79de18fb299bd911a54c7539a3c88772c 100644 GIT binary patch delta 79 zcmZo>UBb$JnwOW00SK7d%rh)K)LOU#KcD9X=DO)iN^F3K-Ro-DzX4FHrU8F2sr delta 46 zcmZ3&+RVy*nwOW00SKlY)85GagHhDT*(xTqIJKxaCO5GtGcm@wD8ImYvL#bC05$v$ AYybcN diff --git a/server/farmsales/settings.py b/server/farmsales/settings.py index f5c2855f..80c121a7 100644 --- a/server/farmsales/settings.py +++ b/server/farmsales/settings.py @@ -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 @@ -37,6 +38,8 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'rest_framework', + 'farmapp', ] MIDDLEWARE = [ @@ -75,12 +78,12 @@ DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.sqlite3', + 'ENGINE': 'django.db.backends.mysql', 'NAME': 'CropCircle', - 'USER': 'backend_team', - 'PASSWORD': 'Akogo660221.', + 'USER': 'root', + 'PASSWORD': '2005', 'HOST': 'localhost', - 'PORT': '3306', + 'PORT': '3308', } } diff --git a/server/farmsales/urls.py b/server/farmsales/urls.py index 7376a3a0..23ded9a7 100644 --- a/server/farmsales/urls.py +++ b/server/farmsales/urls.py @@ -15,8 +15,9 @@ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path +from django.urls import include, path urlpatterns = [ path('admin/', admin.site.urls), -] + path('farmapp/', include('farmapp.urls')) +] \ No newline at end of file diff --git a/server/product_images/spinach.jpeg b/server/product_images/spinach.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..097ab4ad57894fafa1f837dcf8e2badb67e68bdb GIT binary patch literal 7714 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 CB9Tl0 literal 0 HcmV?d00001 diff --git a/server/product_images/spinach_Io7xRWj.jpeg b/server/product_images/spinach_Io7xRWj.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..097ab4ad57894fafa1f837dcf8e2badb67e68bdb GIT binary patch literal 7714 zcmb7HXEYoDv)$Euw_5ZrdRx&&XGNCPiB81o(V`P2I$`zRiPd`$y+-c@(YvV8efiFL z@0|Dd&HS7@bMKiS_sl#mJg)E;*0165U5bYlU=KpX5QHW6)Nzh0I zsQTSdL`Zh$*Pm__Oz_KV%^wHl70iPP;ks{S-SAOu2LA`KJ`t?= zF(#z*QY&4D(>_BrtTBr1dkNHt|KlL>(}P$bp}ArXk0OY?PJQ( zPd`^rZv|q?^eHK+ORY1%*W&%3aiiNfhnVxFSUnX+T z3SxErIl_dXR^X;8OlceH($xF%Uo}CGzf8~l;G#?7KV??5r;UkwBH+66PWrg`*-des zL;eQ8se5ZkN{#$oZ&De-tR@=tMxRRM7jVVs?=;H6b{Unlx!E-WQ)L20wVAkMlw+S|r2*&E6|qOfBtBIN;4 zP++s{#ayyGWmQuMj0oYCn}aNsc_iq=^%vVy;r_}rB8u?ynNXHc8jem%tv*d{ym&np zxBh!!K|t3)RZ595cr5w&y&DM$*|JkM2y6Eem3RDQX`W0tT9LN)X<^{VEpcd^s;Y=B zw1~|_Q&W@Z=lCjCoj(e!)Qy56>vow`Pk_IWL@Qsr-{V2JX#_4GB2fPLHyK#T zR$(0L2WBQIvn!o)SJ|G|EI(@PpmAy*=-=GiIb>6HeR>A`8K<$+o-j=Gk{GXtjgqJm z74;$3?=s!f2JlUo`%u1YOy+GcWW)tX%8#;mBq_x!b4VP{7jm>$`ZuR2QvBv~5v`;l zIPT;#{v_}-IcXL zrzpWJSt`(|w~={)oGK$i&AEE4N1YrryX_LS5l-R3)jwU|&tCYYcb(y+oa_s^;hpNv z8WLz7N9*C2@>6Q$F(x4?2U{W_lPI~IldE2|BFZH8ntpR0l`T^G$#|8&r)37G6m%u6 zU#x-@7l+h!39>>aQ>ZOuNA=GF9xNo&3bh~;S*(h~vF@KTVYSqEqf^06{AJeBGmy#d zNP=WV(KdRCwf(TqGnd*@3T}06FUv4Q5W*!tz zx{r63xPxs;?7XV{o$n75sY{tcBhp9Z8Fzj5!QdttW1R~r!T3Kf5iTC!X1b86`%_5KoqP zakI0uy*>1-d|pRBb&CYnzqIkbZ5;c2jf(r$CcQXO5eGM_1~gS-;dJzdM=D({@2Q#j|x^vK47c1`NMX9mx&vTRc1RElx$@mD8^1OtK*kV zsi*06R(e(kZ`@rYHY>}vql22oZE){ulZfpC+Z1Uy9+4%Z*2lUwm(^-}hRh$0qW%*9 zwm8;%H}VQAFzaRM^4G!udvi;F>5{#$tq|{1YqM_!>@RhS%W3k!94Z&*e<_QsQ3`lI zG+&6gmzLnV#~UO#ImoqE9`BBcP;$L3B?%9o(l+ypqeMOfNG_G*4~aRF3-x=JoeNjz z&zmWG#E|0bU#ZnL2!{{%5AwNp-hPidt(ed1=OLObXW*|!4+OI<3u;7A(L%@m zWHD|1Q9kf*ZthEqE*25=Jg+;U@JTq_whwA51_?ydzKzd#r`{~29bZM|U^QYYTBNvaG~^D!=<4`0b@I`5)9M7&>yD1iaAlEG3uk>`p@U&T@* z?<{G8Ypc5aI+Ul0%MS9a)38q!#p*v-A_r~*Op956YD0#N`SEy41DqfP<7veO_&C3U zPH}=2j~ku=+;ks<_&~2qktMNNiTSKV9o^EWDjUmqunUg}4e&=41=8-^wVZd&{H&zf zAwtB34n>tS&w$1S)KqOH&g~c$#wA&`hHpSR|92!V8C=_>Y|4W(VQ6`Qnf72UpxaSgOqkOX_R!lblOh@1V5z;Q4Qv1brZR3tL1`QvuXY|GR-Qd z$>Z6C@F2bk;EXo1@MR&fZ_T~?4I!s}-2J@&UWKFj-&k^x34%3vb}rSG>c zh?t!3v6dWDJT66^^b9U8N02(30u$d6mJa~#QFUWyDfFtyias{YoFN=T@lUx{pM(C0 zv28jAZy60n>)*>jao@tmAu+V&ya#~VYG_}ph4NGKGc5iIoHu1$CcxjMq7YH zSr8^yxjp`&5vWK^PoQGO=L&;1^xVX>#v*!t4azc~wYgO}i}v}5mdjYD$+~c@1pT}t zk@0hRKh#tsD24xWR^zL11yST{!}X8iG2f(3jj?j=xOO>pcjOA;9%rb7hh1Vh$|kJ- zYIf_fSQX49TNol!!5 zGZ0`f4l#F|$ZRm@dCkOqKDBpfZa5ud(wX^CVTavfY4*wG=_Vv?m_0p}5k+4k=aKCi zyuTg&`0`%jnpXtwANm_1{wcEHW6;TI7xSRcf@S6f7;>I3n5?Rr8_<(@hkeoc1_QVw zl2n|<7*k|Ga=%Y)b#;O93%qV2ZKTR(saxIqZ7HU?e^t0e<-57sf?6!j{y|&yWU}6} zbJzD{xPcqa=VFBtZ>)5wt&?X!(yh_-{RXxY#NoiSxQ9e)vaK2Qou`i^f&Rx0|&<8sZ(SIPvTtHF(;)|_7v)x+-5 zw}}>KL@$HH)JWdRH-f#%v3aegmMHp{<_~)HcfS{N-GV!b+ZHP2o-vkySM~&&%zxo% zquben$$@rk*UinM6iuTJ!K8f4>#&58@m|5&1r=qS`QP8a{}Cz4;O9(iJ~?2-J9`;& zlZ%3Lf7;YYj&mGLl5YqZ>=7g;OT?Z4x{B}w{#{y#)3Od1iY@2VZm|R4>EoU@PkHuS z0W=t_bZHkUY%S|zGcNa^0nxZsI68|gmLk0&eST7&m?6{TNM$W}PAZJx8Sr+2fC6|y z9fI%lse=a^WY+6)AgxStaL9~E=ZZYe8^dRqCxi; zeEP*75G4ig4T|0ubMf-El{!g(Hp;a1KG7LaWR8(x1E*gPx7LeK^)p5zvm7?#kgCPFd*?6fJ+cL zU&9b(F>RVTz@zYNq?o>Rs5_4m#cks~XR7ST%~;YHHioFA{?g_som_XH z7VjOBCBdf9y&>EmR(oe0(u4r95BID*P<7ha6_kyG-uxNlv=rpDUQAy%CI|$f`Iu76 zjqDO(#5Ff`W+Gaym&pmnhZ3w0DHbn2*%ew@3XxB!0OHFDw*CONvW_tLoKs)!|1K-C zm{iG2-t<8cC=qs4fH@qM?HD*%D?nm2h-bWD%=ekv<>z;!<*i&1>eCP;PHRJi*urXx zu^F}%`;#669!>^xm=eqDF!iG`$AB?$FcF7XJJCJ8LAp+z&OB5Z{Asg2LlzkNgC;;H zE`_o|$J+i|L~p`!2-S2Xud@&i&d^t`^73MWd_m%G!ZAqCo0ipu!d={Su8NuYxe?^f zIjoJwcZ}A>-d5?mkSuZtlp-{D@x9&+Ur_0s*yjqf0N1Ub(Wd@2Ql%_CFGsj!nupf# zhT6v|FYan-`RegQnx=il`}})0r&V1o+T_J5?ss`{y;6jO(X^hiUK@!RG5ZT2Vs)C? z=N|C~XbG4T1*00)Rb4|Ka2m~}#KtUSzpaI)$~zRqAF(vadPysjjUFVbY=052LNSuztSc-|+6IN?)!!o021hwlc;n9$E%%&)|ILKO1$CTRQN~ z5FFjjcnKdaFBj0XiRXSFh|X}N%C2(V>r#^3dW}i*G1mGYWN+t-o62zfIKJ@20!B@B zbme7}TrvXkpi-h6s z-gqoluchVHX8?k8+E!i0MulkbGz!y$oyc`a(7YEd+l zAf<#Ctx;z!ho}C{C;8g3M(Oi;$6yG)#zJN{LWqd$oI@If(4t;#1WDigrBFZyAE855 zK{XG&gwwcGYabp$8c28OPLHmvU~eoDoLJ(p6@KYeOU!e}`I#;FnoX%4lZ8Q^Rja_Y z==6CbSE9<;(UGbRn0<6Jc$e;b&H1@b|4&bjCywogM63%)t(xuT_vkNV4~@*rzD9dK znhAPr(RISPr-bLjOD_VZ;4T;O7WiFY>E=(_HbKa8as6fY>)uuLy^nOVsJ^IZ0Ds zL0S0_)y8{B(z#ctSTgUNNcl)I^$v5T4)*2dR_RJ+^A-@I5>a*9Q z{4+M2)ov;a+8p=2_^8}QizDZ|%(1LeWbSO(aYuC2K?}Sb6PZ?MXv&)A4};U#Y{{i;SB1&QHMJ#oI5+O!!s6{(V^~#I z@SA9&+@Ya(5m~2R6iF*uP zzF0gBu=LBj`fl_6w~9$Uc~*BQS)6;A4$y+)1{GM1?_-(=-HpD#sa(9Eg)jc(BBw@( z|8_vio@~*5_ELSyI}DlFjuzCqhAJ@-jN4RC&ja-L9bzlPPaoEiw(n+jH4~ ztk2IkxA@f%jlLaFR$8TCSzQj*DfH`xs>`)(ezr{Rp$SWYY{?xKA{HSkVCbG^F1x|J(p#=@1MmT@kG zQ6aZ_H<)PF>Qrv#<8r&7Eu_S{fRI33PPTiDoz3LG2V!DZ8?5RLT^;jAAXLO(T9*&h zV+?~AuS!`)8ArhiCBzG5b(sLsSd_EO1JAbdj#&VdfjNJsBR1e*@fDQkHqk&sV2|Z-Tf+ zP)%SHTb7x1&H-EK?gAveFMM+sDJx=oLJw<=pTdQPQ(4HTLJ=5rv~N7=+1kH1bv;z@ z6^fi@dwiN4U}UO|3n2?h#C+34FA(8Ps%-Mwj*I)}i?iVlv#@_hBYWO7v$b0gyH!f1Iv`eK``v|jgU{377Dxn1Ea3_Ie(>kk{yz+GEF7+s<7S&ks3 zO#;oE=G0)=FIBWhrIlMeQwf8m)rqZ^QDG?M`aSC}mPr>_Oc%p5fO9=)=7qMwR>i*s zZ-j}aE5{eA7mKuXe*Oq`2$vPO{KY)H>5Vd0#^z-NfonS~&2!1v?uOK-W#pHSd_zzN zV)`s6YBuj5M?SdJE;Ktynea?su{_kU(ka{EsLllHd(%4wV`|PTZ5ZKA09t#j#7(J4pXzAayu>=^|i{p#&7HpQ{fI+_3`#MX^=S?KVWRQC)2Y$_$QMS5&$fO};sXen`tfulCd?C3pz)1c6>TBo zp>iHeVM-;$gBzZUn_)_lE=Vmqvg#Gv)Uvbk3~2A{C%0ASa!22Nj+Bkgr8)7O_3>?WiQ*x!Ls-WvO-^=^za}Kfp_hJq)!Ed+RaMr5F~f6a z8u%#(u2Ps=_RUtGdCro$&`b_Ta%cf~5YUJ^LFrmjf5Ob4|KTk*#%9+>dyvHK-RWr{ zxsLP9pw&H7?>{eXY<2iSgWoycK{r}v#}WDZ>kuo<>WfP3rom`bN53iml{fQG$yM+B=%j{@1(_CjTY_U{@a zcpIY!Y-lwxUU56M{#tm7L>n zix}LSFP)-|S?{t_I-X=LtXu~2u$>qvkw3hTq?$3;UNGgOXXkyLT>otg1o;7D=|hYW^jeaYyNxe6f)&mEkDPwf8~KS{btkQk4$FU-(%S9z z1hHKFxN{1_&w?paeeItFnirD#5SDaE4QP@I)bSIvi55|GR^DCSdavPP#MX-N6ipZ? zZpS3ttpKogW5yw1v8noP)mg56j|0WQryg8f0?yIT?LApauOuoJP)xkfynk2S)Q`Um zD#x(a2=6I{`+*;-tE*AG(du5al*H=lBPB&KM@G#TKJ4b5t|oV5{W5;Z;S3kWd<&*A zH#awgpc=GWU0v19>2&%?7Phblx&5F8ocFpzD`5^F+Xp1g%`MZh8S)uiOGQm&y&aXP z*|QoOZY9jk%>c(uB&01TSH@TSPH+{=JS%sUgE^FC-*@`@`j~V-@(e*+tu-Q>AOOKkAA39l;HJ{}D2q*EpwjHF|9XlRB8g!STg`fRRn6EQaG z%(E0?aDqL68-0VF9XId{H3op4l^x%VNL9cH5(L5#(;ht=gwX~q+xw^fqhzOlUi=T1 CB9Tl0 literal 0 HcmV?d00001 diff --git a/server/product_images/spinach_ZqJzNmp.jpeg b/server/product_images/spinach_ZqJzNmp.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..097ab4ad57894fafa1f837dcf8e2badb67e68bdb GIT binary patch literal 7714 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 CB9Tl0 literal 0 HcmV?d00001 diff --git a/server/product_images/spinach_dK9pbw0.jpeg b/server/product_images/spinach_dK9pbw0.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..097ab4ad57894fafa1f837dcf8e2badb67e68bdb GIT binary patch literal 7714 zcmb7HXEYoDv)$Euw_5ZrdRx&&XGNCPiB81o(V`P2I$`zRiPd`$y+-c@(YvV8efiFL z@0|Dd&HS7@bMKiS_sl#mJg)E;*0165U5bYlU=KpX5QHW6)Nzh0I zsQTSdL`Zh$*Pm__Oz_KV%^wHl70iPP;ks{S-SAOu2LA`KJ`t?= zF(#z*QY&4D(>_BrtTBr1dkNHt|KlL>(}P$bp}ArXk0OY?PJQ( zPd`^rZv|q?^eHK+ORY1%*W&%3aiiNfhnVxFSUnX+T z3SxErIl_dXR^X;8OlceH($xF%Uo}CGzf8~l;G#?7KV??5r;UkwBH+66PWrg`*-des zL;eQ8se5ZkN{#$oZ&De-tR@=tMxRRM7jVVs?=;H6b{Unlx!E-WQ)L20wVAkMlw+S|r2*&E6|qOfBtBIN;4 zP++s{#ayyGWmQuMj0oYCn}aNsc_iq=^%vVy;r_}rB8u?ynNXHc8jem%tv*d{ym&np zxBh!!K|t3)RZ595cr5w&y&DM$*|JkM2y6Eem3RDQX`W0tT9LN)X<^{VEpcd^s;Y=B zw1~|_Q&W@Z=lCjCoj(e!)Qy56>vow`Pk_IWL@Qsr-{V2JX#_4GB2fPLHyK#T zR$(0L2WBQIvn!o)SJ|G|EI(@PpmAy*=-=GiIb>6HeR>A`8K<$+o-j=Gk{GXtjgqJm z74;$3?=s!f2JlUo`%u1YOy+GcWW)tX%8#;mBq_x!b4VP{7jm>$`ZuR2QvBv~5v`;l zIPT;#{v_}-IcXL zrzpWJSt`(|w~={)oGK$i&AEE4N1YrryX_LS5l-R3)jwU|&tCYYcb(y+oa_s^;hpNv z8WLz7N9*C2@>6Q$F(x4?2U{W_lPI~IldE2|BFZH8ntpR0l`T^G$#|8&r)37G6m%u6 zU#x-@7l+h!39>>aQ>ZOuNA=GF9xNo&3bh~;S*(h~vF@KTVYSqEqf^06{AJeBGmy#d zNP=WV(KdRCwf(TqGnd*@3T}06FUv4Q5W*!tz zx{r63xPxs;?7XV{o$n75sY{tcBhp9Z8Fzj5!QdttW1R~r!T3Kf5iTC!X1b86`%_5KoqP zakI0uy*>1-d|pRBb&CYnzqIkbZ5;c2jf(r$CcQXO5eGM_1~gS-;dJzdM=D({@2Q#j|x^vK47c1`NMX9mx&vTRc1RElx$@mD8^1OtK*kV zsi*06R(e(kZ`@rYHY>}vql22oZE){ulZfpC+Z1Uy9+4%Z*2lUwm(^-}hRh$0qW%*9 zwm8;%H}VQAFzaRM^4G!udvi;F>5{#$tq|{1YqM_!>@RhS%W3k!94Z&*e<_QsQ3`lI zG+&6gmzLnV#~UO#ImoqE9`BBcP;$L3B?%9o(l+ypqeMOfNG_G*4~aRF3-x=JoeNjz z&zmWG#E|0bU#ZnL2!{{%5AwNp-hPidt(ed1=OLObXW*|!4+OI<3u;7A(L%@m zWHD|1Q9kf*ZthEqE*25=Jg+;U@JTq_whwA51_?ydzKzd#r`{~29bZM|U^QYYTBNvaG~^D!=<4`0b@I`5)9M7&>yD1iaAlEG3uk>`p@U&T@* z?<{G8Ypc5aI+Ul0%MS9a)38q!#p*v-A_r~*Op956YD0#N`SEy41DqfP<7veO_&C3U zPH}=2j~ku=+;ks<_&~2qktMNNiTSKV9o^EWDjUmqunUg}4e&=41=8-^wVZd&{H&zf zAwtB34n>tS&w$1S)KqOH&g~c$#wA&`hHpSR|92!V8C=_>Y|4W(VQ6`Qnf72UpxaSgOqkOX_R!lblOh@1V5z;Q4Qv1brZR3tL1`QvuXY|GR-Qd z$>Z6C@F2bk;EXo1@MR&fZ_T~?4I!s}-2J@&UWKFj-&k^x34%3vb}rSG>c zh?t!3v6dWDJT66^^b9U8N02(30u$d6mJa~#QFUWyDfFtyias{YoFN=T@lUx{pM(C0 zv28jAZy60n>)*>jao@tmAu+V&ya#~VYG_}ph4NGKGc5iIoHu1$CcxjMq7YH zSr8^yxjp`&5vWK^PoQGO=L&;1^xVX>#v*!t4azc~wYgO}i}v}5mdjYD$+~c@1pT}t zk@0hRKh#tsD24xWR^zL11yST{!}X8iG2f(3jj?j=xOO>pcjOA;9%rb7hh1Vh$|kJ- zYIf_fSQX49TNol!!5 zGZ0`f4l#F|$ZRm@dCkOqKDBpfZa5ud(wX^CVTavfY4*wG=_Vv?m_0p}5k+4k=aKCi zyuTg&`0`%jnpXtwANm_1{wcEHW6;TI7xSRcf@S6f7;>I3n5?Rr8_<(@hkeoc1_QVw zl2n|<7*k|Ga=%Y)b#;O93%qV2ZKTR(saxIqZ7HU?e^t0e<-57sf?6!j{y|&yWU}6} zbJzD{xPcqa=VFBtZ>)5wt&?X!(yh_-{RXxY#NoiSxQ9e)vaK2Qou`i^f&Rx0|&<8sZ(SIPvTtHF(;)|_7v)x+-5 zw}}>KL@$HH)JWdRH-f#%v3aegmMHp{<_~)HcfS{N-GV!b+ZHP2o-vkySM~&&%zxo% zquben$$@rk*UinM6iuTJ!K8f4>#&58@m|5&1r=qS`QP8a{}Cz4;O9(iJ~?2-J9`;& zlZ%3Lf7;YYj&mGLl5YqZ>=7g;OT?Z4x{B}w{#{y#)3Od1iY@2VZm|R4>EoU@PkHuS z0W=t_bZHkUY%S|zGcNa^0nxZsI68|gmLk0&eST7&m?6{TNM$W}PAZJx8Sr+2fC6|y z9fI%lse=a^WY+6)AgxStaL9~E=ZZYe8^dRqCxi; zeEP*75G4ig4T|0ubMf-El{!g(Hp;a1KG7LaWR8(x1E*gPx7LeK^)p5zvm7?#kgCPFd*?6fJ+cL zU&9b(F>RVTz@zYNq?o>Rs5_4m#cks~XR7ST%~;YHHioFA{?g_som_XH z7VjOBCBdf9y&>EmR(oe0(u4r95BID*P<7ha6_kyG-uxNlv=rpDUQAy%CI|$f`Iu76 zjqDO(#5Ff`W+Gaym&pmnhZ3w0DHbn2*%ew@3XxB!0OHFDw*CONvW_tLoKs)!|1K-C zm{iG2-t<8cC=qs4fH@qM?HD*%D?nm2h-bWD%=ekv<>z;!<*i&1>eCP;PHRJi*urXx zu^F}%`;#669!>^xm=eqDF!iG`$AB?$FcF7XJJCJ8LAp+z&OB5Z{Asg2LlzkNgC;;H zE`_o|$J+i|L~p`!2-S2Xud@&i&d^t`^73MWd_m%G!ZAqCo0ipu!d={Su8NuYxe?^f zIjoJwcZ}A>-d5?mkSuZtlp-{D@x9&+Ur_0s*yjqf0N1Ub(Wd@2Ql%_CFGsj!nupf# zhT6v|FYan-`RegQnx=il`}})0r&V1o+T_J5?ss`{y;6jO(X^hiUK@!RG5ZT2Vs)C? z=N|C~XbG4T1*00)Rb4|Ka2m~}#KtUSzpaI)$~zRqAF(vadPysjjUFVbY=052LNSuztSc-|+6IN?)!!o021hwlc;n9$E%%&)|ILKO1$CTRQN~ z5FFjjcnKdaFBj0XiRXSFh|X}N%C2(V>r#^3dW}i*G1mGYWN+t-o62zfIKJ@20!B@B zbme7}TrvXkpi-h6s z-gqoluchVHX8?k8+E!i0MulkbGz!y$oyc`a(7YEd+l zAf<#Ctx;z!ho}C{C;8g3M(Oi;$6yG)#zJN{LWqd$oI@If(4t;#1WDigrBFZyAE855 zK{XG&gwwcGYabp$8c28OPLHmvU~eoDoLJ(p6@KYeOU!e}`I#;FnoX%4lZ8Q^Rja_Y z==6CbSE9<;(UGbRn0<6Jc$e;b&H1@b|4&bjCywogM63%)t(xuT_vkNV4~@*rzD9dK znhAPr(RISPr-bLjOD_VZ;4T;O7WiFY>E=(_HbKa8as6fY>)uuLy^nOVsJ^IZ0Ds zL0S0_)y8{B(z#ctSTgUNNcl)I^$v5T4)*2dR_RJ+^A-@I5>a*9Q z{4+M2)ov;a+8p=2_^8}QizDZ|%(1LeWbSO(aYuC2K?}Sb6PZ?MXv&)A4};U#Y{{i;SB1&QHMJ#oI5+O!!s6{(V^~#I z@SA9&+@Ya(5m~2R6iF*uP zzF0gBu=LBj`fl_6w~9$Uc~*BQS)6;A4$y+)1{GM1?_-(=-HpD#sa(9Eg)jc(BBw@( z|8_vio@~*5_ELSyI}DlFjuzCqhAJ@-jN4RC&ja-L9bzlPPaoEiw(n+jH4~ ztk2IkxA@f%jlLaFR$8TCSzQj*DfH`xs>`)(ezr{Rp$SWYY{?xKA{HSkVCbG^F1x|J(p#=@1MmT@kG zQ6aZ_H<)PF>Qrv#<8r&7Eu_S{fRI33PPTiDoz3LG2V!DZ8?5RLT^;jAAXLO(T9*&h zV+?~AuS!`)8ArhiCBzG5b(sLsSd_EO1JAbdj#&VdfjNJsBR1e*@fDQkHqk&sV2|Z-Tf+ zP)%SHTb7x1&H-EK?gAveFMM+sDJx=oLJw<=pTdQPQ(4HTLJ=5rv~N7=+1kH1bv;z@ z6^fi@dwiN4U}UO|3n2?h#C+34FA(8Ps%-Mwj*I)}i?iVlv#@_hBYWO7v$b0gyH!f1Iv`eK``v|jgU{377Dxn1Ea3_Ie(>kk{yz+GEF7+s<7S&ks3 zO#;oE=G0)=FIBWhrIlMeQwf8m)rqZ^QDG?M`aSC}mPr>_Oc%p5fO9=)=7qMwR>i*s zZ-j}aE5{eA7mKuXe*Oq`2$vPO{KY)H>5Vd0#^z-NfonS~&2!1v?uOK-W#pHSd_zzN zV)`s6YBuj5M?SdJE;Ktynea?su{_kU(ka{EsLllHd(%4wV`|PTZ5ZKA09t#j#7(J4pXzAayu>=^|i{p#&7HpQ{fI+_3`#MX^=S?KVWRQC)2Y$_$QMS5&$fO};sXen`tfulCd?C3pz)1c6>TBo zp>iHeVM-;$gBzZUn_)_lE=Vmqvg#Gv)Uvbk3~2A{C%0ASa!22Nj+Bkgr8)7O_3>?WiQ*x!Ls-WvO-^=^za}Kfp_hJq)!Ed+RaMr5F~f6a z8u%#(u2Ps=_RUtGdCro$&`b_Ta%cf~5YUJ^LFrmjf5Ob4|KTk*#%9+>dyvHK-RWr{ zxsLP9pw&H7?>{eXY<2iSgWoycK{r}v#}WDZ>kuo<>WfP3rom`bN53iml{fQG$yM+B=%j{@1(_CjTY_U{@a zcpIY!Y-lwxUU56M{#tm7L>n zix}LSFP)-|S?{t_I-X=LtXu~2u$>qvkw3hTq?$3;UNGgOXXkyLT>otg1o;7D=|hYW^jeaYyNxe6f)&mEkDPwf8~KS{btkQk4$FU-(%S9z z1hHKFxN{1_&w?paeeItFnirD#5SDaE4QP@I)bSIvi55|GR^DCSdavPP#MX-N6ipZ? zZpS3ttpKogW5yw1v8noP)mg56j|0WQryg8f0?yIT?LApauOuoJP)xkfynk2S)Q`Um zD#x(a2=6I{`+*;-tE*AG(du5al*H=lBPB&KM@G#TKJ4b5t|oV5{W5;Z;S3kWd<&*A zH#awgpc=GWU0v19>2&%?7Phblx&5F8ocFpzD`5^F+Xp1g%`MZh8S)uiOGQm&y&aXP z*|QoOZY9jk%>c(uB&01TSH@TSPH+{=JS%sUgE^FC-*@`@`j~V-@(e*+tu-Q>AOOKkAA39l;HJ{}D2q*EpwjHF|9XlRB8g!STg`fRRn6EQaG z%(E0?aDqL68-0VF9XId{H3op4l^x%VNL9cH5(L5#(;ht=gwX~q+xw^fqhzOlUi=T1 CB9Tl0 literal 0 HcmV?d00001 From 542a5bfb3410943db1a57bbb094db5d8a58b52bf Mon Sep 17 00:00:00 2001 From: jayeblack Date: Thu, 14 Nov 2024 23:24:06 -0800 Subject: [PATCH 2/3] commented out my database credential --- server/farmsales/settings.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/farmsales/settings.py b/server/farmsales/settings.py index 80c121a7..1222e536 100644 --- a/server/farmsales/settings.py +++ b/server/farmsales/settings.py @@ -80,10 +80,10 @@ 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'CropCircle', - 'USER': 'root', - 'PASSWORD': '2005', - 'HOST': 'localhost', - 'PORT': '3308', + # 'USER': 'root', + # 'PASSWORD': '2005', + # 'HOST': 'localhost', + # 'PORT': '3308', } } From 10a6fa19ba8000824a10793b7a71d679f54b42a6 Mon Sep 17 00:00:00 2001 From: jayeblack Date: Sat, 16 Nov 2024 12:53:52 -0800 Subject: [PATCH 3/3] fixed the endpoints --- .../__pycache__/serializers.cpython-312.pyc | Bin 3488 -> 3192 bytes .../farmapp/__pycache__/views.cpython-312.pyc | Bin 5197 -> 4931 bytes server/farmapp/migrations/0001_initial.py | 127 ------------------ server/farmapp/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-312.pyc | Bin 5683 -> 0 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 193 -> 0 bytes server/farmapp/serializers.py | 6 +- server/farmapp/views.py | 43 ++---- .../__pycache__/settings.cpython-312.pyc | Bin 2696 -> 2696 bytes server/farmsales/settings.py | 8 +- ...nach_Io7xRWj.jpeg => spinach_MVlPCwO.jpeg} | Bin server/product_images/spinach_dK9pbw0.jpeg | Bin 7714 -> 0 bytes ...nach_ZqJzNmp.jpeg => spinach_lmtbPMJ.jpeg} | Bin 13 files changed, 20 insertions(+), 164 deletions(-) delete mode 100644 server/farmapp/migrations/0001_initial.py delete mode 100644 server/farmapp/migrations/__init__.py delete mode 100644 server/farmapp/migrations/__pycache__/0001_initial.cpython-312.pyc delete mode 100644 server/farmapp/migrations/__pycache__/__init__.cpython-312.pyc rename server/product_images/{spinach_Io7xRWj.jpeg => spinach_MVlPCwO.jpeg} (100%) delete mode 100644 server/product_images/spinach_dK9pbw0.jpeg rename server/product_images/{spinach_ZqJzNmp.jpeg => spinach_lmtbPMJ.jpeg} (100%) diff --git a/server/farmapp/__pycache__/serializers.cpython-312.pyc b/server/farmapp/__pycache__/serializers.cpython-312.pyc index 5fc9192cb059e7039bd736c25e24c439f5fb15a3..d0baba3aa03d814bfd73e71d09d8bace2b0b4ab0 100644 GIT binary patch delta 364 zcmZ1={X>H9G%qg~0}#0Wvq=BVwvlf?M;r@?4+NjpfW&l$RE8+V6ox1!CI)wg6vh^Y z6sFZoV0nfp<`m`@hA5Uw7ERV$0zs)|nW^Q$sYRKIIhj?dMad9F5E80`;j_YI9d=2c zbf77V7^B!KnKfA^i*ZG|XfhXB0#z1?g9tky;it)7qzvMyfCyC(!44uoZYoj-61N13 zQWI0+^Yd~lYPv8=jw*X2h0&%erkZ57JAt2VldP^|1gYA~I<3$dM&HK2R z7#Ypqo6+~!&2u%>71tQE~gaVLJEDR)C7``(xvpO+;WB`$$xh9|H esb=(??9S^V%E>4?q58VG(M55iuM9vA*c<@MiAk;i delta 487 zcmew%u|S&dG%qg~0}uqAGfOXG-^jP0WAXu3PR47KPqC^>q_Sr5fFw~t7XM^_HYuJp zjH?+T5>XtJ4HzXPQaQ1z7M)zkCY;K&h8duM&bVLT~pEeuh- zmF$`vw*-Px%Q92TgHww#6LT`FQj0VhZ*dfsrWREerfd$+$ZO8D@KF^nLz9L3_7x}^BG*^GuWZNUw^0m zbt~VCR=$_5{IBo@G`QaoG@c-RUC{WVpz)57{V_XZuG(I;s~P<#%k#L1ax;ofsJIqzSYW0Bx6lIsgCw diff --git a/server/farmapp/__pycache__/views.cpython-312.pyc b/server/farmapp/__pycache__/views.cpython-312.pyc index 46384db5816d334b9de15e4926877cdb82069845..b8c7421a192c6e8400901399f609666990d16b86 100644 GIT binary patch delta 1988 zcmZ`)+iz4w7@yfad%CxFFKxGXSln&lP^bk91wm3Qwlvf&O2x2THtU{g-Ll(LXHF?L z#VR(22VyMq0I$5Lgg$8a2TbaNi5j~~EIEPbD^FJGgW-WV-<y!2QNHT(v z0}UeGw}5m%aou%-K0?U`Nv#&tnhI*8qy_{vSV3)))R3TtiKk?t`Tbh0?y<0S178he zD=@^4PMhzNNi&;Cn?&ay;d9N6f_)Pal*BqpI*4-|ClwtpprniciC+q@VPJcZ2`4=;uU4iF{kLR!-6Ozf@L26BiI@jEEQO0eUUMzELD|^ zy5?LH4g7a!i))|QHQi9!u!o=bZ0(id1(k{BqGEYnQtmqJ(b^AHI8T$S6I>=x-*N-vJd{UY;jliA>%lMPN5le*?9)dV9lM-u;rPW zr-nYAF^6=^MJP4sZ0Mv-iB1}3bj+BZ)G5?}RW)VPEpKL;nMR(_A^i@v6g_RGwIKCL z8RMM^k};X(94DsbKV}e?FwEC3XPHS|LVzkD6+S*XdNS41-IGd;jCQ34M&3#sqbr!0-ZT-mBVfCczpl0^5H?QL z56%X}hW#MmL$sziJs0r9NZURbg`0~*G`dy#)muRs*p@ zAodr+a7k^;t+!V?4z9Gm{O$hL{&R)?bN6e{|Li}%<^=Xr77`v^jrKdxvZK3ypL4kf z3ruJ#kGb1N!DlNxMQA?DSk{B2j~z`84FucULgbbuL!h9qjm@&X|s`y$M;hr zrrhZ)ndzD`n7Nz3S^e?<#Q+pH$Dj{r0KhE8z+cL9pNPRJ9N~J+?GgDb=n2hXdF-sE zvbyXNO|jIAGif@`WXH;Kpoc)zX{WlR%OGSTp|q2a2KL}r`6q#+c<;UM0;e%<;afx9 zN%{2W1r7%3^8;ro^6CL0AUb=Jnd!+4`ELR7JE3-boc|QM+-R4HdvlqDc`6)_4Z=kU zfK3(C4>W+o{PS?!FG~rI39W_y8vbU!nToNI8l&kvnK9_au5!yUDx1(JMo?CaomoPe z97J}n$Xb!TCu_2=c+IB!pSlm{#aPXeBQz;Q;ID~Y5FmyC#*ff8zFu43^a$<$4V^8Z Yv+HUd9>KT9*AcAiyLhxtQ^4ha0B>Tb&j0`b delta 2199 zcmZuyO>7fK6rQoy>-BHEHuwi6WE1k|64E3Rd!I5A(G!jbh7}jY zs`p!AUNYp0oOIt;c4FRTx~_!ED+p1KU3T;^ZYOQ9*EL7VE2^JyrQORMj7e-n>A1aa zUrpJ!bI7P@F`e3K>EbujSh3gTsx;z(!L0AB_UVkK8_Gb!Nc39ni5cCT{FUSptdYKBMDR!f$S3> zKn*NNNqu}akxHtTpeJTE0`3!m0evBK?RPU)OHEo%I16@uBnCR3vb*C+b=xCS2dcYh zucJ zyk}F6F4iv8ZpaO*a>H`ln!GnJZU$qE?F;Q2!N%2KA8fW^_x*;GhDkF+5MNx5pm}|TLIcGHbpNkXMfDy z%@t~Uei1kNhFANB*FzTz-iu$#G3h0X8x5`q^jERD`)&5Uf=DMDNCyD)1qVooE-|=+ zUfLQRL%1judf4Y2!#T^DxqL;NFmy|tOr{KtkN_z1G(nDet}M@o=g*%W@9yjzA37Nq zNgNj5Vqi&=3Bv1~9O2VaG3jIE%4uGmH0tu>ZrbWPa|&D^ zj0>cjjbuN-0RYe;2LZNY>wzgi7kewQiH?C%Y(2Ek+5PZuR~82jfhhP!b^{!yH$6LZ zJg|P4!@WY90Ga_R)k#`l+6vIdpgLy46}d@n=Z%p!OZp8QnNS zcX&TP%)=!Rz^l;>00(fGy_M*^mCOyW=wkF=Z!eC~9^c&|?hiB$>uy&uAJ90Q5iIfQ zT!KvL#lAcWrr!fmdohU>T^;(HCyKWEyYLzMiN7CrKK#ai0poi5qNa0%2m7X@>I0*1 zJSt1zTc2P8>>`+E|A^BQ+Uuo3%|J6Arr!syM~g)uy;=k^?UtMNoP>?e0=!ZW$AJSl zNpHwaUS23L9gN55iu~xDhh2F|b_r!QqVsF1SmZqUyia&R@pI><{%`&t=}4O0q$%wv o8DmBz>% diff --git a/server/farmapp/migrations/0001_initial.py b/server/farmapp/migrations/0001_initial.py deleted file mode 100644 index 41ce0088..00000000 --- a/server/farmapp/migrations/0001_initial.py +++ /dev/null @@ -1,127 +0,0 @@ -# Generated by Django 5.1.3 on 2024-11-15 07:18 - -import django.utils.timezone -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='AdminActivityLog', - fields=[ - ('logId', models.AutoField(primary_key=True, serialize=False)), - ('action', models.CharField(max_length=255)), - ('targetId', models.IntegerField()), - ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ], - options={ - 'db_table': 'AdminActivityLog', - 'managed': False, - }, - ), - migrations.CreateModel( - name='Cart', - fields=[ - ('cartId', models.AutoField(primary_key=True, serialize=False)), - ('items', models.JSONField()), - ('totalPrice', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), - ('createdAt', models.DateTimeField(auto_now_add=True)), - ('updatedAt', models.DateTimeField(auto_now=True)), - ], - options={ - 'db_table': 'Cart', - 'managed': False, - }, - ), - migrations.CreateModel( - name='Farmer', - fields=[ - ('farmerId', models.AutoField(primary_key=True, serialize=False)), - ('farmName', models.CharField(max_length=255)), - ('location', models.CharField(max_length=255)), - ('farmType', models.CharField(max_length=50)), - ('certifications', models.TextField(blank=True, null=True)), - ('verificationStatus', models.CharField(choices=[('pending', 'Pending'), ('approved', 'Approved'), ('rejected', 'Rejected')], max_length=10)), - ('createdAt', models.DateTimeField(auto_now_add=True)), - ('updatedAt', models.DateTimeField(auto_now=True)), - ], - options={ - 'db_table': 'Farmer', - 'managed': False, - }, - ), - migrations.CreateModel( - name='Order', - fields=[ - ('orderId', models.AutoField(primary_key=True, serialize=False)), - ('orderItems', models.JSONField()), - ('totalAmount', models.DecimalField(decimal_places=2, max_digits=10)), - ('status', models.CharField(choices=[('pending', 'Pending'), ('processing', 'Processing'), ('shipped', 'Shipped'), ('delivered', 'Delivered')], max_length=20)), - ('createdAt', models.DateTimeField(auto_now_add=True)), - ('updatedAt', models.DateTimeField(auto_now=True)), - ('deliveryDate', models.DateTimeField(blank=True, null=True)), - ], - options={ - 'db_table': 'Order', - 'managed': False, - }, - ), - migrations.CreateModel( - name='Product', - fields=[ - ('productId', models.AutoField(primary_key=True, serialize=False)), - ('productName', models.CharField(max_length=255)), - ('description', models.TextField()), - ('category', models.CharField(max_length=50)), - ('unitPrice', models.DecimalField(decimal_places=2, max_digits=10)), - ('stockQuantity', models.IntegerField()), - ('productImage', models.ImageField(blank=True, null=True, upload_to='product_images/')), - ('status', models.CharField(choices=[('in_stock', 'In Stock'), ('out_of_stock', 'Out of Stock'), ('under_review', 'Under Review')], default='in_stock', max_length=20)), - ('createdAt', models.DateTimeField(auto_now_add=True)), - ('updatedAt', models.DateTimeField(auto_now=True)), - ], - options={ - 'db_table': 'Product', - 'managed': False, - }, - ), - migrations.CreateModel( - name='Review', - fields=[ - ('reviewId', models.AutoField(primary_key=True, serialize=False)), - ('rating', models.IntegerField()), - ('comment', models.TextField(blank=True, null=True)), - ('createdAt', models.DateTimeField(auto_now_add=True)), - ('updatedAt', models.DateTimeField(auto_now=True)), - ], - options={ - 'db_table': 'Review', - 'managed': False, - }, - ), - migrations.CreateModel( - name='User', - fields=[ - ('userId', models.AutoField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=255)), - ('email', models.EmailField(max_length=254, unique=True)), - ('password', models.CharField(max_length=255)), - ('role', models.CharField(choices=[('farmer', 'Farmer'), ('customer', 'Customer'), ('admin', 'Admin')], max_length=10)), - ('phone', models.CharField(blank=True, max_length=15, null=True)), - ('address', models.CharField(blank=True, max_length=255, null=True)), - ('createdAt', models.DateTimeField(auto_now_add=True)), - ('updatedAt', models.DateTimeField(auto_now=True)), - ('last_login', models.DateTimeField(blank=True, null=True)), - ], - options={ - 'db_table': 'User', - 'managed': True, - }, - ), - ] diff --git a/server/farmapp/migrations/__init__.py b/server/farmapp/migrations/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/server/farmapp/migrations/__pycache__/0001_initial.cpython-312.pyc b/server/farmapp/migrations/__pycache__/0001_initial.cpython-312.pyc deleted file mode 100644 index c82c69f0e8aa02bf9e274532626057f130fbc832..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5683 zcmcIoO-vg}7H~nK!2`OO~{C z$!em^)I$ncexQ(*wX70rB?HF$jm3B`*)~jJ+YuhjhRwP=&7~wp;Y2~!?P(FQyqq)? zjpvo(;GN*YyR&5HB{MQDSyI%J)l9LrRZsa33>le`1=bv^bd@y|vhLX4n2nVcGqMxS z#wwbQ9p@XIEto6(oAyRnau?oQNNGw$8!8u7Ij+hJ{^-2{w! ze@To`AKASs*MaS2xlB1wcg<+_qX@BE3z`Gx#g8icSd{2hVO<&OgXh|+WN?h=)smed zqIq%myhU_+&hi1eiwO%DMInbl|%+M|~gts^+M_BAOrXz;U8?qY6VFK;&a(-C(>%ixcPRL1&#j z(^(&$rwzzI0uQFj7&m=^uHysU&&*ErHQBqCZsbPy!S{;WM9Q($yzw|Zqq}BGx3fi^ zj-xau#FGlQ&M6y@#guO2#ncp?7uyC<7=B*jlI#(_?H%E3Y1pdU zp7V^brZ*rq310Jw49_H4P{-aOF2yM_Y?I}A-IbJBMqyE00na>4RuL0|_$t95a5|eo zCri%Kl5U@5q%Edc2EmPD0?dL&Ps|+HD8~#X5pwJS}Dg$cp60uHhT1Zik#5lSM;CKcTU z_OSpC0^x{AfUQHUoRm011>FfKvMEsl9%cnjA=%gKWkpP`J;^eH0^HR-B|~Xo)#jz* zC;?gy>^jH3+VnibqtH__lBO|o7HJ4x5m_yvzdiGK?(0f~4wJN#t1)irt{7gijG1SuzWO z5$=u^C787_xaf5oseRp+c_9ky(IxzgB1o7%22&kS77}D%ck_&_B%n8N!fd!jcP0|J zW)lhBok+kJUY5tQCy{uWW%%NXgM(B-&%l|-#Abyg2i(M;jC$P|DZ&~2Z75msj4KY6 zIEg!e?izc+NQUT{5+Lzxaa50~vj~mFShS;6Mo5XeEvs<649y2tHX#<>0tKzRrWfXB zi&n;srcgA$$i7w#(LIIPQIsbz(nVR!u*DD9AE|fX9`!RCySt3jBQH-+Je`=Cia!cH zn2Rq?%syNOrmiVsW_g7ZaO06gT$;;CNz5cUDao_T@H421Wt}irDqG?R<*5n>vq1aS8MBiE9crqRC=`FZBzZxt#9)FsOFCz_+u(P zRPeT|f!NkcJ`mFavEAE$9sSE_eq>%7na__bY9ouez%!Np=GbLxYB+A7`~!uy(7$b# z=7#rPkIQ}Rt8nMaVa2w))_q&9ZC0h{3Kec1`1(}3zu@(&!PwS%J{Z%2vE8P9MqU0+ zWw~5%Ri)P|-P*I}0uw4dSvk8qo(sfP`oVFX9h{>nf7gj~m+Qf~_6p}(4{`MUIQo9g z-@n_ve=X;qSLr7NmDBmlIsZMCzF*U9W6nRS()SA94z+7&`*yx-Nb4Hf?cQ6=bxo`E z*9Gr2_4=Ld_5Afa+VwmCp{TfN#(YdsOXg+sdy2a8EgpEkGgpT7kzl572GSwa=;aJVAW`qduSo2M&URDjh3$18Qh!+nx^% zX`!LLLG{T(F0`o9&nj62{tqXx$Glmw ztMttAB`1W{MESckG~P{ z>8Zfy0**sJh~Rz@(b^&hZBdmTEL2eB?X6vuYadhT@lRr7sq{|SSf%tX=nGfW*6>zK zzBR11hTksaTEA53yQEw6;-=QC`Jj32-OBkMsr1x&C0TCc@3D12dfYsTk@h_#NIwFk zE81k!Ugtj8G>X5xPTtTVTk|DDR;o**kUr7-q|UW|DV*2_x9H&ll^z@Jl(C)-9J%yL`?i2Tk=~i diff --git a/server/farmapp/migrations/__pycache__/__init__.cpython-312.pyc b/server/farmapp/migrations/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index 5164110297d9c81261398fe4715881df4410967a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 193 zcmX@j%ge<81e?B^rGx0lAOanHW&w&!XQ*V*Wb|9fP{ah}eFmxdmEdd@6Iz^FR2<{w z8szHh>FA;0gOJll3JWyl3x&$mYJ8B6JJo2pOuAwl9``Z91|a(nU`4-AFo$X`HRCQH$SB`C)KWq6=)$N5Ep|O NADI~$8H<>KEC5>uH4p#* diff --git a/server/farmapp/serializers.py b/server/farmapp/serializers.py index b031cd7c..638e7324 100644 --- a/server/farmapp/serializers.py +++ b/server/farmapp/serializers.py @@ -30,14 +30,12 @@ class Meta: class ReviewSerializer(serializers.ModelSerializer): - product = serializers.PrimaryKeyRelatedField(queryset=Product.objects.all()) - customerId = serializers.PrimaryKeyRelatedField(queryset=User.objects.filter(role='customer')) - 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 + return value \ No newline at end of file diff --git a/server/farmapp/views.py b/server/farmapp/views.py index 7af53eeb..72e4cb79 100644 --- a/server/farmapp/views.py +++ b/server/farmapp/views.py @@ -5,47 +5,32 @@ from rest_framework.generics import UpdateAPIView from django.shortcuts import get_object_or_404 from .models import Product, Review, User, Farmer +from rest_framework.permissions import IsAuthenticated from .serializers import ReviewSerializer, ProductSerializer, ProductCreateUpdateSerializer class ProductReviewCreateView(APIView): - def post(self, request, productId): - # Log the incoming data for debugging - print("Request Data:", request.data) - - # Extract customerId, rating, and comment from the request data - customer_id = request.data.get('customerId') # Adjust based on field name in payload - rating = request.data.get('rating') - comment = request.data.get('comment') - - # Validate required fields - if rating is None or comment is None or customer_id is None: - raise ValidationError("Missing required fields: rating, comment, or customerId.") - - # Validate rating range: 1-5 - if not (1 <= int(rating) <= 5): - raise ValidationError("Rating must be between 1 and 5.") + permission_classes = [IsAuthenticated] - # Fetch product and customer instance based on the passed IDs - product = get_object_or_404(Product, productId=productId) # Corrected this line - customer = get_object_or_404(User, userId=customer_id, role='customer') # customerId should match userId + 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 data for serialization (pass the customer and product references) - review_data = { - 'product': product, # Ensure 'product' field is passed as the actual product object - 'customer': customer, # Ensure 'customer' field is passed as the actual customer object - 'rating': rating, - 'comment': comment - } + # 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 - # Use ReviewSerializer to handle review creation and validation + # Validate and save the review serializer = ReviewSerializer(data=review_data) if serializer.is_valid(): serializer.save() - return Response({"review": serializer.data}, status=status.HTTP_201_CREATED) + 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 diff --git a/server/farmsales/__pycache__/settings.cpython-312.pyc b/server/farmsales/__pycache__/settings.cpython-312.pyc index a1d74a05b0a05d8642b8406c3c38ee46608353b6..bb8b4d18821447b45f429920f11846d47d4ff307 100644 GIT binary patch delta 20 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 CB9Tl0 diff --git a/server/product_images/spinach_ZqJzNmp.jpeg b/server/product_images/spinach_lmtbPMJ.jpeg similarity index 100% rename from server/product_images/spinach_ZqJzNmp.jpeg rename to server/product_images/spinach_lmtbPMJ.jpeg