create-cactus 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-cactus",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Create a new Stock Management System (Cactus)",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -1,4 +1,20 @@
1
1
  import stocktransaction from "../models/stocktransaction.js";
2
+ import product from "../models/products.js";
3
+
4
+ async function updateInventory(ProductCode, QuantityMoved, TransactionType) {
5
+ const prod = await product.findOne({ ProductCode });
6
+ if (!prod) throw { status: 404, message: "product not found" };
7
+
8
+ if (TransactionType === "IN") {
9
+ prod.QuantityInStock += QuantityMoved;
10
+ } else {
11
+ prod.QuantityInStock -= QuantityMoved;
12
+ if (prod.QuantityInStock < 0) {
13
+ throw { status: 400, message: "insufficient stock" };
14
+ }
15
+ }
16
+ await prod.save();
17
+ }
2
18
 
3
19
  export const addStock=async(req,res)=>{
4
20
  try {
@@ -9,10 +25,12 @@ export const addStock=async(req,res)=>{
9
25
  return res.status(400).json({message:"stockTransaction already exists"})
10
26
  }
11
27
 
28
+ await updateInventory(ProductCode, QuantityMoved, TransactionType);
12
29
  await new stocktransaction({TransactionId,TransactionDate,QuantityMoved,TransactionType,UserId,WarehouseCode,ProductCode}).save();
13
30
 
14
31
  res.status(201).json({message:"new stockTransaction created"})
15
32
  } catch (error) {
33
+ if (error.status) return res.status(error.status).json({message:error.message});
16
34
  res.status(500).json({message:"internal server error",error:error.message})
17
35
 
18
36
  }
@@ -46,25 +64,39 @@ export const getAllStocks=async(req,res)=>{
46
64
 
47
65
  export const updateStock=async(req,res)=>{
48
66
  try {
49
- const stockExists=await stocktransaction.findByIdAndUpdate(req.params.id,req.body,{new:true});
67
+ const old = await stocktransaction.findById(req.params.id);
68
+ if (!old) return res.status(404).json({ message: "stock transaction not found" });
50
69
 
51
- if (!stockExists) {
52
- return res.status(404).json({ message: "stock transaction not found" });
53
- }
54
- res.status(200).json(stockExists);
70
+ const { TransactionType, QuantityMoved, ProductCode } = req.body;
71
+
72
+ if (ProductCode && ProductCode !== old.ProductCode) {
73
+ return res.status(400).json({ message: "cannot change product on an existing transaction" });
74
+ }
75
+
76
+ const revertType = old.TransactionType === "IN" ? "OUT" : "IN";
77
+ await updateInventory(old.ProductCode, old.QuantityMoved, revertType);
78
+ await updateInventory(old.ProductCode, QuantityMoved || old.QuantityMoved, TransactionType || old.TransactionType);
79
+
80
+ const updated = await stocktransaction.findByIdAndUpdate(req.params.id, req.body, {new:true});
81
+ res.status(200).json(updated);
55
82
  } catch (error) {
83
+ if (error.status) return res.status(error.status).json({message:error.message});
56
84
  res.status(500).json({message:"internal server error",error:error.message})
57
85
  }
58
86
  };
87
+
59
88
  export const deleteStock=async(req,res)=>{
60
89
  try {
61
- const stockExists=await stocktransaction.findByIdAndDelete(req.params.id);
90
+ const target = await stocktransaction.findById(req.params.id);
91
+ if (!target) return res.status(404).json({ message: "stock transaction not found" });
62
92
 
63
- if (!stockExists) {
64
- return res.status(404).json({ message: "stock transaction not found" });
65
- }
66
- res.status(200).json({message:"stock transaction deleted"});
93
+ const revertType = target.TransactionType === "IN" ? "OUT" : "IN";
94
+ await updateInventory(target.ProductCode, target.QuantityMoved, revertType);
95
+ await stocktransaction.findByIdAndDelete(req.params.id);
96
+
97
+ res.status(200).json({message:"stock transaction deleted"});
67
98
  } catch (error) {
99
+ if (error.status) return res.status(error.status).json({message:error.message});
68
100
  res.status(500).json({message:"internal server error",error:error.message})
69
101
  }
70
102
  }
@@ -37,9 +37,10 @@ export const login=async(req,res)=>{
37
37
  const verifypassword=await bcryptjs.compare(password,userExists.password)
38
38
 
39
39
  if(!verifypassword){
40
- return res.status(404).json({message:"wrong password"});
40
+ return res.status(401).json({message:"wrong password"});
41
41
  }
42
- const token=jwt.sign({UserId:userExists.UserId,email:userExists.email},"secretkey",{expiresIn:"1d"})
42
+ const token=jwt.sign({UserId:userExists.UserId,email:userExists.email},process.env.JWT_SECRET,{expiresIn:"1d"})
43
+ res.cookie("token", token, {httpOnly: false, secure: true, sameSite: "none", maxAge: 60*60*1000})
43
44
  res.status(200).json({message:"user logged in successfully",token,username:userExists.username})
44
45
 
45
46
 
@@ -50,7 +51,7 @@ export const login=async(req,res)=>{
50
51
 
51
52
  export const getAllProfiles=async(req,res)=>{
52
53
  try {
53
- const userExists= await user.find()
54
+ const userExists= await user.find().select('-password')
54
55
  if(!userExists){
55
56
  return res.status(404).json({message:"no users found"})
56
57
  }
@@ -66,7 +67,7 @@ export const getProfile=async(req,res)=>{
66
67
  try {
67
68
  const userExists= await user.findById(req.params.id);
68
69
  if(!userExists){
69
- return res.status(404).json({mesage:"user not found"});
70
+ return res.status(404).json({message:"user not found"});
70
71
  }
71
72
 
72
73
  res.status(200).json({user:{
@@ -7,7 +7,7 @@ export const verifyToken = (req, res, next) => {
7
7
  }
8
8
  const token = authHeader.split(' ')[1];
9
9
  try {
10
- const decoded = jwt.verify(token, process.env.JWT_SECRET || 'secretkey');
10
+ const decoded = jwt.verify(token, process.env.JWT_SECRET);
11
11
  req.user = decoded;
12
12
  next();
13
13
  } catch (error) {
@@ -6,7 +6,7 @@ const productSchema=new mongoose.Schema({
6
6
  ProductName:{type:String,required:true},
7
7
  Category:{type:String,required:true},
8
8
  QuantityInStock:{type:Number,required:true},
9
- UnitPrice:{type:String,required:true},
9
+ UnitPrice:{type:Number,required:true},
10
10
  SupplierName:{type:String,required:true},
11
11
  DateRecorded:{type:Date,default:Date.now}
12
12
  })
@@ -6,7 +6,7 @@ const stocktransactionSchema=new mongoose.Schema({
6
6
  TransactionId:{type:Number,required:true,unique:true},
7
7
  TransactionDate:{type:Date,default:Date.now},
8
8
  QuantityMoved:{type:Number,required:true},
9
- TransactionType:{type:String,required:true},
9
+ TransactionType:{type:String,required:true,enum:['IN','OUT']},
10
10
  UserId:{type:String,required:true,ref:'user'},
11
11
  WarehouseCode:{type:String,required:true,ref:'warehouse'},
12
12
  ProductCode:{type:String,required:true,ref:'products'},
@@ -1,14 +1,14 @@
1
1
  import express from 'express';
2
2
  import { deleteUser, getAllProfiles, getProfile, login, signup, updateUser } from '../controllers/userController.js';
3
-
3
+ import { verifyToken } from '../middleware/authMiddleware.js';
4
4
 
5
5
  const router=express.Router();
6
6
 
7
7
  router.post("/register",signup);
8
8
  router.post("/login",login);
9
- router.get("/profiles",getAllProfiles)
10
- router.get("/profile/:id",getProfile);
11
- router.put("/updateUser/:id",updateUser);
12
- router.delete("/deleteUser/:id",deleteUser)
9
+ router.get("/profiles",verifyToken,getAllProfiles)
10
+ router.get("/profile/:id",verifyToken,getProfile);
11
+ router.put("/updateUser/:id",verifyToken,updateUser);
12
+ router.delete("/deleteUser/:id",verifyToken,deleteUser)
13
13
 
14
14
  export default router;
@@ -2,6 +2,7 @@ import express from 'express';
2
2
  import cors from 'cors';
3
3
  import 'dotenv/config';
4
4
  import cookieParser from 'cookie-parser';
5
+
5
6
  import { connectDb } from './db/connectDb.js';
6
7
  import userRoutes from './routes/userRoutes.js';
7
8
  import productsRoutes from './routes/productsRoutes.js';
@@ -20,5 +20,8 @@ export const addWarehouse = (data) => api.post('/api/warehouses/insertWarehouse'
20
20
  export const getAllWarehouses = () => api.get('/api/warehouses')
21
21
  export const addStock = (data) => api.post('/api/stocktransactions/insertStock', data)
22
22
  export const getAllStocks = () => api.get('/api/stocktransactions/getStocks')
23
+ export const getStock = (id) => api.get(`/api/stocktransactions/getStock/${id}`)
24
+ export const updateStock = (id, data) => api.put(`/api/stocktransactions/updateStock/${id}`, data)
25
+ export const deleteStock = (id) => api.delete(`/api/stocktransactions/deleteStock/${id}`)
23
26
  export const getAllProfiles = () => api.get('/api/user/profiles')
24
27
  export const getReports = () => api.get('/api/reports/getReport')
@@ -15,7 +15,7 @@ export default function Products() {
15
15
  ProductName: event.target.ProductName.value,
16
16
  Category: event.target.Category.value,
17
17
  QuantityInStock: Number(event.target.QuantityInStock.value),
18
- UnitPrice: event.target.UnitPrice.value,
18
+ UnitPrice: Number(event.target.UnitPrice.value),
19
19
  SupplierName: event.target.SupplierName.value,
20
20
  };
21
21
 
@@ -1,33 +1,35 @@
1
1
  import React, { useEffect, useState } from "react";
2
- import { addStock, getAllProducts, getAllWarehouses, getAllProfiles } from "../api/api";
3
- import { useNavigate } from "react-router-dom";
2
+ import { addStock, getAllProducts, getAllWarehouses, getAllProfiles, getAllStocks, updateStock, deleteStock } from "../api/api";
4
3
 
5
4
  export default function Stocks() {
6
- const navigate = useNavigate();
7
5
  const [loading, setLoading] = useState(false);
8
6
  const [products, setProducts] = useState([]);
9
7
  const [warehouses, setWarehouses] = useState([]);
10
8
  const [users, setUsers] = useState([]);
9
+ const [transactions, setTransactions] = useState([]);
10
+ const [editing, setEditing] = useState(null);
11
11
 
12
12
  useEffect(() => {
13
- async function fetchOptions() {
13
+ async function fetchData() {
14
14
  try {
15
- const [pRes, wRes, uRes] = await Promise.all([
15
+ const [pRes, wRes, uRes, tRes] = await Promise.all([
16
16
  getAllProducts(),
17
17
  getAllWarehouses(),
18
18
  getAllProfiles(),
19
+ getAllStocks(),
19
20
  ]);
20
21
  setProducts(pRes.data);
21
22
  setWarehouses(wRes.data);
22
23
  setUsers(uRes.data);
24
+ setTransactions(tRes.data);
23
25
  } catch (error) {
24
- console.error("Failed to load options", error);
26
+ console.error("Failed to load data", error);
25
27
  }
26
28
  }
27
- fetchOptions();
29
+ fetchData();
28
30
  }, []);
29
31
 
30
- async function handleSubmit(event) {
32
+ async function handleAdd(event) {
31
33
  event.preventDefault();
32
34
  setLoading(true);
33
35
 
@@ -44,7 +46,9 @@ export default function Stocks() {
44
46
  try {
45
47
  await addStock(formData);
46
48
  alert('Stock transaction recorded');
47
- navigate('/reports');
49
+ event.target.reset();
50
+ const tRes = await getAllStocks();
51
+ setTransactions(tRes.data);
48
52
  } catch (error) {
49
53
  alert(error.response?.data?.message || 'Failed to add transaction');
50
54
  } finally {
@@ -52,72 +56,166 @@ export default function Stocks() {
52
56
  }
53
57
  }
54
58
 
59
+ async function handleEdit(event) {
60
+ event.preventDefault();
61
+ setLoading(true);
62
+
63
+ const formData = {
64
+ TransactionDate: event.target.TransactionDate.value || undefined,
65
+ QuantityMoved: Number(event.target.QuantityMoved.value),
66
+ TransactionType: event.target.TransactionType.value,
67
+ UserId: event.target.UserId.value,
68
+ WarehouseCode: event.target.WarehouseCode.value,
69
+ };
70
+
71
+ try {
72
+ await updateStock(editing, formData);
73
+ alert('Transaction updated');
74
+ setEditing(null);
75
+ const tRes = await getAllStocks();
76
+ setTransactions(tRes.data);
77
+ } catch (error) {
78
+ alert(error.response?.data?.message || 'Failed to update transaction');
79
+ } finally {
80
+ setLoading(false);
81
+ }
82
+ }
83
+
84
+ async function handleDelete(id) {
85
+ if (!window.confirm('Delete this transaction? This will revert inventory.')) return;
86
+ try {
87
+ await deleteStock(id);
88
+ alert('Transaction deleted');
89
+ const tRes = await getAllStocks();
90
+ setTransactions(tRes.data);
91
+ } catch (error) {
92
+ alert(error.response?.data?.message || 'Failed to delete');
93
+ }
94
+ }
95
+
96
+ function openEdit(t) {
97
+ setEditing(t._id);
98
+ }
99
+
100
+ const editTx = editing ? transactions.find(t => t._id === editing) : null;
101
+
55
102
  return (
56
- <div className="flex flex-col items-center">
57
- <h1 className="text-xl font-bold text-gray-800 mb-4 hover:text-olive-600 cursor-pointer">Stock Transaction</h1>
58
- <div className="bg-white border border-gray-200 rounded-lg p-4 w-full max-w-lg">
59
- <form onSubmit={handleSubmit} className="space-y-4">
60
- <div className="grid grid-cols-2 gap-4">
61
- <div>
62
- <label className="block text-sm font-medium text-gray-700 mb-1">Transaction ID</label>
63
- <input type="number" name="TransactionId" required placeholder="Enter t-Id" className="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-olive-500" />
64
- </div>
65
- <div>
66
- <label className="block text-sm font-medium text-gray-700 mb-1">Date</label>
67
- <input type="date" name="TransactionDate" className="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-olive-500" />
68
- </div>
69
- </div>
103
+ <div className="space-y-4">
104
+ <h1 className="text-xl font-bold text-gray-800 hover:text-olive-600 cursor-pointer text-center">Stock Transaction</h1>
70
105
 
71
- <div className="grid grid-cols-2 gap-4">
72
- <div>
73
- <label className="block text-sm font-medium text-gray-700 mb-1">Quantity</label>
74
- <input type="number" name="QuantityMoved" required placeholder="Enter Quantity Moved" className="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-olive-500" />
106
+ <div className="flex flex-col lg:flex-row gap-4 items-start">
107
+ <div className="bg-white border border-gray-200 rounded-lg p-4 w-full lg:w-96 shrink-0">
108
+ <h2 className="text-base font-semibold mb-2">{editing ? 'Edit Transaction' : 'New Transaction'}</h2>
109
+ <form onSubmit={editing ? handleEdit : handleAdd} className="space-y-2">
110
+ <div className="grid grid-cols-2 gap-2">
111
+ <div>
112
+ <label className="block text-xs font-medium text-gray-700 mb-0.5">T-ID</label>
113
+ <input type="number" name="TransactionId" required disabled={!!editing} defaultValue={editTx?.TransactionId || ''} placeholder="t-Id" className="w-full border border-gray-300 rounded px-2 py-1.5 text-xs focus:outline-none focus:ring-2 focus:ring-olive-500 disabled:bg-gray-100" />
114
+ </div>
115
+ <div>
116
+ <label className="block text-xs font-medium text-gray-700 mb-0.5">Date</label>
117
+ <input type="date" name="TransactionDate" defaultValue={editTx ? editTx.TransactionDate?.split('T')[0] : ''} className="w-full border border-gray-300 rounded px-2 py-1.5 text-xs focus:outline-none focus:ring-2 focus:ring-olive-500" />
118
+ </div>
75
119
  </div>
76
- <div>
77
- <label className="block text-sm font-medium text-gray-700 mb-1">Type</label>
78
- <select name="TransactionType" required className="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-olive-500 bg-white">
79
- <option value="">Select</option>
80
- <option value="IN">Stock In</option>
81
- <option value="OUT">Stock Out</option>
82
- </select>
120
+ <div className="grid grid-cols-2 gap-2">
121
+ <div>
122
+ <label className="block text-xs font-medium text-gray-700 mb-0.5">Quantity</label>
123
+ <input type="number" name="QuantityMoved" required defaultValue={editTx?.QuantityMoved || ''} placeholder="Quantity" className="w-full border border-gray-300 rounded px-2 py-1.5 text-xs focus:outline-none focus:ring-2 focus:ring-olive-500" />
124
+ </div>
125
+ <div>
126
+ <label className="block text-xs font-medium text-gray-700 mb-0.5">Type</label>
127
+ <select name="TransactionType" required defaultValue={editTx?.TransactionType || ''} className="w-full border border-gray-300 rounded px-2 py-1.5 text-xs focus:outline-none focus:ring-2 focus:ring-olive-500 bg-white">
128
+ <option value="">Select</option>
129
+ <option value="IN">IN</option>
130
+ <option value="OUT">OUT</option>
131
+ </select>
132
+ </div>
83
133
  </div>
84
- </div>
85
-
86
- <div>
87
- <label className="block text-sm font-medium text-gray-700 mb-1">User</label>
88
- <select name="UserId" required className="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-olive-500 bg-white">
89
- <option value="">Select user</option>
90
- {users.map((u) => (
91
- <option key={u._id} value={u.UserId}>{u.UserId} — {u.username}</option>
92
- ))}
93
- </select>
94
- </div>
95
-
96
- <div className="grid grid-cols-2 gap-4">
97
134
  <div>
98
- <label className="block text-sm font-medium text-gray-700 mb-1">Warehouse</label>
99
- <select name="WarehouseCode" required className="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-olive-500 bg-white">
100
- <option value="">Select warehouse</option>
101
- {warehouses.map((w) => (
102
- <option key={w._id} value={w.WarehouseCode}>{w.WarehouseCode} — {w.WarehouseName}</option>
135
+ <label className="block text-xs font-medium text-gray-700 mb-0.5">User</label>
136
+ <select name="UserId" required defaultValue={editTx?.UserId || ''} className="w-full border border-gray-300 rounded px-2 py-1.5 text-xs focus:outline-none focus:ring-2 focus:ring-olive-500 bg-white">
137
+ <option value="">Select</option>
138
+ {users.map((u) => (
139
+ <option key={u._id} value={u.UserId}>{u.UserId}</option>
103
140
  ))}
104
141
  </select>
105
142
  </div>
106
- <div>
107
- <label className="block text-sm font-medium text-gray-700 mb-1">Product</label>
108
- <select name="ProductCode" required className="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-olive-500 bg-white">
109
- <option value="">Select product</option>
110
- {products.map((p) => (
111
- <option key={p._id} value={p.ProductCode}>{p.ProductCode} — {p.ProductName}</option>
112
- ))}
113
- </select>
143
+ <div className="grid grid-cols-2 gap-2">
144
+ <div>
145
+ <label className="block text-xs font-medium text-gray-700 mb-0.5">Warehouse</label>
146
+ <select name="WarehouseCode" required defaultValue={editTx?.WarehouseCode || ''} disabled={!!editing} className="w-full border border-gray-300 rounded px-2 py-1.5 text-xs focus:outline-none focus:ring-2 focus:ring-olive-500 bg-white disabled:bg-gray-100">
147
+ <option value="">Select</option>
148
+ {warehouses.map((w) => (
149
+ <option key={w._id} value={w.WarehouseCode}>{w.WarehouseCode}</option>
150
+ ))}
151
+ </select>
152
+ </div>
153
+ <div>
154
+ <label className="block text-xs font-medium text-gray-700 mb-0.5">Product</label>
155
+ <select name="ProductCode" required defaultValue={editTx?.ProductCode || ''} disabled={!!editing} className="w-full border border-gray-300 rounded px-2 py-1.5 text-xs focus:outline-none focus:ring-2 focus:ring-olive-500 bg-white disabled:bg-gray-100">
156
+ <option value="">Select</option>
157
+ {products.map((p) => (
158
+ <option key={p._id} value={p.ProductCode}>{p.ProductCode}</option>
159
+ ))}
160
+ </select>
161
+ </div>
114
162
  </div>
115
- </div>
163
+ <div className="flex gap-2 pt-1">
164
+ <button type="submit" disabled={loading} className="flex-1 h-8 text-xs bg-olive-600 hover:bg-olive-700 disabled:bg-gray-400 text-white rounded font-medium">
165
+ {loading ? '...' : editing ? 'Update' : 'Add'}
166
+ </button>
167
+ {editing && (
168
+ <button type="button" onClick={() => setEditing(null)} className="h-8 px-3 text-xs bg-gray-300 hover:bg-gray-400 rounded font-medium">
169
+ Cancel
170
+ </button>
171
+ )}
172
+ </div>
173
+ </form>
174
+ </div>
116
175
 
117
- <button type="submit" className="w-full h-10 bg-olive-600 hover:bg-olive-700 text-white rounded font-medium ">
118
- Add
119
- </button>
120
- </form>
176
+ <div className="w-full min-w-0">
177
+ <h2 className="text-base font-semibold mb-2">Transaction History</h2>
178
+ <div className="overflow-auto bg-white rounded-lg border border-gray-200" style={{ maxHeight: '420px' }}>
179
+ <table className="w-full text-xs text-left">
180
+ <thead className="bg-gray-50 text-gray-600 uppercase sticky top-0">
181
+ <tr>
182
+ <th className="px-3 py-2">T-ID</th>
183
+ <th className="px-3 py-2">Date</th>
184
+ <th className="px-3 py-2">Type</th>
185
+ <th className="px-3 py-2">Quantityty</th>
186
+ <th className="px-3 py-2">Product</th>
187
+ <th className="px-3 py-2">Warehouse</th>
188
+ <th className="px-3 py-2">User</th>
189
+ <th className="px-3 py-2">Actions</th>
190
+ </tr>
191
+ </thead>
192
+ <tbody className="divide-y divide-gray-100">
193
+ {transactions.length === 0 && (
194
+ <tr><td colSpan={8} className="px-3 py-4 text-center text-gray-400">No transactions yet</td></tr>
195
+ )}
196
+ {transactions.map((t) => (
197
+ <tr key={t._id} className="hover:bg-gray-50">
198
+ <td className="px-3 py-2">{t.TransactionId}</td>
199
+ <td className="px-3 py-2 whitespace-nowrap">{new Date(t.TransactionDate).toLocaleDateString()}</td>
200
+ <td className="px-3 py-2">
201
+ <span className={`px-1.5 py-0.5 rounded text-xs font-medium ${t.TransactionType === 'IN' ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700'}`}>
202
+ {t.TransactionType}
203
+ </span>
204
+ </td>
205
+ <td className="px-3 py-2">{t.QuantityMoved}</td>
206
+ <td className="px-3 py-2">{t.ProductCode}</td>
207
+ <td className="px-3 py-2">{t.WarehouseCode}</td>
208
+ <td className="px-3 py-2">{t.UserId}</td>
209
+ <td className="px-3 py-2 flex gap-1.5">
210
+ <button onClick={() => openEdit(t)} className="text-blue-600 hover:underline">Edit</button>
211
+ <button onClick={() => handleDelete(t._id)} className="text-red-600 hover:underline">Del</button>
212
+ </td>
213
+ </tr>
214
+ ))}
215
+ </tbody>
216
+ </table>
217
+ </div>
218
+ </div>
121
219
  </div>
122
220
  </div>
123
221
  );
@@ -1,392 +0,0 @@
1
- <mxfile host="65bd71144e">
2
- <diagram id="PQ5hsovL6DdM_u9k81B_" name="Page-1">
3
- <mxGraphModel dx="3047" dy="863" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
4
- <root>
5
- <mxCell id="0"/>
6
- <mxCell id="1" parent="0"/>
7
- <mxCell id="2" value="&lt;b&gt;PRODUCT&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
8
- <mxGeometry x="-650" y="250" width="120" height="60" as="geometry"/>
9
- </mxCell>
10
- <mxCell id="4" value="STOCK&lt;div&gt;TRANSACTION&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1" vertex="1" parent="1">
11
- <mxGeometry x="-130" y="635" width="120" height="60" as="geometry"/>
12
- </mxCell>
13
- <mxCell id="5" value="WAREHOUSE" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1" vertex="1" parent="1">
14
- <mxGeometry x="-640" y="640" width="120" height="60" as="geometry"/>
15
- </mxCell>
16
- <mxCell id="6" value="&lt;u&gt;ProductCode&lt;/u&gt;" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
17
- <mxGeometry x="-760" y="180" width="120" height="30" as="geometry"/>
18
- </mxCell>
19
- <mxCell id="7" value="ProductName" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
20
- <mxGeometry x="-860" y="210" width="120" height="40" as="geometry"/>
21
- </mxCell>
22
- <mxCell id="8" value="Category" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
23
- <mxGeometry x="-820" y="265" width="120" height="30" as="geometry"/>
24
- </mxCell>
25
- <mxCell id="9" value="QuantityIn&lt;div&gt;Stock&lt;/div&gt;" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
26
- <mxGeometry x="-610" y="170" width="120" height="30" as="geometry"/>
27
- </mxCell>
28
- <mxCell id="10" value="UnitPrice" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
29
- <mxGeometry x="-860" y="330" width="120" height="20" as="geometry"/>
30
- </mxCell>
31
- <mxCell id="11" value="DateReceived" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
32
- <mxGeometry x="-500" y="203" width="120" height="30" as="geometry"/>
33
- </mxCell>
34
- <mxCell id="12" value="SupplierName" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
35
- <mxGeometry x="-850" y="390" width="120" height="30" as="geometry"/>
36
- </mxCell>
37
- <mxCell id="21" value="&lt;u&gt;TransactionId&lt;/u&gt;" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
38
- <mxGeometry x="40" y="535" width="120" height="40" as="geometry"/>
39
- </mxCell>
40
- <mxCell id="22" value="WarehouseCode(FK)" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
41
- <mxGeometry x="70" y="605" width="120" height="30" as="geometry"/>
42
- </mxCell>
43
- <mxCell id="23" value="TransactionType" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
44
- <mxGeometry x="10" y="665" width="120" height="40" as="geometry"/>
45
- </mxCell>
46
- <mxCell id="24" value="QuantityMoved" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
47
- <mxGeometry x="-10" y="740" width="120" height="30" as="geometry"/>
48
- </mxCell>
49
- <mxCell id="25" value="TransactionDate" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
50
- <mxGeometry x="-120" y="715" width="120" height="30" as="geometry"/>
51
- </mxCell>
52
- <mxCell id="26" value="ProductCode(FK)" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
53
- <mxGeometry x="-250" y="730" width="120" height="40" as="geometry"/>
54
- </mxCell>
55
- <mxCell id="27" value="WarehouseLocation" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
56
- <mxGeometry x="-560" y="760" width="120" height="30" as="geometry"/>
57
- </mxCell>
58
- <mxCell id="28" value="WarehouseName" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
59
- <mxGeometry x="-690" y="770" width="120" height="40" as="geometry"/>
60
- </mxCell>
61
- <mxCell id="29" value="&lt;u&gt;WarehouseCode&lt;/u&gt;" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
62
- <mxGeometry x="-780" y="655" width="120" height="30" as="geometry"/>
63
- </mxCell>
64
- <mxCell id="30" value="has" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
65
- <mxGeometry x="-405" y="240" width="80" height="80" as="geometry"/>
66
- </mxCell>
67
- <mxCell id="31" value="records" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
68
- <mxGeometry x="-425" y="630" width="80" height="80" as="geometry"/>
69
- </mxCell>
70
- <mxCell id="33" value="contains" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
71
- <mxGeometry x="-630" y="480" width="80" height="80" as="geometry"/>
72
- </mxCell>
73
- <mxCell id="36" value="" style="endArrow=none;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="31" target="5">
74
- <mxGeometry width="50" height="50" relative="1" as="geometry">
75
- <mxPoint x="-380" y="590" as="sourcePoint"/>
76
- <mxPoint x="-330" y="540" as="targetPoint"/>
77
- </mxGeometry>
78
- </mxCell>
79
- <mxCell id="39" value="" style="endArrow=none;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="1" source="33" target="2">
80
- <mxGeometry width="50" height="50" relative="1" as="geometry">
81
- <mxPoint x="-569" y="411.02" as="sourcePoint"/>
82
- <mxPoint x="-570" y="330" as="targetPoint"/>
83
- </mxGeometry>
84
- </mxCell>
85
- <mxCell id="40" value="" style="endArrow=none;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" target="33">
86
- <mxGeometry width="50" height="50" relative="1" as="geometry">
87
- <mxPoint x="-590" y="640" as="sourcePoint"/>
88
- <mxPoint x="-590.36" y="620" as="targetPoint"/>
89
- </mxGeometry>
90
- </mxCell>
91
- <mxCell id="41" value="" style="endArrow=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="31" target="4">
92
- <mxGeometry width="50" height="50" relative="1" as="geometry">
93
- <mxPoint x="-250" y="665" as="sourcePoint"/>
94
- <mxPoint x="-135" y="665" as="targetPoint"/>
95
- <Array as="points">
96
- <mxPoint x="-175" y="665"/>
97
- </Array>
98
- </mxGeometry>
99
- </mxCell>
100
- <mxCell id="42" value="" style="endArrow=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="2" target="30">
101
- <mxGeometry width="50" height="50" relative="1" as="geometry">
102
- <mxPoint x="-380" y="210" as="sourcePoint"/>
103
- <mxPoint x="-370" y="230" as="targetPoint"/>
104
- </mxGeometry>
105
- </mxCell>
106
- <mxCell id="44" value="" style="endArrow=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1">
107
- <mxGeometry width="50" height="50" relative="1" as="geometry">
108
- <mxPoint x="-60.00493141924167" y="399.99506858075836" as="sourcePoint"/>
109
- <mxPoint x="-60" y="309" as="targetPoint"/>
110
- </mxGeometry>
111
- </mxCell>
112
- <mxCell id="46" value="" style="endArrow=none;html=1;entryX=0.638;entryY=1.071;entryDx=0;entryDy=0;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryPerimeter=0;" edge="1" parent="1" source="2" target="9">
113
- <mxGeometry width="50" height="50" relative="1" as="geometry">
114
- <mxPoint x="-630" y="310" as="sourcePoint"/>
115
- <mxPoint x="-390" y="150" as="targetPoint"/>
116
- </mxGeometry>
117
- </mxCell>
118
- <mxCell id="47" value="" style="endArrow=none;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=-0.017;exitY=0.15;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="2" target="7">
119
- <mxGeometry width="50" height="50" relative="1" as="geometry">
120
- <mxPoint x="-440" y="200" as="sourcePoint"/>
121
- <mxPoint x="-390" y="150" as="targetPoint"/>
122
- </mxGeometry>
123
- </mxCell>
124
- <mxCell id="48" value="" style="endArrow=none;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="2" target="8">
125
- <mxGeometry width="50" height="50" relative="1" as="geometry">
126
- <mxPoint x="-440" y="200" as="sourcePoint"/>
127
- <mxPoint x="-690" y="280" as="targetPoint"/>
128
- </mxGeometry>
129
- </mxCell>
130
- <mxCell id="49" value="" style="endArrow=none;html=1;entryX=0.667;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.192;exitY=-0.05;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="2" target="6">
131
- <mxGeometry width="50" height="50" relative="1" as="geometry">
132
- <mxPoint x="-630" y="240" as="sourcePoint"/>
133
- <mxPoint x="-390" y="150" as="targetPoint"/>
134
- </mxGeometry>
135
- </mxCell>
136
- <mxCell id="55" value="" style="endArrow=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="26">
137
- <mxGeometry width="50" height="50" relative="1" as="geometry">
138
- <mxPoint x="-510" y="585" as="sourcePoint"/>
139
- <mxPoint x="-460" y="535" as="targetPoint"/>
140
- </mxGeometry>
141
- </mxCell>
142
- <mxCell id="56" value="" style="endArrow=none;html=1;entryX=0.367;entryY=-0.05;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="5" target="28">
143
- <mxGeometry width="50" height="50" relative="1" as="geometry">
144
- <mxPoint x="-1010" y="860" as="sourcePoint"/>
145
- <mxPoint x="-960" y="810" as="targetPoint"/>
146
- </mxGeometry>
147
- </mxCell>
148
- <mxCell id="57" value="" style="endArrow=none;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=-0.005;exitY=0.345;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="5" target="29">
149
- <mxGeometry width="50" height="50" relative="1" as="geometry">
150
- <mxPoint x="-1010" y="860" as="sourcePoint"/>
151
- <mxPoint x="-960" y="810" as="targetPoint"/>
152
- </mxGeometry>
153
- </mxCell>
154
- <mxCell id="58" value="" style="endArrow=none;html=1;exitX=0;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="2">
155
- <mxGeometry width="50" height="50" relative="1" as="geometry">
156
- <mxPoint x="-600" y="200" as="sourcePoint"/>
157
- <mxPoint x="-770" y="329" as="targetPoint"/>
158
- </mxGeometry>
159
- </mxCell>
160
- <mxCell id="59" value="" style="endArrow=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.293;exitY=1.024;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="2" target="12">
161
- <mxGeometry width="50" height="50" relative="1" as="geometry">
162
- <mxPoint x="-600" y="200" as="sourcePoint"/>
163
- <mxPoint x="-550" y="150" as="targetPoint"/>
164
- </mxGeometry>
165
- </mxCell>
166
- <mxCell id="60" value="" style="endArrow=none;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;" edge="1" parent="1" source="2">
167
- <mxGeometry width="50" height="50" relative="1" as="geometry">
168
- <mxPoint x="-602" y="310" as="sourcePoint"/>
169
- <mxPoint x="-480" y="230" as="targetPoint"/>
170
- </mxGeometry>
171
- </mxCell>
172
- <mxCell id="62" value="" style="endArrow=none;html=1;entryX=0.042;entryY=0.725;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.808;exitY=0.017;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="4" target="21">
173
- <mxGeometry width="50" height="50" relative="1" as="geometry">
174
- <mxPoint x="-190" y="565" as="sourcePoint"/>
175
- <mxPoint x="-140" y="515" as="targetPoint"/>
176
- </mxGeometry>
177
- </mxCell>
178
- <mxCell id="63" value="" style="endArrow=none;html=1;entryX=0.083;entryY=0.7;entryDx=0;entryDy=0;entryPerimeter=0;exitX=1;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="1" source="4" target="22">
179
- <mxGeometry width="50" height="50" relative="1" as="geometry">
180
- <mxPoint x="-190" y="565" as="sourcePoint"/>
181
- <mxPoint x="-140" y="515" as="targetPoint"/>
182
- </mxGeometry>
183
- </mxCell>
184
- <mxCell id="64" value="" style="endArrow=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="4" target="23">
185
- <mxGeometry width="50" height="50" relative="1" as="geometry">
186
- <mxPoint x="-190" y="565" as="sourcePoint"/>
187
- <mxPoint x="-140" y="515" as="targetPoint"/>
188
- </mxGeometry>
189
- </mxCell>
190
- <mxCell id="65" value="" style="endArrow=none;html=1;entryX=0.35;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;exitX=1;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="4" target="24">
191
- <mxGeometry width="50" height="50" relative="1" as="geometry">
192
- <mxPoint x="-190" y="565" as="sourcePoint"/>
193
- <mxPoint x="-140" y="515" as="targetPoint"/>
194
- </mxGeometry>
195
- </mxCell>
196
- <mxCell id="66" value="" style="endArrow=none;html=1;entryX=0.375;entryY=0.033;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.442;exitY=0.983;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="4" target="25">
197
- <mxGeometry width="50" height="50" relative="1" as="geometry">
198
- <mxPoint x="-190" y="565" as="sourcePoint"/>
199
- <mxPoint x="-140" y="515" as="targetPoint"/>
200
- </mxGeometry>
201
- </mxCell>
202
- <mxCell id="67" value="" style="endArrow=none;html=1;entryX=0.21;entryY=-0.024;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.698;exitY=1.071;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="5" target="27">
203
- <mxGeometry width="50" height="50" relative="1" as="geometry">
204
- <mxPoint x="-550" y="710" as="sourcePoint"/>
205
- <mxPoint x="-640" y="790" as="targetPoint"/>
206
- </mxGeometry>
207
- </mxCell>
208
- <mxCell id="69" value="" style="endArrow=none;html=1;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" target="4">
209
- <mxGeometry width="50" height="50" relative="1" as="geometry">
210
- <mxPoint x="-150" y="665" as="sourcePoint"/>
211
- <mxPoint x="-340" y="515" as="targetPoint"/>
212
- </mxGeometry>
213
- </mxCell>
214
- <mxCell id="70" value="" style="endArrow=none;html=1;exitX=0.62;exitY=1.048;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="2">
215
- <mxGeometry width="50" height="50" relative="1" as="geometry">
216
- <mxPoint x="-480" y="180" as="sourcePoint"/>
217
- <mxPoint x="-590" y="350" as="targetPoint"/>
218
- </mxGeometry>
219
- </mxCell>
220
- <mxCell id="71" value="" style="endArrow=none;html=1;" edge="1" parent="1">
221
- <mxGeometry width="50" height="50" relative="1" as="geometry">
222
- <mxPoint x="-600" y="310" as="sourcePoint"/>
223
- <mxPoint x="-590" y="350" as="targetPoint"/>
224
- </mxGeometry>
225
- </mxCell>
226
- <mxCell id="72" value="" style="endArrow=none;html=1;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" edge="1" parent="1" target="4">
227
- <mxGeometry width="50" height="50" relative="1" as="geometry">
228
- <mxPoint x="-150" y="665" as="sourcePoint"/>
229
- <mxPoint x="-340" y="515" as="targetPoint"/>
230
- </mxGeometry>
231
- </mxCell>
232
- <mxCell id="73" value="" style="endArrow=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="30">
233
- <mxGeometry width="50" height="50" relative="1" as="geometry">
234
- <mxPoint x="-520" y="290" as="sourcePoint"/>
235
- <mxPoint x="-130" y="280" as="targetPoint"/>
236
- </mxGeometry>
237
- </mxCell>
238
- <mxCell id="74" value="" style="endArrow=none;html=1;" edge="1" parent="1">
239
- <mxGeometry width="50" height="50" relative="1" as="geometry">
240
- <mxPoint x="-80" y="630" as="sourcePoint"/>
241
- <mxPoint x="-60" y="615" as="targetPoint"/>
242
- </mxGeometry>
243
- </mxCell>
244
- <mxCell id="75" value="" style="endArrow=none;html=1;" edge="1" parent="1">
245
- <mxGeometry width="50" height="50" relative="1" as="geometry">
246
- <mxPoint x="-60" y="615" as="sourcePoint"/>
247
- <mxPoint x="-50" y="630" as="targetPoint"/>
248
- </mxGeometry>
249
- </mxCell>
250
- <mxCell id="76" value="" style="endArrow=none;html=1;" edge="1" parent="1">
251
- <mxGeometry width="50" height="50" relative="1" as="geometry">
252
- <mxPoint x="-150" y="270" as="sourcePoint"/>
253
- <mxPoint x="-150" y="290" as="targetPoint"/>
254
- <Array as="points"/>
255
- </mxGeometry>
256
- </mxCell>
257
- <mxCell id="80" value="USER" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1" vertex="1" parent="1">
258
- <mxGeometry x="-130" y="248" width="120" height="60" as="geometry"/>
259
- </mxCell>
260
- <mxCell id="81" value="password" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
261
- <mxGeometry x="-250" y="233" width="120" height="20" as="geometry"/>
262
- </mxCell>
263
- <mxCell id="82" value="email" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
264
- <mxGeometry x="-20" y="208" width="120" height="25" as="geometry"/>
265
- </mxCell>
266
- <mxCell id="83" value="username" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
267
- <mxGeometry x="-110" y="188" width="120" height="20" as="geometry"/>
268
- </mxCell>
269
- <mxCell id="84" value="&lt;span style=&quot;font-weight: 400;&quot;&gt;&lt;u&gt;UserId&lt;/u&gt;&lt;/span&gt;" style="ellipse;whiteSpace=wrap;html=1;fontStyle=1" vertex="1" parent="1">
270
- <mxGeometry x="-220" y="208" width="120" height="20" as="geometry"/>
271
- </mxCell>
272
- <mxCell id="85" value="" style="endArrow=none;html=1;entryX=0.383;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="80" target="83">
273
- <mxGeometry width="50" height="50" relative="1" as="geometry">
274
- <mxPoint x="70" y="468" as="sourcePoint"/>
275
- <mxPoint x="120" y="418" as="targetPoint"/>
276
- </mxGeometry>
277
- </mxCell>
278
- <mxCell id="86" value="" style="endArrow=none;html=1;entryX=1;entryY=1;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="80" target="81">
279
- <mxGeometry width="50" height="50" relative="1" as="geometry">
280
- <mxPoint x="70" y="468" as="sourcePoint"/>
281
- <mxPoint x="120" y="418" as="targetPoint"/>
282
- </mxGeometry>
283
- </mxCell>
284
- <mxCell id="87" value="" style="endArrow=none;html=1;entryX=0.725;entryY=0.9;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" target="84">
285
- <mxGeometry width="50" height="50" relative="1" as="geometry">
286
- <mxPoint x="-100" y="248" as="sourcePoint"/>
287
- <mxPoint x="120" y="418" as="targetPoint"/>
288
- </mxGeometry>
289
- </mxCell>
290
- <mxCell id="88" value="" style="endArrow=none;html=1;entryX=0.325;entryY=0.96;entryDx=0;entryDy=0;entryPerimeter=0;exitX=1;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="1" source="80" target="82">
291
- <mxGeometry width="50" height="50" relative="1" as="geometry">
292
- <mxPoint x="70" y="468" as="sourcePoint"/>
293
- <mxPoint x="120" y="418" as="targetPoint"/>
294
- </mxGeometry>
295
- </mxCell>
296
- <mxCell id="89" value="" style="endArrow=none;html=1;" edge="1" parent="1">
297
- <mxGeometry width="50" height="50" relative="1" as="geometry">
298
- <mxPoint x="-80" y="330" as="sourcePoint"/>
299
- <mxPoint x="-40" y="330" as="targetPoint"/>
300
- </mxGeometry>
301
- </mxCell>
302
- <mxCell id="90" value="" style="endArrow=none;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" target="98">
303
- <mxGeometry width="50" height="50" relative="1" as="geometry">
304
- <mxPoint x="-60" y="630" as="sourcePoint"/>
305
- <mxPoint x="-49.15506858075878" y="448.28493141924184" as="targetPoint"/>
306
- </mxGeometry>
307
- </mxCell>
308
- <mxCell id="91" value="" style="endArrow=none;html=1;" edge="1" parent="1">
309
- <mxGeometry width="50" height="50" relative="1" as="geometry">
310
- <mxPoint x="-600" y="620" as="sourcePoint"/>
311
- <mxPoint x="-580" y="620" as="targetPoint"/>
312
- </mxGeometry>
313
- </mxCell>
314
- <mxCell id="92" value="" style="endArrow=none;html=1;entryX=1;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" target="2">
315
- <mxGeometry width="50" height="50" relative="1" as="geometry">
316
- <mxPoint x="-500" y="280" as="sourcePoint"/>
317
- <mxPoint x="-330" y="350" as="targetPoint"/>
318
- </mxGeometry>
319
- </mxCell>
320
- <mxCell id="93" value="" style="endArrow=none;html=1;entryX=1;entryY=0.75;entryDx=0;entryDy=0;" edge="1" parent="1" target="2">
321
- <mxGeometry width="50" height="50" relative="1" as="geometry">
322
- <mxPoint x="-500" y="280" as="sourcePoint"/>
323
- <mxPoint x="-330" y="350" as="targetPoint"/>
324
- </mxGeometry>
325
- </mxCell>
326
- <mxCell id="98" value="performs" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
327
- <mxGeometry x="-100" y="400" width="80" height="80" as="geometry"/>
328
- </mxCell>
329
- <mxCell id="100" value="involvedIn" style="rhombus;whiteSpace=wrap;html=1;rotation=45;" vertex="1" parent="1">
330
- <mxGeometry x="-360" y="460" width="80" height="80" as="geometry"/>
331
- </mxCell>
332
- <mxCell id="101" value="" style="endArrow=none;html=1;entryX=1;entryY=1;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="100" target="2">
333
- <mxGeometry width="50" height="50" relative="1" as="geometry">
334
- <mxPoint x="-440" y="540" as="sourcePoint"/>
335
- <mxPoint x="-390" y="490" as="targetPoint"/>
336
- </mxGeometry>
337
- </mxCell>
338
- <mxCell id="102" value="" style="endArrow=none;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="1" source="4" target="100">
339
- <mxGeometry width="50" height="50" relative="1" as="geometry">
340
- <mxPoint x="-440" y="540" as="sourcePoint"/>
341
- <mxPoint x="-390" y="490" as="targetPoint"/>
342
- </mxGeometry>
343
- </mxCell>
344
- <mxCell id="103" value="" style="endArrow=none;html=1;" edge="1" parent="1">
345
- <mxGeometry width="50" height="50" relative="1" as="geometry">
346
- <mxPoint x="-500" y="690" as="sourcePoint"/>
347
- <mxPoint x="-500" y="650" as="targetPoint"/>
348
- </mxGeometry>
349
- </mxCell>
350
- <mxCell id="104" value="&lt;u&gt;Key&lt;/u&gt;&lt;div&gt;Primary keys:-UserId&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -WarehouseCode&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -ProductCode&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-TransactionId&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Foreign keys:-WarehouseCode&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -ProductCode&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-UserId&lt;/div&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
351
- <mxGeometry x="-1170" y="640" width="370" height="370" as="geometry"/>
352
- </mxCell>
353
- <mxCell id="105" value="UserId(FK)" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
354
- <mxGeometry x="150" y="650" width="120" height="30" as="geometry"/>
355
- </mxCell>
356
- <mxCell id="106" value="" style="endArrow=none;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="105">
357
- <mxGeometry width="50" height="50" relative="1" as="geometry">
358
- <mxPoint x="20" y="640" as="sourcePoint"/>
359
- <mxPoint x="70" y="590" as="targetPoint"/>
360
- </mxGeometry>
361
- </mxCell>
362
- <mxCell id="107" value="" style="endArrow=none;html=1;" edge="1" parent="1">
363
- <mxGeometry width="50" height="50" relative="1" as="geometry">
364
- <mxPoint x="-530" y="330" as="sourcePoint"/>
365
- <mxPoint x="-500" y="310" as="targetPoint"/>
366
- </mxGeometry>
367
- </mxCell>
368
- <mxCell id="108" value="" style="endArrow=none;html=1;entryX=0.094;entryY=-0.05;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" target="4">
369
- <mxGeometry width="50" height="50" relative="1" as="geometry">
370
- <mxPoint x="-150" y="620" as="sourcePoint"/>
371
- <mxPoint x="-430" y="580" as="targetPoint"/>
372
- </mxGeometry>
373
- </mxCell>
374
- <mxCell id="109" value="" style="endArrow=none;html=1;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" target="4">
375
- <mxGeometry width="50" height="50" relative="1" as="geometry">
376
- <mxPoint x="-160" y="620" as="sourcePoint"/>
377
- <mxPoint x="-430" y="580" as="targetPoint"/>
378
- </mxGeometry>
379
- </mxCell>
380
- <mxCell id="110" value="TransactionId(FK)" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
381
- <mxGeometry x="-465" y="720" width="120" height="30" as="geometry"/>
382
- </mxCell>
383
- <mxCell id="111" value="" style="endArrow=none;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="5" target="110">
384
- <mxGeometry width="50" height="50" relative="1" as="geometry">
385
- <mxPoint x="-480" y="630" as="sourcePoint"/>
386
- <mxPoint x="-430" y="580" as="targetPoint"/>
387
- </mxGeometry>
388
- </mxCell>
389
- </root>
390
- </mxGraphModel>
391
- </diagram>
392
- </mxfile>