Affiliate API and Coupon API

This commit is contained in:
Raj-varu 2024-03-12 13:53:24 +05:30
parent 468238a28f
commit f85a516808
6 changed files with 954 additions and 3 deletions

12
app.js
View File

@ -157,8 +157,12 @@ import SpecialtiesRouter from "./resources/Specialties/SpecialtiesRoute.js";
import ShippingAddressRoute from "./resources/ShippingAddresses/ShippingAddressRoute.js"; import ShippingAddressRoute from "./resources/ShippingAddresses/ShippingAddressRoute.js";
import stripeRoute from "./resources/StripePayment/stripeRoute.js"; import stripeRoute from "./resources/StripePayment/stripeRoute.js";
import SeoRoute from "./resources/SEO&Analytics/SEORouter.js" import SeoRoute from "./resources/SEO&Analytics/SEORouter.js";
//Affiliate Routes
import AffiliateRoute from "./resources/Affiliate&Coupon/Affiliate/AffiliateRoute.js";
//Coupon Routes
import CouponRoute from "./resources/Affiliate&Coupon/Coupon/CouponRoute.js";
//short urls //short urls
// import ShortUrlRouter from "./resources/Businesses/Short_Urls/ShortUrlRoute.js"; // import ShortUrlRouter from "./resources/Businesses/Short_Urls/ShortUrlRoute.js";
@ -207,6 +211,12 @@ app.use("/api/config", ConfigRouter);
app.use("/api/stripe", stripeRoute); app.use("/api/stripe", stripeRoute);
app.use("/api/seo", SeoRoute); app.use("/api/seo", SeoRoute);
//Affiliates
app.use("/api/v1/affiliate", AffiliateRoute);
//Coupons
app.use("/api/v1/coupon", CouponRoute);
//config specialty //config specialty
// app.use("/api/config/specialty", SpecialtiesRouter); // app.use("/api/config/specialty", SpecialtiesRouter);
//specialties //specialties

View File

@ -0,0 +1,291 @@
import { AffiliateModel } from "./AffiliateModel.js";
// -----------------------------AFFILIATE & COUPONS ARE HARDLY BINDED DATA--------------------------------------------------------
//Create Affiliate
export const createAffiliate = async (req, res) => {
try {
const result = req.body;
const affiliate = new AffiliateModel(result);
const savedData = await affiliate.save();
if (savedData) {
return res
.status(201)
.json({ success: true, message: "Affiliate Added" });
}
} catch (error) {
res.status(500).json({
success: false,
message: error.message
.split(":")
.splice(1)
.join(":")
.trim()
.split(":")
.splice(1)
.join(":")
.trim(),
});
}
};
//EDIT
export const editAffiliate = async (req, res) => {
const updateFields = {};
const {
name,
mobile,
email,
country,
state,
city,
address,
pincode,
nameAsBank,
accountNo,
ifsc,
bankName,
branchName,
} = req.body;
// Add only the fields that are present in the request body to the updateFields object
if (name) updateFields.name = name;
if (mobile) updateFields.mobile = mobile;
if (email) updateFields.email = email;
if (country) updateFields.country = country;
if (state) {
updateFields.state = state;
} else {
updateFields.state = "";
}
if (city) {
updateFields.city = city;
} else {
updateFields.city = "";
}
if (address) updateFields.address = address;
if (pincode) updateFields.pincode = pincode;
if (nameAsBank) updateFields.nameAsBank = nameAsBank;
if (accountNo) updateFields.accountNo = accountNo;
if (ifsc) updateFields.ifsc = ifsc;
if (bankName) updateFields.bankName = bankName;
if (branchName) updateFields.branchName = branchName;
try {
const saveData = await AffiliateModel.findByIdAndUpdate(
{ _id: req.params.id },
{ $set: updateFields },
{ new: true }
);
res.json({
success: true,
message: "Affiliate Updated Succesfully",
});
} catch (error) {
res.status(400).json({
success: false,
message: "Error in Updation",
});
}
};
//DELETE
export const deleteAffiliate = async (req, res) => {};
//PAY AFFILIATE TODO
export const payAffiliate = async (req, res) => {
// console.log(req.body);
const { noOfCoupons, amountToPay, amount, transecId, date, time } = req.body;
if (
!req.params.id ||
!noOfCoupons ||
!amountToPay ||
!amount ||
!transecId ||
!date ||
!time
) {
return res.status(400).json({
success: false,
message: "Error in Payment",
});
}
try {
const affiliate = await AffiliateModel.findById(req.params.id);
//Checking if it's valid data from the client
if (
amountToPay != affiliate.total_earning - affiliate.paid_amount ||
noOfCoupons != affiliate.coupon_claimed - affiliate.no_of_paid_coupon
) {
return res.status(400).json({
success: false,
message: "Data invalid",
});
}
// Construct the update operation
const updateOperation = {
$push: {
affiliate_pay_history: {
amount: amountToPay,
transecId: transecId,
date: date,
time: time,
},
},
$inc: {
paid_amount: amountToPay,
no_of_paid_coupon: noOfCoupons,
},
};
// Execute the update operation
const updatedAffiliate = await AffiliateModel.findByIdAndUpdate(
req.params.id,
updateOperation,
{ new: true }
);
return res.json({
success: true,
message: "Payment Done Successfully",
updatedAffiliate: { updatedAffiliate },
});
} catch (error) {
console.error(error);
return res.status(400).json({
success: false,
message: "Error in Payment",
});
}
};
//GET ONE AFFLILIATE
export const getOneAffiliate = async (req, res) => {
if (req.params?.id) {
try {
const saveData = await AffiliateModel.findById(req.params.id);
const resObj = {
name: saveData.name,
mobile: saveData.mobile,
email: saveData.email,
country: saveData.country,
state: saveData.state,
city: saveData.city,
address: saveData.address,
pincode: saveData.pincode,
nameAsBank: saveData.nameAsBank,
accountNo: saveData.accountNo,
ifsc: saveData.ifsc,
bankName: saveData.bankName,
branchName: saveData.branchName,
};
res.status(200).json({
success: true,
message: resObj,
});
} catch (error) {
res.status(400).json({
success: false,
message: "Error in getting Affiliates",
});
}
}
};
//LIST ALL AFFILIATE
export const listAllAffiliate = async (req, res) => {
try {
const affiliate = await AffiliateModel.find(
{},
{
name: 1,
_id: 1,
coupon_claimed: 1,
coupon_code: 1,
total_earning: 1,
paid_amount: 1,
is_affiliate_active: 1,
}
).sort({ createdAt: -1 });
res.status(200).json({
success: true,
message: affiliate,
});
} catch (error) {
res.status(500).json({
success: false,
messgae: error.message ? error.message : "Something went wrong!",
});
}
};
//Activate & Deactivate Affiliates
export const suspendAffiliate = async (req, res) => {
const { id, is_affiliate_active } = req.body;
try {
const saveData = await AffiliateModel.findByIdAndUpdate(id, {
is_affiliate_active: is_affiliate_active,
});
res.status(200).json({
success: true,
message: "Success",
});
} catch (error) {
res.status(400).json({
success: false,
message: "Affiliate Doesn't Exists",
});
}
};
//Get Affiliate data for payment
export const getOneAffiliateForPay = async (req, res) => {
if (req.params?.id) {
try {
const saveData = await AffiliateModel.findById(req.params.id);
const resObj = {
name: saveData.name,
coupon_claimed: saveData.coupon_claimed,
total_earning: saveData.total_earning,
paid_amount: saveData.paid_amount,
no_of_paid_coupon: saveData.no_of_paid_coupon,
affiliate_discount_amount: saveData.affiliate_discount_amount,
coupon_code: saveData.coupon_code,
nameAsBank: saveData.nameAsBank,
accountNo: saveData.accountNo,
ifsc: saveData.ifsc,
bankName: saveData.bankName,
branchName: saveData.branchName,
};
res.status(200).json({
success: true,
message: resObj,
});
} catch (error) {
res.status(400).json({
success: false,
message: "Error in getting Affiliates",
});
}
}
};
//Get Affiliate data for History
export const affiliatePayHistory = async (req, res) => {
if (req.params?.id) {
try {
const saveData = await AffiliateModel.findById(req.params.id).sort({
updatedAt: -1,
});
const resObj = {
affiliate_pay_history: saveData.affiliate_pay_history,
name: saveData.name,
};
res.status(200).json({
success: true,
message: resObj,
});
} catch (error) {
res.status(400).json({
success: false,
message: "Error in getting History",
});
}
}
};

View File

@ -0,0 +1,122 @@
import mongoose from "mongoose";
const { Schema, model } = mongoose;
const couponUsedSchema = new Schema({
userId: { type: String, required: true },
orderId: { type: String, required: true },
couponCode: { type: String, required: true },
date: { type: String, required: true },
});
const affilitePaySchema = new Schema({
amount: { type: Number, required: true },
transecId: { type: String, required: true },
date: { type: String, required: true },
time: { type: String, required: true },
});
const affiliateSchema = new Schema(
{
name: {
type: String,
maxLength: [25, "name cannot exceed 25 characters"],
required: [true, "Please Enter Name"],
},
mobile: {
type: Number,
maxLength: [10, "Mobile cannot exceed 10 characters"],
minlength: [10, "Invalid Mobile Number"],
required: [true, "Please Enter Mobile Number"],
unique: true,
},
email: {
type: String,
required: [true, "Please Enter Email"],
unique: true,
},
country: {
type: String,
required: [true, "Please Enter Country"],
},
state: {
type: String,
},
city: {
type: String,
},
address: {
type: String,
required: [true, "Please Enter Address"],
},
pincode: {
type: Number,
required: [true, "Please Enter Pincode"],
},
nameAsBank: {
type: String,
required: [true, "Please Enter Name as Bank"],
},
accountNo: {
type: Number,
required: [true, "Please Enter Account Number"],
unique: true,
},
ifsc: {
type: String,
required: [true, "Please Enter IFSC code"],
},
bankName: {
type: String,
required: [true, "Please Enter Bank Name"],
},
branchName: {
type: String,
required: [true, "Please Enter Branch Name"],
},
coupon_code: {
type: String,
unique: [true, "Coupon Alerady Exists"],
sparse: true,
},
discount_amount: {
type: Number,
},
affiliate_discount_amount: {
type: Number,
},
valid_till: {
type: String,
},
createdAt: {
type: String,
},
coupon_claimed: {
type: Number,
default: 0,
},
total_earning: {
type: Number,
default: 0,
},
paid_amount: {
type: Number,
default: 0,
},
no_of_paid_coupon: {
type: Number,
default: 0,
},
is_affiliate_active: {
type: Boolean,
default: true,
},
is_coupon_active: {
type: Boolean,
default: false,
},
coupon_used_history: [couponUsedSchema],
affiliate_pay_history: [affilitePaySchema],
},
{ timestamps: true }
);
export const AffiliateModel = model("Affiliate", affiliateSchema);

View File

@ -0,0 +1,69 @@
import express from "express";
import {
affiliatePayHistory,
createAffiliate,
editAffiliate,
getOneAffiliate,
getOneAffiliateForPay,
listAllAffiliate,
payAffiliate,
suspendAffiliate,
} from "./AffiliateController.js";
import {
isAuthenticatedUser,
authorizeRoles,
} from "../../../middlewares/auth.js";
const router = express.Router();
router.post(
"/create",
isAuthenticatedUser,
authorizeRoles("admin"),
createAffiliate
);
router.get(
"/getall",
isAuthenticatedUser,
authorizeRoles("admin"),
listAllAffiliate
);
router.get(
"/getone/:id",
isAuthenticatedUser,
authorizeRoles("admin"),
getOneAffiliate
);
router.patch(
"/edit/:id",
isAuthenticatedUser,
authorizeRoles("admin"),
editAffiliate
);
router.patch(
"/suspend",
isAuthenticatedUser,
authorizeRoles("admin"),
suspendAffiliate
);
router.post(
"/pay/:id",
isAuthenticatedUser,
authorizeRoles("admin"),
payAffiliate
);
router.get(
"/getpay/:id",
isAuthenticatedUser,
authorizeRoles("admin"),
getOneAffiliateForPay
);
router.get(
"/history/:id",
isAuthenticatedUser,
authorizeRoles("admin"),
affiliatePayHistory
);
export default router;

View File

@ -0,0 +1,383 @@
import { AffiliateModel } from "../Affiliate/AffiliateModel.js"; //Note AffiliteModel is binded with coupons
//GET ALL Coupons
export const listAllCoupon = async (req, res) => {
try {
const coupon = await AffiliateModel.find(
{},
{
name: 1,
_id: 1,
coupon_code: 1,
discount_amount: 1,
affiliate_discount_amount: 1,
is_coupon_active: 1,
}
).sort({ createdAt: -1 });
const filteredCoupons = coupon.filter(
(data) => !(data.coupon_code == null)
);
// console.log(filteredCoupons);
// console.log(coupon);
res.status(200).json({
success: true,
message: filteredCoupons,
});
} catch (error) {
res.status(500).json({
success: false,
message: error.message ? error.message : "Something went wrong!",
});
}
};
//CREATE Coupon (AKA Need to update Affiliate )
export const createCoupon = async (req, res) => {
//creation of date
const date = new Date();
const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
const monthsOfYear = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
const dayOfWeek = daysOfWeek[date.getUTCDay()];
const dateOfMonth = date.getUTCDate();
const month = monthsOfYear[date.getUTCMonth()];
const year = date.getUTCFullYear();
const formattedDate = `${dayOfWeek} ${dateOfMonth}-${month}-${year}`;
const {
coupon_code,
discount_amount,
valid_till,
is_coupon_active,
affiliate_discount_amount,
} = req.body;
try {
const { id } = req.body;
const update = {
coupon_code,
discount_amount,
valid_till,
affiliate_discount_amount,
createdAt: formattedDate,
is_coupon_active,
};
const options = { new: true };
const saveData = await AffiliateModel.findByIdAndUpdate(
id,
update,
options
);
if (saveData) {
res.json("done");
} else {
res.status(404).json("Affiliate not found");
}
} catch (error) {
res.status(400).json({
success: true,
message: "Coupon Already Exists",
});
console.log(error);
}
};
//GET AFFILIATE FOR COUPON LIST
export const listAffiliateCoupon = async (req, res) => {
try {
let resArr = [];
const coupon = await AffiliateModel.find(
{},
{
name: 1,
_id: 1,
is_coupon_active: 1,
mobile: 1,
}
);
for (let i = 0; i < coupon.length; i++) {
if (coupon[i].is_coupon_active == false) {
resArr.push(coupon[i]);
}
}
// console.log(resArr);
res.status(200).json({
success: true,
message: resArr,
});
} catch (error) {
res.status(500).json({
success: false,
message: error.message ? error.message : "Something went wrong!",
});
}
};
//EDIT COUPON
export const editCoupon = async (req, res) => {
const {
coupon_code,
discount_amount,
valid_till,
affiliate_discount_amount,
} = req.body;
const updateFields = {};
// Add only the fields that are present in the request body to the updateFields object
if (coupon_code) updateFields.coupon_code = coupon_code;
if (discount_amount) updateFields.discount_amount = discount_amount;
if (valid_till) updateFields.valid_till = valid_till;
if (affiliate_discount_amount)
updateFields.affiliate_discount_amount = affiliate_discount_amount;
try {
const saveData = await AffiliateModel.findByIdAndUpdate(
{ _id: req.params.id },
{ $set: updateFields },
{ new: true }
);
res.json({
success: true,
message: "Coupon Edited Succesfully",
});
} catch (error) {
res.status(400).json({
success: false,
message: error.message
? error.message
.split(":")
.splice(1)
.join(":")
.trim()
.split(":")
.splice(1)
.join(":")
.trim()
: "Error in Editing Coupon",
});
}
};
//SUSPEND COUPON
export const suspendCoupon = async (req, res) => {
const { id, is_coupon_active } = req.body;
try {
const saveData = await AffiliateModel.findByIdAndUpdate(id, {
is_coupon_active: is_coupon_active,
});
res.status(200).json({
success: true,
message: "Success",
});
} catch (error) {
res.status(400).json({
success: false,
message: "Coupon Doesn't Exists",
});
}
};
//GET ONE COUPON
export const getOneCoupon = async (req, res) => {
if (req.params?.id) {
try {
const saveData = await AffiliateModel.findById(req.params.id);
const resObj = {
name: saveData.name,
mobile: saveData.mobile,
coupon_code: saveData.coupon_code,
discount_amount: saveData.discount_amount,
valid_till: saveData.valid_till,
affiliate_discount_amount: saveData.affiliate_discount_amount,
};
res.status(200).json({
success: true,
message: resObj,
});
} catch (error) {
res.status(400).json({
success: false,
message: "Error in getting Coupons",
});
}
}
};
//Validate Coupon-----------------------
export const validateCoupon = async (req, res) => {
const { coupon } = req.params;
if (!coupon) {
return res.status(400).json({
success: false,
message: "Coupon code is required",
});
}
try {
// Find the coupon data in the database
const couponData = await AffiliateModel.findOne({ coupon_code: coupon });
if (!couponData) {
return res.status(404).json({
success: false,
message: "Coupon not found",
});
}
const { valid_till, discount_amount, is_coupon_active } = couponData;
//Check whether Coupon is Active or not
if (!is_coupon_active) {
return res.status(404).json({
success: false,
message: "Coupon Code Expired",
});
}
// Check if the coupon is expired
const currentDate = new Date();
const expirationDate = new Date(valid_till);
if (currentDate > expirationDate) {
return res.status(400).json({
success: false,
message: "Coupon has expired",
});
}
// If coupon is valid, return success response
res.status(200).json({
success: true,
message: "Coupon is valid",
discount_amount: discount_amount,
});
} catch (error) {
console.error(error);
res.status(500).json({
success: false,
message: "Internal server error",
});
}
};
//PAY & HISTORY---------------------
export const usedCoupon = async (req, res) => {
// Retrieve orderId and coupon_code from request body or query parameters
const { orderId, coupon_code, userId } = req.body;
if (!orderId || !coupon_code || !userId) {
return res.status(400).json({
success: false,
message: "Error in getting OrderId or Coupon",
});
}
// Validating Coupon
try {
const couponData = await AffiliateModel.findOne({
coupon_code: coupon_code,
});
// Check if the coupon exists
if (!couponData) {
return res.status(404).json({
success: false,
message: "Coupon not found",
});
}
const {
valid_till,
is_coupon_active,
total_earning,
is_affiliate_active,
coupon_claimed,
affiliate_discount_amount,
_id,
} = couponData;
// console.log(couponData);
if (!is_coupon_active || !is_affiliate_active) {
return res.status(404).json({
success: false,
message: "Coupon Code Expired",
});
}
const currentDate = new Date();
const expirationDate = new Date(valid_till);
if (currentDate > expirationDate) {
return res.status(400).json({
success: false,
message: "Coupon has expired",
});
}
AffiliateModel.findByIdAndUpdate(
_id,
{
$inc: { total_earning: affiliate_discount_amount, coupon_claimed: 1 },
$push: {
coupon_used_history: {
orderId: orderId,
userId: userId,
date: currentDate,
couponCode: coupon_code,
},
},
},
{ new: true }
)
.then(() => {
res.status(200).json({
success: true,
message: "Coupon add success",
});
})
.catch((error) => {
console.error(error);
res.status(500).json({
success: false,
message: "Internal server error",
});
});
} catch (error) {
console.error(error);
res.status(500).json({
success: false,
message: "Internal server error",
});
}
};
//Get Coupon data for History
export const couponPayHistory = async (req, res) => {
if (req.params?.id) {
try {
const saveData = await AffiliateModel.findById(req.params.id).sort({
updatedAt: -1,
});
// console.log(saveData.coupon_used_history);
const resObj = {
coupon_used_history: saveData.coupon_used_history,
coupon_code: saveData.coupon_code,
};
res.status(200).json({
success: true,
message: resObj,
});
} catch (error) {
res.status(400).json({
success: false,
message: "Error in getting History",
});
}
}
};

View File

@ -0,0 +1,76 @@
import express from "express";
import {
couponPayHistory,
createCoupon,
editCoupon,
getOneCoupon,
listAffiliateCoupon,
listAllCoupon,
suspendCoupon,
usedCoupon,
validateCoupon,
} from "./CouponController.js";
import {
isAuthenticatedUser,
authorizeRoles,
} from "../../../middlewares/auth.js";
const router = express.Router();
router.get(
"/getall",
isAuthenticatedUser,
authorizeRoles("admin"),
listAllCoupon
);
router.patch(
"/create",
isAuthenticatedUser,
authorizeRoles("admin"),
createCoupon
);
router.get(
"/getaffiliate",
isAuthenticatedUser,
authorizeRoles("admin"),
listAffiliateCoupon
);
router.patch(
"/edit/:id",
isAuthenticatedUser,
authorizeRoles("admin"),
editCoupon
);
router.get(
"/getone/:id",
isAuthenticatedUser,
authorizeRoles("admin"),
getOneCoupon
);
router.get("/validcoupon/:coupon", validateCoupon);
router.patch(
"/suspend",
isAuthenticatedUser,
authorizeRoles("admin"),
suspendCoupon
);
router.patch(
"/paycoupon",
// isAuthenticatedUser,
usedCoupon
);
/* url:http://localhost:5000/api/v1/coupon/paycoupon
json structure to paycoupon , Need Header to be auth
{
"userId":"random1",
"orderId":"12s213",
"coupon_code":"3000MONY"
}*/
router.get(
"/history/:id",
isAuthenticatedUser,
authorizeRoles("admin"),
couponPayHistory
);
export default router;