Skip to content

Commit

Permalink
Ready for Deploy
Browse files Browse the repository at this point in the history
  • Loading branch information
younusFoysal committed Jan 3, 2025
0 parents commit 21a07f1
Show file tree
Hide file tree
Showing 23 changed files with 7,313 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.vercel
node_modules
.env
5 changes: 5 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/server.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import express from 'express';
import cors from 'cors';
import dotenv from 'dotenv';
import mongoose from 'mongoose';
import authRoutes from './routes/auth.js';
import productRoutes from './routes/products.js';
import salesRoutes from './routes/sales.js';
import purchasesRoutes from './routes/purchases.js';
import supplierRoutes from './routes/suppliers.js';
import customerRoutes from './routes/customers.js';
import reportRoutes from './routes/reports.js';

dotenv.config();

const app = express();

app.use(cors());
app.use(express.json());

// Connect to MongoDB
mongoose.connect(process.env.MONGODB_URI)
.then(() => console.log('Connected to MongoDB'))
.catch((err) => console.error('MongoDB connection error:', err));

// Routes
app.use('/api/auth', authRoutes);
app.use('/api/products', productRoutes);
app.use('/api/sales', salesRoutes);
app.use('/api/purchases', purchasesRoutes);
app.use('/api/suppliers', supplierRoutes);
app.use('/api/customers', customerRoutes);
app.use('/api/reports', reportRoutes);
app.get("/", (req, res) => {
res.send("Pharmacy Server Is Running...");
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
18 changes: 18 additions & 0 deletions middleware/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import jwt from 'jsonwebtoken';

export const authenticateToken = (req, res, next) => {
const authHeader = req.headers.authorization;
const token = authHeader && authHeader.split(' ')[1];

if (!token) {
return res.status(401).json({ message: 'No token provided' });
}

try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
return res.status(403).json({ message: 'Invalid token' });
}
};
46 changes: 46 additions & 0 deletions models/Customer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import mongoose from 'mongoose';

const customerSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
phone: {
type: String,
required: true
},
address: {
street: String,
city: String,
state: String,
zipCode: String,
country: String
},
healthInfo: {
allergies: [String],
conditions: [String],
medications: [String]
},
dateOfBirth: Date,
gender: {
type: String,
enum: ['male', 'female', 'other'],
default: 'other'
},
insuranceInfo: {
provider: String,
policyNumber: String
}
}, {
timestamps: true
});

// Index for search optimization
customerSchema.index({ name: 'text', email: 'text', phone: 'text' });

export default mongoose.model('Customer', customerSchema);
37 changes: 37 additions & 0 deletions models/Product.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import mongoose from 'mongoose';

const productSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
description: String,
category: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
cost: {
type: Number,
required: true
},
stock: {
type: Number,
required: true,
default: 0
},
manufacturer: String,
expiryDate: Date,
batchNumber: String,
reorderLevel: {
type: Number,
default: 10
}
}, {
timestamps: true
});

export default mongoose.model('Product', productSchema);
63 changes: 63 additions & 0 deletions models/PurchaseOrder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import mongoose from 'mongoose';

const purchaseOrderSchema = new mongoose.Schema({
orderNumber: {
type: String,
required: true,
unique: true
},
supplier: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Supplier',
required: true
},
items: [{
product: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Product',
required: true
},
quantity: {
type: Number,
required: true
},
unitCost: {
type: Number,
required: true
},
subtotal: {
type: Number,
required: true
}
}],
status: {
type: String,
enum: ['draft', 'ordered', 'received', 'cancelled'],
default: 'draft'
},
totalAmount: {
type: Number,
required: true
},
expectedDeliveryDate: Date,
receivedDate: Date,
notes: String,
createdBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
}
}, {
timestamps: true
});

// Generate order number before saving
// purchaseOrderSchema.pre('save', async function(next) {
// if (this.isNew) {
// const count = await this.constructor.countDocuments();
// this.orderNumber = `PO${String(count + 1).padStart(6, '0')}`;
// }
// next();
// });

export default mongoose.model('PurchaseOrder', purchaseOrderSchema);
89 changes: 89 additions & 0 deletions models/Sale.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import mongoose from 'mongoose';

const saleSchema = new mongoose.Schema({
invoiceNumber: {
type: String,
required: true,
unique: true
},
date: {
type: Date,
default: Date.now
},
customerId: {
type: String,
required: true,
},
customerName: {
type: String,
required: true
},
customerPhone: String,
items: [{
product: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Product',
required: true
},
quantity: {
type: Number,
required: true
},
price: {
type: Number,
required: true
},
subtotal: {
type: Number,
required: true
}
}],
total: {
type: Number,
required: true
},
paidAmount: {
type: Number,
required: true
},
dueAmount :{
type: Number,
},
paymentMethod: {
type: String,
enum: ['cash', 'card'],
default: 'cash'
},
status: {
type: String,
enum: ['paid', 'partial'],
default: 'paid'
}
}, {
timestamps: true
});

// Generate invoice number before saving
// saleSchema.pre('save', async function(next) {
// if (this.isNew) {
// const count = await this.constructor.countDocuments();
// this.invoiceNumber = `INV${String(count + 1).padStart(6, '0')}`;
// }
// next();
// });

saleSchema.pre('save', async function (next) {
if (this.isNew) {
try {
// Fetch the current count of Sale documents
const count = await this.constructor.countDocuments();
// Generate a unique invoice number
this.invoiceNumber = `INV${String(count + 1).padStart(6, '0')}`;
} catch (error) {
return next(error); // Pass any errors to Mongoose's error handling
}
}
next();
});

export default mongoose.model('Sale', saleSchema);
35 changes: 35 additions & 0 deletions models/Supplier.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import mongoose from 'mongoose';

const supplierSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
phone: {
type: String,
required: true
},
address: {
street: String,
city: String,
state: String,
zipCode: String,
country: String
},
contactPerson: String,
taxId: String,
status: {
type: String,
enum: ['active', 'inactive'],
default: 'active'
},
notes: String
}, {
timestamps: true
});

export default mongoose.model('Supplier', supplierSchema);
Loading

0 comments on commit 21a07f1

Please sign in to comment.