Skip to content

Commit 0356f72

Browse files
committed
Added Warehouse and Rack Shelf Floor Management
1 parent d6f75a0 commit 0356f72

File tree

24 files changed

+509
-11
lines changed

24 files changed

+509
-11
lines changed

Backend/EcommerceInventory/EcommerceInventory/Helpers.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
from functools import wraps
88
from django.db.models import Q
99
from django.db import models
10+
from rest_framework import serializers
1011

1112
def getDynamicFormModels():
1213
return {
1314
'product':'ProductServices.Products',
1415
'category':'ProductServices.Categories',
1516
'warehouse':'InventoryServices.Warehouse',
1617
'supplier':'UserServices.Users',
18+
'rackShelfFloor':'InventoryServices.RackAndShelvesAndFloor',
1719
}
1820

1921
def getSuperAdminDynamicFormModels():
@@ -160,3 +162,29 @@ def wrapped_list_method(self,request,*args,**kwargs):
160162
return renderResponse(data={'data':data,'totalPages':total_pages,'currentPage':current_page,'pageSize':page_size,'totalItems':total_items},message='Data Retrieved Successfully',status=200)
161163
return wrapped_list_method
162164
return decorator
165+
166+
167+
def createParsedCreatedAtUpdatedAt(cls):
168+
cls.formatted_created_at=serializers.SerializerMethodField()
169+
cls.formatted_updated_at=serializers.SerializerMethodField()
170+
171+
def get_formatted_created_at(self,obj):
172+
return obj.created_at.strftime('%dth %B %Y, %H:%M')
173+
174+
def get_formatted_updated_at(self,obj):
175+
return obj.created_at.strftime('%dth %B %Y, %H:%M')
176+
177+
cls.get_formatted_created_at=get_formatted_created_at
178+
cls.get_formatted_updated_at=get_formatted_updated_at
179+
180+
original_to_representation=cls.to_representation
181+
182+
@wraps(original_to_representation)
183+
def to_representation(self,obj):
184+
representation=original_to_representation(self,obj)
185+
representation['created_at']=self.get_formatted_created_at(obj)
186+
representation['updated_at']=self.get_formatted_updated_at(obj)
187+
return representation
188+
189+
cls.to_representation=to_representation
190+
return cls
Binary file not shown.
Binary file not shown.

Backend/EcommerceInventory/EcommerceInventory/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
path('api/superAdminForm/<str:modelName>/',SuperAdminDynamicFormController.as_view(),name='superadmindynamicForm'),
3434
path('api/getMenus/',ModuleView.as_view(),name='sidebarmenu'),
3535
path('api/products/',include('ProductServices.urls')),
36+
path('api/inventory/',include('InventoryServices.urls')),
3637
path('api/uploads/',FileUploadViewInS3.as_view(),name='fileupload')
3738
]
3839

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
from EcommerceInventory.Helpers import CommonListAPIMixin, CustomPageNumberPagination, createParsedCreatedAtUpdatedAt
2+
from InventoryServices.models import RackAndShelvesAndFloor, Warehouse
3+
from rest_framework import serializers
4+
from rest_framework import generics
5+
from rest_framework.permissions import IsAuthenticated
6+
from rest_framework_simplejwt.authentication import JWTAuthentication
7+
8+
@createParsedCreatedAtUpdatedAt
9+
class RackShelfFloorSerializer(serializers.ModelSerializer):
10+
added_by_user_id=serializers.SerializerMethodField()
11+
domain_user_id=serializers.SerializerMethodField()
12+
warehouse_id=serializers.SerializerMethodField()
13+
14+
class Meta:
15+
model = RackAndShelvesAndFloor
16+
fields = '__all__'
17+
18+
def get_added_by_user_id(self,obj):
19+
return "#"+str(obj.added_by_user_id.id)+" "+obj.added_by_user_id.username
20+
21+
def get_domain_user_id(self,obj):
22+
return "#"+str(obj.domain_user_id.id)+" "+obj.domain_user_id.username
23+
24+
def get_warehouse_id(self,obj):
25+
return "#"+str(obj.warehouse_id.id)+" "+obj.warehouse_id.name
26+
27+
@createParsedCreatedAtUpdatedAt
28+
class WarehouseSerializer(serializers.ModelSerializer):
29+
added_by_user_id=serializers.SerializerMethodField()
30+
domain_user_id=serializers.SerializerMethodField()
31+
warehouse_manager=serializers.SerializerMethodField()
32+
rack_shelf_floor=serializers.SerializerMethodField()
33+
34+
class Meta:
35+
model = Warehouse
36+
fields = '__all__'
37+
38+
def get_added_by_user_id(self,obj):
39+
return "#"+str(obj.added_by_user_id.id)+" "+obj.added_by_user_id.username
40+
41+
def get_domain_user_id(self,obj):
42+
return "#"+str(obj.domain_user_id.id)+" "+obj.domain_user_id.username
43+
44+
def get_warehouse_manager(self,obj):
45+
return "#"+str(obj.warehouse_manager.id)+" "+obj.warehouse_manager.username
46+
47+
def get_rack_shelf_floor(self,obj):
48+
queryset=RackAndShelvesAndFloor.objects.filter(warehouse_id=obj.id)
49+
return RackShelfFloorSerializer(queryset,many=True).data
50+
51+
52+
class WarehouseListView(generics.ListAPIView):
53+
serializer_class = WarehouseSerializer
54+
authentication_classes = [JWTAuthentication]
55+
permission_classes = [IsAuthenticated]
56+
pagination_class = CustomPageNumberPagination
57+
58+
def get_queryset(self):
59+
queryset=Warehouse.objects.filter(domain_user_id=self.request.user.domain_user_id.id)
60+
return queryset
61+
62+
@CommonListAPIMixin.common_list_decorator(WarehouseSerializer)
63+
def list(self,request,*args,**kwargs):
64+
return super().list(request,*args,**kwargs)
65+
66+
67+
class UpdateWarehouseView(generics.UpdateAPIView):
68+
serializer_class = WarehouseSerializer
69+
authentication_classes = [JWTAuthentication]
70+
permission_classes = [IsAuthenticated]
71+
72+
def get_queryset(self):
73+
return Warehouse.objects.filter(domain_user_id=self.request.user.domain_user_id.id,id=self.kwargs['pk'])
74+
75+
def perform_update(self,serializer):
76+
serializer.save()
Binary file not shown.
Binary file not shown.

Backend/EcommerceInventory/InventoryServices/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ class Warehouse(models.Model):
2626
created_at=models.DateTimeField(auto_now_add=True)
2727
updated_at=models.DateTimeField(auto_now=True)
2828

29+
def defaultkey():
30+
return "name"
31+
2932
class RackAndShelvesAndFloor(models.Model):
3033
id=models.AutoField(primary_key=True)
3134
name=models.CharField(max_length=255,blank=True,null=True)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from django.urls import path
2+
from .Controller.WarehouseController import WarehouseListView,UpdateWarehouseView
3+
4+
urlpatterns=[
5+
path('warehouse/', WarehouseListView.as_view(), name='warehouse_list'),
6+
path('toggleWarehouse/<pk>/', UpdateWarehouseView.as_view(), name='update_warehouse'),
7+
]

Backend/EcommerceInventory/ProductServices/controller/CategoryController.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from EcommerceInventory.Helpers import CommonListAPIMixin, CustomPageNumberPagination, renderResponse
1+
from EcommerceInventory.Helpers import CommonListAPIMixin, CustomPageNumberPagination, createParsedCreatedAtUpdatedAt, renderResponse
22
from ProductServices.models import Categories
33
from rest_framework import generics
44
from rest_framework import serializers
@@ -7,6 +7,7 @@
77
from django.db.models import Q
88
from django.db import models
99

10+
@createParsedCreatedAtUpdatedAt
1011
class CategorySerializer(serializers.ModelSerializer):
1112
children = serializers.SerializerMethodField()
1213
domain_user_id=serializers.SerializerMethodField()

Backend/EcommerceInventory/ProductServices/controller/ProductController.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from UserServices.models import Users
2-
from EcommerceInventory.Helpers import CommonListAPIMixin, CustomPageNumberPagination, renderResponse
2+
from EcommerceInventory.Helpers import CommonListAPIMixin, CustomPageNumberPagination, createParsedCreatedAtUpdatedAt, renderResponse
33
from ProductServices.models import ProductQuestions, ProductReviews, Products
44
from rest_framework import generics
55
from rest_framework import serializers
@@ -8,6 +8,7 @@
88
from django.db.models import Q
99
from django.db import models
1010

11+
@createParsedCreatedAtUpdatedAt
1112
class ProductReviewSerializer(serializers.ModelSerializer):
1213
review_user_id=serializers.SerializerMethodField()
1314
class Meta:
@@ -17,6 +18,7 @@ class Meta:
1718
def get_review_user_id(self,obj):
1819
return "#"+str(obj.review_user_id.id)+" "+obj.review_user_id.username
1920

21+
@createParsedCreatedAtUpdatedAt
2022
class ProductQuestionSerializer(serializers.ModelSerializer):
2123
question_user_id=serializers.SerializerMethodField()
2224
answer_user_id=serializers.SerializerMethodField()
@@ -29,7 +31,7 @@ def get_question_user_id(self,obj):
2931

3032
def get_answer_user_id(self,obj):
3133
return "#"+str(obj.answer_user_id.id)+" "+obj.answer_user_id.username
32-
34+
@createParsedCreatedAtUpdatedAt
3335
class ProductSerializer(serializers.ModelSerializer):
3436
category_id=serializers.SerializerMethodField()
3537
domain_user_id=serializers.SerializerMethodField()

Frontend/ecommerce_inventory/src/App.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import 'react-toastify/dist/ReactToastify.css';
1515
import './style/style.css';
1616
import ManageCategories from './pages/category/ManageCategories';
1717
import ManageProducts from './pages/products/ManageProducts';
18+
import Error404Page from './pages/Error404Page';
19+
import ManageWarhouse from './pages/warehouse/ManageWarehouse';
1820

1921
function App() {
2022
const {status,error,items}=useSelector(state=>state.sidebardata);
@@ -32,12 +34,14 @@ function App() {
3234
{
3335
path:"/",
3436
element:<Layout sidebarList={items}/>,
37+
errorElement:<Layout sidebarList={items} childPage={<Error404Page/>}/>,
3538
children:[
3639
{path:"/",element:<ProtectedRoute element={<Home/>}/>},
3740
{path:"/home",element:<ProtectedRoute element={<Home/>}/>},
3841
{path:"/form/:formName/:id?",element:<ProtectedRoute element={<DynamicForm/>}/>},
3942
{path:"/manage/category",element:<ProtectedRoute element={<ManageCategories/>}/>},
40-
{path:"/manage/product",element:<ProtectedRoute element={<ManageProducts/>}/>}
43+
{path:"/manage/product",element:<ProtectedRoute element={<ManageProducts/>}/>},
44+
{path:"/manage/warehouse",element:<ProtectedRoute element={<ManageWarhouse/>}/>}
4145
]},
4246
]
4347
)

Frontend/ecommerce_inventory/src/components/StepTextComponents.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
import {useFormContext} from 'react-hook-form';
22
import { Box,FormControl,InputLabel,Select,MenuItem, FormControlLabel, Switch, TextField } from "@mui/material";
3+
import { useEffect, useState } from "react";
34

45
const StepTextComponents = ({formConfig,fieldType}) => {
5-
const {register,formState:{errors}} = useFormContext();
6-
const textFiels=formConfig.data.text;
6+
const {register,formState:{errors},reset} = useFormContext();
7+
const [textFiels,setTextFiels]=useState(formConfig.data.text);
8+
9+
useEffect(()=>{
10+
setTextFiels(formConfig.data.text);
11+
const defaultValues=formConfig.data.text.reduce((acc,field)=>{
12+
acc[field.name]=field.default;
13+
return acc;
14+
},{});
15+
reset(defaultValues);
16+
},[formConfig.data.text])
17+
718
return (
819
<Box>
920
{textFiels.map((field,index)=>(

Frontend/ecommerce_inventory/src/pages/DynamicForm.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@ import { useForm } from 'react-hook-form';
1313
import { toast } from 'react-toastify';
1414
import { getFormTypes } from '../utils/Helper';
1515
import { useNavigate } from 'react-router-dom';
16-
const DynamicForm=()=>{
16+
const DynamicForm=({formNameVar,idVar,onSaveEvent})=>{
1717
const stepItems=getFormTypes();
18-
const {formName,id}=useParams();
18+
let {formName,id}=useParams();
19+
if(formNameVar){
20+
formName=formNameVar;
21+
}
22+
if(idVar){
23+
id=idVar;
24+
}
1925
const {error,loading,callApi}=useApi();
2026
const [formConfig,setFormConfig]=useState(null);
2127
const [currentStep,setCurrentStep]=useState(0);
@@ -24,8 +30,10 @@ const DynamicForm=()=>{
2430
const navigate=useNavigate();
2531

2632
useEffect(()=>{
33+
methods.reset();
34+
setSteps(stepItems);
2735
fetchForm();
28-
},[formName])
36+
},[formName,formNameVar,idVar])
2937

3038
const fetchForm=async()=>{
3139
const PID=id?`${id}/`:'';
@@ -60,7 +68,12 @@ const DynamicForm=()=>{
6068
toast.success(response.data.message);
6169
setCurrentStep(0);
6270
methods.reset();
63-
navigate(`/manage/${formName}`)
71+
if(onSaveEvent){
72+
onSaveEvent();
73+
}
74+
else{
75+
navigate(`/manage/${formName}`)
76+
}
6477
}
6578
catch(err){
6679
console.log(err);
@@ -96,7 +109,7 @@ const DynamicForm=()=>{
96109

97110
return (
98111
<Container>
99-
<Typography variant="h6" gutterBottom>{id?'EDIT':'ADD'} {formName.toUpperCase()}</Typography>
112+
{(!formNameVar) && <Typography variant="h6" gutterBottom>{id?'EDIT':'ADD'} {formName.toUpperCase()}</Typography>}
100113
<Divider sx={{margingTop:'15px',marginBottom:'15px'}}/>
101114
<Stepper activeStep={currentStep} sx={{overflowX:'auto'}} alternativeLabel>
102115
{steps.map((step,index)=>(
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import {Box} from '@mui/material';
2+
const Error404Page=()=>{
3+
return <Box sx={{textAlign:'center',marginTop:'100px'}}>
4+
<h1>404 Error</h1>
5+
<h2>Page Not Found</h2>
6+
</Box>
7+
}
8+
export default Error404Page;

0 commit comments

Comments
 (0)