ironGym/webapp/src/app/api/user/actions/members/route.ts
2025-06-19 23:16:02 +03:00

354 lines
12 KiB
TypeScript

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"
}
})
}
}