import dbConnect from "@/database/dbConnect"; import { NextResponse } from "next/server"; import memberModel from "@/database/models/memberModel"; import serviceModel from "@/database/models/serviceModel"; import mongoose from 'mongoose' import statisticsModel from "@/database/models/statisticsModel"; import incomeModel from "@/database/models/incomeModel"; // POST METHOD export async function POST(req:Request) { try{ // connect to the db dbConnect(); // get the request payload const { payload } = await req.json(); // declare the needed variables const firstName : string | null = payload.firstName as string | null, lastName : string | null = payload.lastName as string | null, email : string | null = payload.email as string | null, phone : string | null = payload.phone as string | null, address : string | null = payload.address as string | null, services : [string] | [] = payload.services as [string] | [], planDelay : number = payload.planDelay ? payload.planDelay : 1 as number, gendre : string | null = payload.gendre as string | null, bodyState : { startBodyForm: String, startWeight: Number, } | null = payload.bodyState as { startBodyForm: String, startWeight: Number, } | null; // calculat month pay const ids = services?.map((v , i) => { return new mongoose.Types.ObjectId(v as any) }) const servicesDocs = await serviceModel.aggregate([ { $match: { _id: { $in : ids } } }, { $group: { _id: null, totalPrice: { $sum: "$price" } } } ]) // inc the value of totalSubscribers for all included services in the membership await serviceModel.updateMany({_id : {$in : ids}} , { $inc: { totalSubscribers: 1 } }) const payMonth : number = servicesDocs[0] ? servicesDocs[0].totalPrice : 0 // declare needed variables let current_date = new Date(), current_date_unix = Math.floor(Date.now() / 1000), planDelay_unix = planDelay ? planDelay * 2592000: 0 * 2592000, planExpAt = new Date((current_date_unix + planDelay_unix) * 1000); // save the doc const doc = new memberModel({ firstName, lastName, email, phone, address, payMonth, services, gendre, bodyState, registerAt: current_date.toUTCString(), registerAt_unix: current_date_unix, planUpdatedAt: current_date.toUTCString(), planUpdatedAt_unix: current_date_unix, planDelay, planDelay_unix: planDelay_unix, planExpAt: planExpAt.toUTCString(), planExpAt_unix: current_date_unix + planDelay_unix, active: true, }) await doc.save() // return the success response with the new added doc return NextResponse.json({ success: true, message: "requestTerminatedWithSuccess", data: doc, }, { status: 200, headers: { "content-type": "application/json" } }) }catch(e) { // catch any error and return an error response return NextResponse.json({ success: false, message: "serverError", }, { status: 500, headers: { "content-type": "application/json" } }) } } // set the revalidate variable export const revalidate = 5; // GET METHOD export async function GET(req:Request) { try{ // connect to the db dbConnect(); // get the parms const { searchParams } = new URL(req.url) const type = searchParams.get('type') // if get by page if(type=='page') { // get the page const page : string | null = searchParams.get('page') ? searchParams.get('page') : '0', range : number[] = [(parseInt(page?page : '0') - 1) * 4 , 4]; // get the docs const docs = await memberModel.find({}).skip(range[0]).limit(range[1]), // get the size of the docs docs_count = await memberModel.countDocuments({}); // prepare the return data return NextResponse.json({ success: true, message: "docsGetedSuccessfully", data: { docs, docs_count, } }) } // if type is search else if(type == 'search') { // get the searchKeyword param let searchKeyword = searchParams.get('searchKeyword') // get the search results docs let results = await memberModel.find({ $or: [ // search by ( case insensitive search ) { firstName: { $regex: searchKeyword, $options: 'i' } }, { lastName: { $regex: searchKeyword, $options: 'i' } }, { email: { $regex: searchKeyword, $options: 'i' } }, { phone: { $regex: searchKeyword, $options: 'i' } }, ] }) // get the docs let responseData = { docs: results, docs_count : results.length, } // return the response return NextResponse.json({ success: true, message: "docsGetedSuccessfully", data: responseData ? responseData : [], } , { status: 200, }) } }catch(e) { // catch any error and return an error response return NextResponse.json({ success: false, message: "serverError", }, { status: 500, headers: { "content-type": "application/json" } }) } } // DELETE METHOD export async function DELETE(req:Request) { try{ // connect to the db dbConnect(); // get the parms const { searchParams } = new URL(req.url) const page = searchParams.get('page'), _id : string | null = searchParams.get('_id'), range : number[] = [(parseInt(page?page : '0') - 1) * 4 , 4]; // delete the doc await memberModel.findByIdAndRemove(_id) // get the docs by page const docs = await memberModel.find({}).skip(range[0]).limit(range[1]), // get the size of the docs docs_count = await memberModel.countDocuments({}); // prepare the return data return NextResponse.json({ success: true, message: "docsGetedSuccessfully", data: { docs, docs_count, } }) }catch(e) { // catch any error and return an error response return NextResponse.json({ success: false, message: "serverError", }, { status: 500, headers: { "content-type": "application/json" } }) } } // PUT METHOD export async function PUT(req:Request) { try{ // connect to the db dbConnect(); // get the request payload const { args , payload } = await req.json(); // check the type const type : "personal" | "subscription" | null = args.type as "personal" | "subscription" | null; if(type == "personal") { // declare the needed variables const _id : string | null = payload._id as string | null, firstName : string | null = payload.firstName as string | null, lastName : string | null = payload.lastName as string | null, email : string | null = payload.email as string | null, phone : string | null = payload.phone as string | null, address : string | null = payload.address as string | null, active : boolean | null = payload.active as boolean | null; // save the doc const doc = await memberModel.findByIdAndUpdate( _id , { firstName, lastName, email, phone, address, active, } , { new: true }) // return the success response return NextResponse.json({ success: true, message: "requestTerminatedWithSuccess", data: doc, }, { status: 200, headers: { "content-type": "application/json" } }) } else if(type == "subscription") { // declare the needed variables const _id : string | null = payload._id as string | null, services : [string] | [] = payload.services as [string] | [], planDelay : number = payload.planDelay ? payload.planDelay : 1 as number, bodyState : { currentBodyForm: String, currentWeight: Number, } | null = payload.bodyState as { currentBodyForm: String, currentWeight: Number, } | null; // calculat month pay const ids = services?.map((v , i) => { return new mongoose.Types.ObjectId(v as string) }) const servicesDocs = await serviceModel.aggregate([ { $match: { _id: { $in : ids } } }, { $group: { _id: null, totalPrice: { $sum: "$price" } } } ]) const payMonth : number = servicesDocs[0] ? servicesDocs[0].totalPrice : 0 // declare needed variables let current_date = new Date(), current_date_unix = Math.floor(Date.now() / 1000), planDelay_unix = planDelay ? planDelay * 2592000: 0 * 2592000, planExpAt = new Date((current_date_unix + planDelay_unix) * 1000); // save the doc const doc = await memberModel.findByIdAndUpdate( _id , { bodyState, services, payMonth, planUpdatedAt: current_date.toUTCString(), planUpdatedAt_unix: current_date_unix, planDelay, planDelay_unix: planDelay_unix, planExpAt: planExpAt.toUTCString(), planExpAt_unix: current_date_unix + planDelay_unix, active: true, } , { new: true }) // add the subscription income let income = payMonth * planDelay await statisticsModel.findOneAndUpdate({} , { $inc: { totalIncome: income } }) // return the success response return NextResponse.json({ success: true, message: "requestTerminatedWithSuccess", data: doc, }, { status: 200, headers: { "content-type": "application/json" } }) } }catch(e) { // catch any error and return an error response return NextResponse.json({ success: false, message: "serverError", }, { status: 500, headers: { "content-type": "application/json" } }) } }