task updated and product manual completed

This commit is contained in:
Sibunnayak 2024-08-27 13:00:55 +05:30
parent 768fc3c77f
commit 059e39e13c
9 changed files with 353 additions and 4 deletions

3
app.js
View File

@ -132,6 +132,7 @@ app.use(
//auth
import user from "./resources/user/userRoute.js";
import ProductRouter from "./resources/Products/ProductRoute.js";
import ProductManualRouter from "./resources/ProductMannual/ProductManualRoute.js";
//Businesses
// import BusinessRoute from "./resources/Businesses/BusinessRoute.js";
@ -199,6 +200,8 @@ app.use("/api/v1", user);
//Product
app.use("/api", ProductRouter);
//Product Manual
app.use("/api/productmanual", ProductManualRouter);
//businesses
// app.use("/api/businesses", BusinessRoute);
// Design

Binary file not shown.

View File

@ -0,0 +1,181 @@
import ProductManual from "./ProductManualModel.js";
import cloudinary from "../../Utils/cloudinary.js";
// Create a new product manual
export const createProductManual = async (req, res) => {
const { title } = req.body;
try {
let productManualDetails;
// Check if a file is provided
if (req.files && req.files.product_manual) {
const pdfFile = req.files.product_manual;
const result = await cloudinary.v2.uploader.upload(pdfFile.tempFilePath, {
folder: "chemiNova/ProductManuals",
resource_type: "raw", // For PDF or other non-image files
});
productManualDetails = {
public_id: result.public_id,
url: result.secure_url,
};
}
// Create the product manual
const productManual = await ProductManual.create({
title,
product_manual: productManualDetails,
});
res.status(201).json({
success: true,
productManual,
message: "Product manual created successfully",
});
} catch (error) {
console.error("Error creating product manual:", error);
res.status(500).json({
success: false,
message: error.message || "Internal server error",
});
}
};
// Get all product manuals
export const getAllProductManuals = async (req, res) => {
try {
const productManuals = await ProductManual.find();
res.status(200).json({
success: true,
productManuals,
});
} catch (error) {
console.error("Error fetching product manuals:", error);
res.status(500).json({
success: false,
message: error.message || "Internal server error",
});
}
};
// Get a single product manual by ID
export const getSingleProductManual = async (req, res) => {
const { id } = req.params;
try {
const productManual = await ProductManual.findById(id);
if (!productManual) {
return res.status(404).json({
success: false,
message: "Product manual not found",
});
}
res.status(200).json({
success: true,
productManual,
});
} catch (error) {
console.error("Error fetching product manual:", error);
res.status(500).json({
success: false,
message: error.message || "Internal server error",
});
}
};
// Update a product manual
export const updateProductManual = async (req, res) => {
const { id } = req.params;
const { title } = req.body;
try {
const productManual = await ProductManual.findById(id);
if (!productManual) {
return res.status(404).json({
success: false,
message: "Product manual not found",
});
}
// Check if a new file is provided
if (req.files && req.files.product_manual) {
// Delete the old file from Cloudinary
if (productManual.product_manual.public_id) {
await cloudinary.v2.uploader.destroy(productManual.product_manual.public_id, {
resource_type: "raw",
});
}
// Upload the new file to Cloudinary
const pdfFile = req.files.product_manual;
const result = await cloudinary.v2.uploader.upload(pdfFile.tempFilePath, {
folder: "chemiNova/ProductManuals",
resource_type: "raw",
});
// Update the product manual details
productManual.product_manual = {
public_id: result.public_id,
url: result.secure_url,
};
}
// Update the title
productManual.title = title || productManual.title;
await productManual.save();
res.status(200).json({
success: true,
productManual,
message: "Product manual updated successfully",
});
} catch (error) {
console.error("Error updating product manual:", error);
res.status(500).json({
success: false,
message: error.message || "Internal server error",
});
}
};
// Delete a product manual
export const deleteProductManual = async (req, res) => {
const { id } = req.params;
try {
const productManual = await ProductManual.findById(id);
if (!productManual) {
return res.status(404).json({
success: false,
message: "Product manual not found",
});
}
// Delete the file from Cloudinary
if (productManual.product_manual.public_id) {
await cloudinary.v2.uploader.destroy(productManual.product_manual.public_id, {
resource_type: "raw",
});
}
// Delete the product manual from the database
await ProductManual.findByIdAndDelete(id);
res.status(200).json({
success: true,
message: "Product manual deleted successfully",
});
} catch (error) {
console.error("Error deleting product manual:", error);
res.status(500).json({
success: false,
message: error.message || "Internal server error",
});
}
};

View File

@ -0,0 +1,25 @@
import mongoose from "mongoose";
const ProductManualSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
},
product_manual: {
public_id: {
type: String,
required: true,
},
url: {
type: String,
required: true,
},
},
},
{ timestamps: true }
);
const ProductManual = mongoose.model("ProductManual", ProductManualSchema);
export default ProductManual;

View File

@ -0,0 +1,90 @@
import express from "express";
import {
createProductManual,
getAllProductManuals,
getSingleProductManual,
updateProductManual,
deleteProductManual,
} from "./ProductManualController.js";
import {
isAuthenticatedUser,
authorizeRoles,
} from "../../middlewares/auth.js";
import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js";
import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js";
const router = express.Router();
// Route for creating a product manual (Only Admin can create)
router
.route("/create")
.post(isAuthenticatedUser, authorizeRoles("admin"), createProductManual);
// Route for getting all product manuals (accessible to Sales Coordinator, Territory Manager, and Admin)
router.route("/").get(
(req, res, next) => {
// Allow access if the user is a sales coordinator, territory manager, or admin
isAuthenticatedSalesCoOrdinator(req, res, (err) => {
if (err) {
isAuthenticatedTerritoryManager(req, res, (err) => {
if (err) {
isAuthenticatedUser(req, res, (err) => {
if (err || !["admin"].includes(req.user.role)) {
return res.status(403).json({
success: false,
message: "Access denied. Unauthorized role.",
});
}
next();
});
} else {
next();
}
});
} else {
next();
}
});
},
getAllProductManuals
);
// Route for getting a single product manual by ID (accessible to Sales Coordinator, Territory Manager, and Admin)
router.route("/:id").get(
(req, res, next) => {
// Allow access if the user is a sales coordinator, territory manager, or admin
isAuthenticatedSalesCoOrdinator(req, res, (err) => {
if (err) {
isAuthenticatedTerritoryManager(req, res, (err) => {
if (err) {
isAuthenticatedUser(req, res, (err) => {
if (err || !["admin"].includes(req.user.role)) {
return res.status(403).json({
success: false,
message: "Access denied. Unauthorized role.",
});
}
next();
});
} else {
next();
}
});
} else {
next();
}
});
},
getSingleProductManual
);
// Route to update a product manual by ID
router
.route("/update/:id")
.put(isAuthenticatedUser, authorizeRoles("admin"), updateProductManual);
// Route to delete a product manual by ID
router
.route("/delete/:id")
.delete(isAuthenticatedUser, authorizeRoles("admin"), deleteProductManual);
export default router;
// /api/productmanual

View File

@ -12,6 +12,7 @@ export const assignTask = async (req, res) => {
taskAssignedTo,
addedFor,
addedForId,
tradename,
} = req.body;
const currentYear = new Date().getFullYear().toString().slice(-2);
@ -29,6 +30,7 @@ export const assignTask = async (req, res) => {
taskAssignedBy: req.user._id,
addedFor,
addedForId,
tradename,
});
res.status(201).json({
@ -73,8 +75,33 @@ export const getTasksByStatus = async (req, res) => {
});
}
};
export const getTasksbytask = async (req, res) => {
try {
const { task } = req.params;
// Validate the provided status
if (!["Visit RD/PD", "Update Sales Data", "Update Inventory Data", "Collect KYC"].includes(task)) {
return res.status(400).json({
success: false,
message: "Invalid task type provided.",
});
}
const tasks = await Task.find({
taskAssignedTo: req.user._id,
task: task,
}).sort({ createdAt: -1 });
res.status(200).json({
success: true,
tasks,
});
} catch (error) {
res.status(500).json({
success: false,
message: error.message,
});
}
};
export const updateTaskStatus = async (req, res) => {
try {
const { taskId } = req.params;

View File

@ -12,12 +12,12 @@ const TaskSchema = new mongoose.Schema(
task: {
type: String,
required: true,
enum: ["Visit Retailers", "Update Sales Data", "Update Inventory Data", "Collect KYC"],
enum: ["Visit RD/PD", "Update Sales Data", "Update Inventory Data", "Collect KYC"],
},
note: {
type: String,
required: function () {
return this.task === "Collect KYC";
return this.task === "Collect KYC" || this.task === "Visit RD/PD";
},
},
taskStatus: {
@ -60,6 +60,12 @@ const TaskSchema = new mongoose.Schema(
return this.task === "Update Inventory Data";
},
},
tradename: {
type: String,
required: function () {
return this.task === "Update Inventory Data";
},
},
},
{ timestamps: true }
);

View File

@ -3,6 +3,7 @@ import {
assignTask,
getTasksByStatus,
updateTaskStatus,
getTasksbytask,
} from "./TaskController.js";
import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js";
import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js";
@ -22,7 +23,11 @@ router.get(
isAuthenticatedSalesCoOrdinator,
getTasksByStatus
);
router.get(
"/task/type/:task",
isAuthenticatedSalesCoOrdinator,
getTasksbytask
);
// Route to update task status
router.put(
"/update-task-status/:taskId",

View File

@ -563,7 +563,19 @@ export const uploadPrincipaldistributors = async (req, res) => {
uniqueId: item.uniqueId,
});
await distributor.save();
await sendEmail({
to: distributor.email,
from: process.env.SEND_EMAIL_FROM,
subject: `Cheminova Account Created`,
html: `
Your Principal Distributor Account is created successfully.
<br/>Name: <strong>${distributor.name}</strong><br/>
<br/>Mobile Number: <strong>${distributor.phone}</strong><br/>
<br/>Password: <strong>${password}</strong><br/><br/>
<a href="${process.env.PD_APP_URL}/login">Click here to login</a><br/><br/>
If you have not requested this email, please ignore it.
`,
});
// Now create the address for the new user
const addressData = {
street: item.street,