diff --git a/src/controllers/authcontroller.js b/src/controllers/authcontroller.js index d19435d..d3c7dc7 100644 --- a/src/controllers/authcontroller.js +++ b/src/controllers/authcontroller.js @@ -1,7 +1,7 @@ -import bcrypt from 'bcrypt'; -import jwt from 'jsonwebtoken'; -import User from '../models/User.js'; -import { createAndSendOTP, verifyOTP } from '../services/otp.service.js'; +import bcrypt from "bcrypt"; +import jwt from "jsonwebtoken"; +import User from "../models/User.js"; +import { createAndSendOTP, verifyOTP } from "../services/otp.service.js"; export const login = async (req, res) => { try { @@ -15,35 +15,39 @@ export const login = async (req, res) => { } const user = await User.findOne({ - email: { $regex: new RegExp(`^${email}$`, 'i') }, - role: { $regex: new RegExp(`^${role}$`, 'i') }, - }).select('email role status password'); + email: { $regex: new RegExp(`^${email}$`, "i") }, + role: { $regex: new RegExp(`^${role}$`, "i") }, + }).select("email role status password name"); if (!user) { - return res.status(401).json({ success: false, message: 'Invalid role or email' }); + return res.status(401).json({ success: false, message: "Invalid role or email" }); } const isMatch = await bcrypt.compare(password, user.password); if (!isMatch) { - return res.status(401).json({ success: false, message: 'Invalid password' }); + return res.status(401).json({ success: false, message: "Invalid password" }); } // if (user.role.toLowerCase() === 'doctor' && user.status !== 'Active') { // return res.status(403).json({ success: false, message: "Your account is currently inactive. Kindly reach out to the admin for support." }); // } - if (user.status !== 'Active') { - return res.status(403).json({ success: false, message: "Your account is currently inactive. Kindly reach out to the admin for support." }); + if (user.status !== "Active") { + return res.status(403).json({ + success: false, + message: + "Your account is currently inactive. Kindly reach out to the admin for support.", + }); } const token = jwt.sign( { id: user._id, role: user.role, email: user.email }, process.env.JWT_SECRET, - { expiresIn: '1h' } + { expiresIn: "1h" }, ); res.status(200).json({ success: true, - message: 'Login successful', + message: "Login successful", role: user.role, token, user: { @@ -51,11 +55,12 @@ export const login = async (req, res) => { email: user.email, role: user.role, status: user.status, + name: user.name, }, }); } catch (error) { - console.error('Login error:', error); - res.status(500).json({ success: false, message: 'Server error' }); + console.error("Login error:", error); + res.status(500).json({ success: false, message: "Server error" }); } }; @@ -66,7 +71,7 @@ export const sendOTP = async (req, res, next) => { if (!email) { return res.status(400).json({ success: false, - message: 'Email is required' + message: "Email is required", }); } @@ -74,9 +79,8 @@ export const sendOTP = async (req, res, next) => { res.status(200).json({ success: true, - message: 'OTP sent successfully' + message: "OTP sent successfully", }); - } catch (error) { next(error); } @@ -89,7 +93,7 @@ export const validateOTP = async (req, res, next) => { if (!email || !otp) { return res.status(400).json({ success: false, - message: 'Email and OTP are required' + message: "Email and OTP are required", }); } @@ -97,10 +101,9 @@ export const validateOTP = async (req, res, next) => { res.status(200).json({ success: true, - message: 'OTP verified successfully' + message: "OTP verified successfully", }); - } catch (error) { next(error); } -}; \ No newline at end of file +}; diff --git a/src/controllers/billing.controller.js b/src/controllers/billing.controller.js index 3bc47ec..3d55bb2 100644 --- a/src/controllers/billing.controller.js +++ b/src/controllers/billing.controller.js @@ -1,25 +1,36 @@ -import Billing from '../models/billing.js'; -import billingService from '../services/billing.service.js'; -import mongoose from 'mongoose'; -import { createOrder } from '../services/payment.service.js'; -import razorpay from '../config/razorpay.js'; -import crypto from 'crypto'; +import Billing from "../models/billing.js"; +import billingService from "../services/billing.service.js"; +import mongoose from "mongoose"; +import { createOrder } from "../services/payment.service.js"; +import razorpay from "../config/razorpay.js"; +import crypto from "crypto"; const createBilling = async (req, res, next) => { try { - const { patient, appointment, amount } = req.body; + const { patient, appointment, amount, paymentMethod, transactionId, status } = + req.body; if (!patient || !amount) { return res.status(400).json({ - success: false, - message: "Patient and amount are required", + success: false, + message: "Patient and amount are required", + }); + } + + if (!paymentMethod || !["cash", "online"].includes(paymentMethod)) { + return res.status(400).json({ + success: false, + message: "Valid payment method (cash or online) is required", }); } const billing = await Billing.create({ patient, - appointment, + appointment: appointment || undefined, amount, + paymentMethod, + status: status || "pending", + transactionId: transactionId || undefined, createdBy: req.user.id, }); @@ -40,6 +51,13 @@ const getAllBilling = async (req, res, next) => { const bills = await Billing.find() .populate("patient", "name email") + .populate({ + path: "appointment", + populate: [ + { path: "doctor", select: "name spec" }, + { path: "dept", select: "dept" }, + ], + }) .sort({ createdAt: -1 }) .skip(skip) .limit(limit); @@ -62,18 +80,20 @@ const getAllBilling = async (req, res, next) => { const getMyBills = async (req, res, next) => { try { - const patient = await mongoose.model('Patient').findOne({ email: req.user.email }); + const patient = await mongoose.model("Patient").findOne({ email: req.user.email }); if (!patient) { - return res.status(404).json({ success: false, message: "Patient record not found" }); + return res + .status(404) + .json({ success: false, message: "Patient record not found" }); } const bills = await Billing.find({ patient: patient._id }) .populate({ - path: 'appointment', + path: "appointment", populate: [ - { path: 'doctor', select: 'name' }, - { path: 'dept', select: 'dept' } - ] + { path: "doctor", select: "name" }, + { path: "dept", select: "dept" }, + ], }) .sort({ createdAt: -1 }); @@ -89,7 +109,7 @@ const getMyBills = async (req, res, next) => { const createRazorpayOrder = async (req, res, next) => { try { const { amount, billId } = req.body; - + // Check if bill exists const bill = await Billing.findById(billId); if (!bill) { @@ -103,7 +123,7 @@ const createRazorpayOrder = async (req, res, next) => { keyId: process.env.RAZORPAY_KEY_ID, orderId: order.id, amount: order.amount, - currency: order.currency + currency: order.currency, }); } catch (error) { next(error); @@ -134,13 +154,13 @@ const verifyRazorpayPayment = async (req, res, next) => { res.status(200).json({ success: true, valid: true, - message: "Payment verified successfully" + message: "Payment verified successfully", }); } else { res.status(400).json({ success: false, valid: false, - message: "Invalid signature" + message: "Invalid signature", }); } } catch (error) { @@ -223,7 +243,7 @@ const createBillingStaff = async (req, res, next) => { const billing = await billingService.createBillingStaff(req.body); res.status(201).json(billing); } catch (error) { - next(error) + next(error); } }; @@ -231,12 +251,13 @@ const changePassword = async (req, res, next) => { try { const { oldPassword, newPassword } = req.body; const result = await billingService.changePassword( - req.user.id, - oldPassword, - newPassword); + req.user.id, + oldPassword, + newPassword, + ); res.status(200).json(result); } catch (err) { - next(err) + next(err); } }; @@ -245,7 +266,7 @@ const getAllBillingStaff = async (req, res, next) => { const billing = await billingService.getAllBillingStaff(); res.json(billing); } catch (err) { - next(err) + next(err); } }; @@ -255,7 +276,7 @@ const updateBillingStaff = async (req, res, next) => { const billing = await billingService.updateBillingStaff(id, req.body); res.json(billing); } catch (err) { - next(err) + next(err); } }; @@ -265,7 +286,7 @@ const deleteBillingStaff = async (req, res, next) => { const result = await billingService.deleteBillingStaff(id); res.json(result); } catch (err) { - next(err) + next(err); } }; @@ -277,7 +298,6 @@ export { deleteBilling, // Staff CRUD for admin - createBillingStaff, changePassword, getAllBillingStaff, @@ -285,5 +305,5 @@ export { deleteBillingStaff, getMyBills, createRazorpayOrder, - verifyRazorpayPayment -} \ No newline at end of file + verifyRazorpayPayment, +}; diff --git a/src/controllers/patient.js b/src/controllers/patient.js index 7d017ca..b44bf02 100644 --- a/src/controllers/patient.js +++ b/src/controllers/patient.js @@ -37,7 +37,8 @@ const createPatient = async (req, res, next) => { if (normalizedEmail) { try { - await createPatientPortalAccount(normalizedEmail); + const patientName = req.body.name || patient.name || ""; + await createPatientPortalAccount(normalizedEmail, patient.name); } catch (portalErr) { console.error( `Patient saved but portal creation failed for ${normalizedEmail}:`, diff --git a/src/services/patientPortal.service.js b/src/services/patientPortal.service.js index d8d6d78..8405d99 100644 --- a/src/services/patientPortal.service.js +++ b/src/services/patientPortal.service.js @@ -3,7 +3,7 @@ import User from "../models/User.js"; import { generateRandomPassword } from "../utils/password.utils.js"; import { sendCredentialsEmail } from "./email.service.js"; -export const createPatientPortalAccount = async (email) => { +export const createPatientPortalAccount = async (email, name) => { const existingUser = await User.findOne({ email }); if (existingUser) { @@ -20,6 +20,7 @@ export const createPatientPortalAccount = async (email) => { role: "patient", status: "Active", mustChangePassword: true, + name: name || "", }); await user.save();