From f56997970f5108674284b9502ef5f70c459645e5 Mon Sep 17 00:00:00 2001 From: ShivaniYadav07 Date: Sat, 23 Nov 2024 22:34:11 +0530 Subject: [PATCH 1/2] refactor chapter&topicnumber --- controller/chapterController.js | 68 +++++++++++++++++++++------------ controller/topicController.js | 52 ++++++++++++------------- model/chapterModel.js | 4 ++ model/topicModel.js | 4 ++ 4 files changed, 78 insertions(+), 50 deletions(-) diff --git a/controller/chapterController.js b/controller/chapterController.js index c5b9c7b..23c603d 100644 --- a/controller/chapterController.js +++ b/controller/chapterController.js @@ -15,46 +15,66 @@ export const createChapter = async (req, res) => { return res.status(400).json({ success: false, message: 'Subject name and chapters (array) must be provided.' }); } - const existingSubject = await Subject.findOne({ name, standard }).populate('chapters'); // Ensure to populate the chapters + const existingSubject = await Subject.findOne({ name, standard }); - if (existingSubject) { - for (const chapterData of chapters) { - const { name: chapterName, topics } = chapterData; + if (!existingSubject) { + return res.status(404).json({ success: false, message: 'Subject not found.' }); + } - const existingChapter = existingSubject.chapters.find( - chapter => chapter.name === chapterName - ); + for (const chapterData of chapters) { + const { name: chapterName, chapterNumber, topics } = chapterData; - if (existingChapter) { - return res.status(400).json({ success: false, message: `Chapter "${chapterName}" already exists.` }); - } + const existingChapterByName = await Chapter.findOne({ + name: chapterName, + standard, + subjectName: name, + }); - const newChapter = new Chapter({ name: chapterName, subjectName: name, standard }); + if (existingChapterByName) { + return res.status(400).json({ success: false, message: `Chapter with name "${chapterName}" already exists.` }); + } - if (Array.isArray(topics)) { - for (const topicName of topics) { - const newTopic = new Topic({ name: topicName, subjectName: name, chapterName, standard }); - await newTopic.save(); - newChapter.topics.push(newTopic._id); - } - } + const existingChapterByNumber = await Chapter.findOne({ + chapterNumber, + standard, + subjectName: name, + }); - await newChapter.save(); - existingSubject.chapters.push(newChapter._id); + if (existingChapterByNumber) { + return res.status(400).json({ success: false, message: `Chapter number "${chapterNumber}" already exists.` }); } - await existingSubject.save(); + const newChapter = new Chapter({ + name: chapterName, + subjectName: name, + standard, + chapterNumber, + }); - return res.status(201).json({ success: true, message: 'Chapters added successfully.', chapters }); - } else { - return res.status(404).json({ success: false, message: 'Subject not found.' }); + if (Array.isArray(topics)) { + for (const topicName of topics) { + const newTopic = new Topic({ name: topicName, subjectName: name, chapterName, standard }); + await newTopic.save(); + newChapter.topics.push(newTopic._id); + } + } + + await newChapter.save(); + existingSubject.chapters.push(newChapter._id); } + + await existingSubject.save(); + + return res.status(201).json({ success: true, message: 'Chapters added successfully.' }); } catch (error) { console.error('Error creating chapter:', error); res.status(500).json({ success: false, message: error.message || 'Internal Server Error' }); } }; + + + export const getChapter = async (req, res) => { try { const subjectName = (req.query.subjectName || req.body.subjectName || '').trim(); diff --git a/controller/topicController.js b/controller/topicController.js index 7a96e03..0c2fbc3 100644 --- a/controller/topicController.js +++ b/controller/topicController.js @@ -7,38 +7,38 @@ import {Subtopic} from "../model/subtopicModel.js" export const createTopic = async (req, res) => { try { - const { subjectName, standard, chapterName, chapterId, topics } = req.body; + const { subjectName, standard, chapterName, topics } = req.body; - // Validate that required fields are provided - if (!subjectName || !chapterName || !chapterId || !Array.isArray(topics) || topics.length === 0) { + if (!subjectName || !chapterName || !Array.isArray(topics) || topics.length === 0) { return res.status(400).json({ success: false, - message: 'Subject name, chapter name, chapterId, and topics (array) must be provided' + message: 'Subject name, chapter name, and topics (array) must be provided' }); } - // Fetch the existing subject with populated chapters and topics const existingSubject = await Subject.findOne({ name: subjectName, standard }) - .populate({ - path: 'chapters', - populate: { path: 'topics' } - }); + .populate('chapters'); if (!existingSubject) { return res.status(404).json({ success: false, message: 'Subject not found' }); } - // Find the specific chapter by name or ID - const existingChapter = existingSubject.chapters.find(chapter => chapter._id.toString() === chapterId); + const existingChapter = existingSubject.chapters.find(chapter => chapter.name === chapterName); if (!existingChapter) { return res.status(404).json({ success: false, message: 'Chapter not found' }); } - // Set of existing topic names to prevent duplicates - const existingTopicNames = new Set(existingChapter.topics.map(topic => topic.name)); + const chapterId = existingChapter._id; + + const existingTopics = await Topic.find({ + chapterId, + subjectName, + standard + }, 'topicNumber'); + + const existingTopicNumbers = new Set(existingTopics.map(topic => topic.topicNumber)); - // Validate and add new topics const newTopics = []; for (const topic of topics) { if (!topic.name || typeof topic.name !== 'string') { @@ -47,33 +47,29 @@ export const createTopic = async (req, res) => { const topicName = topic.name.trim(); - // Check for duplicate topic names in the same chapter - if (existingTopicNames.has(topicName)) { - return res.status(400).json({ success: false, message: `Topic "${topicName}" already exists in the chapter` }); + const topicNumber = topic.topicNumber || Math.max(0, ...Array.from(existingTopicNumbers)) + 1; + if (existingTopicNumbers.has(topicNumber)) { + return res.status(400).json({ success: false, message: `Topic number "${topicNumber}" already exists in the chapter "${chapterName}" for subject "${subjectName}" and standard "${standard}".` }); } - // Create and save new topic const newTopic = new Topic({ name: topicName, chapterName, - chapterId, subjectName, - standard + standard, + chapterId, + topicNumber: topicNumber }); await newTopic.save(); - // Add new topic ID to chapter - existingChapter.topics.push(newTopic._id); + existingTopicNumbers.add(topicNumber); newTopics.push(newTopic); } - // Save the updated chapter with new topics - await existingChapter.save(); - res.status(200).json({ success: true, - message: 'Topics created and added to chapter successfully', + message: 'Topics created successfully', newTopics }); @@ -85,6 +81,10 @@ export const createTopic = async (req, res) => { + + + + export const editTopic = async (req, res) => { try { const { id } = req.params; diff --git a/model/chapterModel.js b/model/chapterModel.js index 23b0913..f753ac7 100644 --- a/model/chapterModel.js +++ b/model/chapterModel.js @@ -8,6 +8,10 @@ const chapterSchema = new mongoose.Schema({ subjectName: { type: String, required: true, + }, + chapterNumber: { + type: Number, + default: undefined, }, standard: { type: Number, diff --git a/model/topicModel.js b/model/topicModel.js index 6a9f786..5fc9d43 100644 --- a/model/topicModel.js +++ b/model/topicModel.js @@ -10,6 +10,10 @@ const topicSchema = new mongoose.Schema({ type: String, required: true, }, + topicNumber: { + type: Number, + default: undefined, + }, chapterId: { type: mongoose.Schema.Types.ObjectId, ref: "Chapter", From c4c632f739d331fda9009be92954732a5d898fb2 Mon Sep 17 00:00:00 2001 From: ShivaniYadav07 Date: Mon, 25 Nov 2024 12:07:08 +0530 Subject: [PATCH 2/2] added numbers to updatetopic and updatechapter --- controller/chapterController.js | 75 +++++++++++++++++++++++---------- controller/topicController.js | 55 ++++++++++++------------ 2 files changed, 78 insertions(+), 52 deletions(-) diff --git a/controller/chapterController.js b/controller/chapterController.js index 23c603d..e572beb 100644 --- a/controller/chapterController.js +++ b/controller/chapterController.js @@ -270,53 +270,82 @@ export const updateChapterExamTags = async (req, res) => { export const updateChapter = async (req, res) => { try { const { id } = req.params; - const { name } = req.body; + const { name, chapterNumber } = req.body; - if (!id || !name) { - return res.status(400).json({ success: false, message: 'Chapter ID and new name must be provided' }); + if (!id || !name || chapterNumber === undefined) { + return res.status(400).json({ + success: false, + message: 'Chapter ID, new name, and chapter number must be provided.' + }); } const chapter = await Chapter.findById(id); if (!chapter) { - return res.status(404).json({ success: false, message: 'Chapter not found' }); + return res.status(404).json({ success: false, message: 'Chapter not found.' }); + } + + const { subjectName, standard } = chapter; // Use current chapter's subject and standard for validation + + // Check for duplicate chapter name in the same subject and standard + const existingChapterByName = await Chapter.findOne({ + name, + standard, + subjectName, + _id: { $ne: id }, // Exclude the current chapter from the check + }); + + if (existingChapterByName) { + return res.status(400).json({ success: false, message: `Chapter with name "${name}" already exists.` }); } + // Check for duplicate chapter number in the same subject and standard + const existingChapterByNumber = await Chapter.findOne({ + chapterNumber, + standard, + subjectName, + _id: { $ne: id }, // Exclude the current chapter from the check + }); + + if (existingChapterByNumber) { + return res.status(400).json({ success: false, message: `Chapter number "${chapterNumber}" already exists.` }); + } + + // Update Chapter details const oldName = chapter.name; chapter.name = name; + chapter.chapterNumber = chapterNumber; await chapter.save(); - // Update the chapter ID in the Subject collection where the chapter ID matches - await Subject.updateOne( - { chapters: id }, - { $set: { "chapters.$": id } } - ); - - await Ques.updateMany( - { chapter: oldName }, - { $set: { "chapter.$[elem]": name } }, - { arrayFilters: [{ "elem": oldName }] } - ); - // Update chapter name in the Topic collection + // Update related collections await Topic.updateMany( - { chapterName: oldName,}, - { $set: { chapterName: name } } + { chapterName: oldName, subjectName, standard }, + { $set: { chapterName: name, chapterNumber } } ); - // Update chapter name in the Subtopic collection await Subtopic.updateMany( - { chapterName: oldName, }, - { $set: { chapterName: name } } + { chapterName: oldName, subjectName, standard }, + { $set: { chapterName: name, chapterNumber } } ); - return res.status(200).json({ success: true, message: 'Chapter name updated successfully in all relevant collections' }); + return res.status(200).json({ + success: true, + message: 'Chapter name and chapter number updated successfully in all relevant collections.', + }); } catch (error) { console.error('Error in updateChapter:', error); - return res.status(500).json({ success: false, message: 'An unexpected error occurred. Please try again later.' }); + return res.status(500).json({ + success: false, + message: error.message || 'An unexpected error occurred. Please try again later.', + }); } }; + + + + export const deleteChapter = async (req, res) => { try { const { id } = req.params; diff --git a/controller/topicController.js b/controller/topicController.js index 0c2fbc3..49bf599 100644 --- a/controller/topicController.js +++ b/controller/topicController.js @@ -80,11 +80,6 @@ export const createTopic = async (req, res) => { }; - - - - - export const editTopic = async (req, res) => { try { const { id } = req.params; @@ -271,59 +266,61 @@ export const updateTopicExamTags = async (req, res) => { export const updateTopic = async (req, res) => { try { const { id } = req.params; - const { name } = req.body; + const { name, topicNumber } = req.body; if (!id || !name) { - return res.status(400).json({ success: false, message: 'Topic ID and new name must be provided' }); + return res.status(400).json({ success: false, message: 'Topic ID and name must be provided' }); } const topic = await Topic.findById(id); - if (!topic) { return res.status(404).json({ success: false, message: 'Topic not found' }); } - // Find the chapter associated with the topic by name and subjectName const existingChapter = await Chapter.findOne({ name: topic.chapterName, subjectName: topic.subjectName, + standard: topic.standard, }).populate('topics'); - // Check if the chapter exists if (!existingChapter) { return res.status(404).json({ success: false, message: 'Chapter not found' }); } - // Check if the new name already exists in the same chapter - const topicExists = existingChapter.topics.some(t => t.name === name && t._id.toString() !== id); + const existingTopics = await Topic.find( + { + chapterId: existingChapter._id, + standard: topic.standard, + subjectName: topic.subjectName, + }, + 'topicNumber' + ); - if (topicExists) { - return res.status(400).json({ success: false, message: `Topic name "${name}" already exists in the chapter` }); - } + const existingTopicNumbers = new Set(existingTopics.map(t => t.topicNumber)); - const oldName = topic.name; - topic.name = name; - await topic.save(); + const newTopicNumber = topicNumber !== undefined ? topicNumber : topic.topicNumber; - // Update the name in Ques and Subtopic collections - await Ques.updateMany( - { topics: oldName }, - { $set: { "topics.$": name } } - ); + if (existingTopicNumbers.has(newTopicNumber) && newTopicNumber !== topic.topicNumber) { + return res.status(400).json({ + success: false, + message: `Topic number "${newTopicNumber}" already exists in the chapter "${topic.chapterName}" for subject "${topic.subjectName}" and standard "${topic.standard}".`, + }); + } - await Subtopic.updateMany( - { topicName: oldName }, - { $set: { topicName: name } } - ); + // Update topic details + topic.name = name.trim(); + topic.topicNumber = newTopicNumber; + await topic.save(); - return res.status(200).json({ success: true, message: 'Topic name updated successfully across all related collections' }); + res.status(200).json({ success: true, message: 'Topic updated successfully', topic }); } catch (error) { console.error('Error in updateTopic:', error); - return res.status(500).json({ success: false, message: 'An unexpected error occurred. Please try again later.' }); + res.status(500).json({ success: false, message: error.message || 'Internal Server Error' }); } }; + export const deleteTopicnullquestion = async (req, res) => { try { const { id } = req.params;