first commit

This commit is contained in:
2026-01-26 10:54:31 +03:30
commit 1db3038221
20 changed files with 4026 additions and 0 deletions

54
routes/herdRoutes.js Normal file
View File

@@ -0,0 +1,54 @@
const express = require("express");
const router = express.Router();
const Herd = require("../models/herd");
const { verifyToken } = require("../lib/jwtUtils");
router.post("/herds", async (req, res) => {
try {
const {
agent,
birth_day,
contractor_code,
gender,
herd_code,
national_id_livestock_code,
registering_date,
registering_user,
type,
unique_identifier,
} = req.body;
const newHerd = new Herd({
agent,
birth_day,
contractor_code,
gender,
herd_code,
national_id_livestock_code,
registering_date,
registering_user,
type,
unique_identifier,
});
const savedHerd = await newHerd.save();
res.status(201).json(savedHerd);
} catch (error) {
console.error("Error creating herd:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.get("/herds", async (req, res) => {
try {
const herds = await Herd.find();
res.status(200).json(herds);
} catch (error) {
console.error("Error retrieving herds:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
module.exports = router;

225
routes/inspectRoutes.js Normal file
View File

@@ -0,0 +1,225 @@
const express = require("express");
const router = express.Router();
const Inspect = require("../models/Inspect");
const { verifyToken } = require("../lib/jwtUtils");
router.use(verifyToken);
router.post("/inspections", async (req, res) => {
try {
const {
place_key,
province,
license_type,
document_number,
issuer,
economic_code,
registration_number,
ownership_type,
unit_type,
description,
infractions,
violation_amount,
plaintiff_damage,
inspectors,
user_id,
} = req.body;
const newInspection = new Inspect({
place_key,
province,
license_type,
document_number,
issuer,
economic_code,
registration_number,
ownership_type,
unit_type,
description,
infractions,
violation_amount,
plaintiff_damage,
inspectors,
user_id,
});
await newInspection.save();
res.status(201).json({
message: "inspection created successfully",
place: newInspection,
});
} catch (error) {
console.error("Error creating inspection:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.get("/inspections/:place_key", async (req, res) => {
try {
const placeId = req.params.place_key;
const inspections = await Inspect.find({ place_key: placeId }).sort({
createdAt: -1,
});
if (!inspections || inspections.length === 0) {
return res
.status(404)
.json({ message: "Inspections not found for this place" });
}
res.status(200).json(inspections);
} catch (error) {
console.error("Error retrieving inspections:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.get("/userinspections/:userInspects", async (req, res) => {
try {
const userInspects = req.params.userInspects;
const inspections = await Inspect.find({ user_id: userInspects }).sort({
createdAt: -1,
});
if (!inspections || inspections.length === 0) {
return res
.status(404)
.json({ message: "Inspections not found for this user" });
}
res.status(200).json(inspections);
} catch (error) {
console.error("Error retrieving inspections:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.get("/inspects", async (req, res) => {
try {
const places = await Inspect.find().sort({ createdAt: -1 });
res.status(200).json(places);
} catch (error) {
console.error("Error retrieving inspects:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.get("/inspectkeys", async (req, res) => {
try {
const places = await Inspect.find()
.select("place_key infractions")
.sort({ createdAt: -1 });
const placesWithInfractions = places.map((place) => ({
place_key: place.place_key,
hasInfractions: place.infractions.length > 0,
}));
res.status(200).json(placesWithInfractions);
} catch (error) {
console.error("Error retrieving inspects:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.delete("/inspections/:inspectId", async (req, res) => {
try {
const inspectId = req.params.inspectId;
const deletedPlace = await Inspect.findByIdAndDelete(inspectId);
if (!deletedPlace) {
return res.status(404).json({ message: "Inspection not found" });
}
res.status(200).json({
message: "Inspection deleted successfully",
place: deletedPlace,
});
} catch (error) {
console.error("Error deleting inspection:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.delete(
"/inspections/:id/infractions/:infractionId",
async (req, res) => {
const inspectId = req.params.id;
const infractionId = req.params.infractionId;
try {
const inspect = await Inspect.findById(inspectId);
if (!inspect) {
return res.status(404).json({ message: "Place not found" });
}
inspect.infractions.pull({ _id: infractionId });
await inspect.save();
res.status(200).json({ message: "Infraction deleted successfully" });
} catch (error) {
console.error("Error deleting infraction:", error);
res.status(500).json({ message: "Internal Server Error" });
}
}
);
//routes
router.put("/inspections/:inspectionId", async (req, res) => {
try {
const inspectionId = req.params.inspectionId;
const {
place_key,
province,
license_type,
document_number,
issuer,
economic_code,
registration_number,
ownership_type,
unit_type,
description,
infractions,
violation_amount,
plaintiff_damage,
inspectors,
} = req.body;
const updatedPlace = await Inspect.findByIdAndUpdate(
inspectionId,
{
place_key,
province,
license_type,
document_number,
issuer,
economic_code,
registration_number,
ownership_type,
unit_type,
description,
infractions,
violation_amount,
plaintiff_damage,
inspectors,
},
{ new: true }
);
if (!updatedPlace) {
return res.status(404).json({ message: "Inspection not found" });
}
res.status(200).json({
message: "Inspection updated successfully",
place: updatedPlace,
});
} catch (error) {
console.error("Error updating Inspection:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
module.exports = router;

View File

@@ -0,0 +1,543 @@
const express = require("express");
const router = express.Router();
const https = require("https");
const querystring = require("querystring");
const zlib = require("zlib");
const { verifyToken } = require("../lib/jwtUtils");
function getRandomElement(array) {
const randomIndex = Math.floor(Math.random() * array.length);
return array[randomIndex];
}
function parseBaJsonResponse(response, rawBuffer) {
const encoding = String(response.headers["content-encoding"] || "")
.trim()
.toLowerCase();
let buf = rawBuffer;
if (encoding === "gzip") {
buf = zlib.gunzipSync(buf);
} else if (encoding === "deflate") {
buf = zlib.inflateSync(buf);
} else if (encoding === "br") {
buf = zlib.brotliDecompressSync(buf);
}
return JSON.parse(buf.toString("utf8"));
}
async function performLogin() {
const getOptions = {
hostname: "ba124.ir",
path: "/Account/Login",
method: "GET",
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7",
Connection: "keep-alive",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1",
},
};
const loginPageCookies = await new Promise((resolve, reject) => {
const request = https.request(getOptions, (response) => {
let data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
const csrfMatch = data.match(
/<input name="__RequestVerificationToken" type="hidden" value="([^"]+)"/
);
const csrfToken = csrfMatch ? csrfMatch[1] : null;
if (!csrfToken) {
reject(new Error("Could not extract CSRF token"));
return;
}
const cookies = response.headers["set-cookie"] || [];
const cookieString = cookies
.map((cookie) => cookie.split(";")[0])
.join("; ");
resolve({ csrfToken, cookieString });
});
});
request.on("error", (error) => {
reject(error);
});
request.end();
});
const randomUser = getRandomElement([
4072893341, 4072452238, 4070413170, 4189617652, 4071417919, 4172069355,
]);
const postData = querystring.stringify({
NationalId: randomUser,
Password: randomUser,
__RequestVerificationToken: loginPageCookies.csrfToken,
});
const postOptions = {
hostname: "ba124.ir",
path: "/Account/Login",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(postData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7",
Connection: "keep-alive",
Cookie: loginPageCookies.cookieString,
Host: "ba124.ir",
Origin: "https://ba124.ir",
Referer: "https://ba124.ir/Account/Login",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1",
},
};
const finalCookie = await new Promise((resolve, reject) => {
const request = https.request(postOptions, (response) => {
response.on("data", () => {});
response.on("end", () => {
const cookies = response.headers["set-cookie"] || [];
const cookieString = cookies
.map((cookie) => cookie.split(";")[0])
.join("; ");
const combinedCookie = loginPageCookies.cookieString
? `${loginPageCookies.cookieString}; ${cookieString}`
: cookieString;
resolve(combinedCookie);
});
});
request.on("error", (error) => {
reject(error);
});
request.write(postData);
request.end();
});
return finalCookie;
}
async function makeInquiryRequest(info, type, cookie) {
const payloadData =
type === "person"
? querystring.stringify({
nationalCode: info,
birthDateString: "1404/08/12",
})
: type === "unit"
? querystring.stringify({
NationalCode: info,
})
: JSON.stringify({
NationaId: info,
});
const requestOptions = {
hostname: "ba124.ir",
path:
type === "person"
? "/Inquiries/PersonInfo"
: type === "unit"
? "/Inquiries/CallGetLegalPersonInfoByNationalCode"
: "/Inquiries/AsnafGWLicenseInquiry",
method: "POST",
headers: {
"Content-Type":
type === "person" || type === "unit"
? "application/x-www-form-urlencoded; charset=UTF-8"
: "application/json; charset=UTF-8",
"Content-Length": Buffer.byteLength(payloadData),
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
Accept: "application/json, text/javascript, */*; q=0.01",
Accept_Encoding: "gzip, deflate, br, zstd",
Accept_Language: "en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7",
Connection: "keep-alive",
Cookie: cookie,
Host: "ba124.ir",
Origin: "https://ba124.ir",
Referer:
type === "person"
? "https://ba124.ir/Inquiries/PersonInfo"
: type === "unit"
? "https://ba124.ir/Inquiries/GetLegalPersonInfoByNationalCode"
: "https://ba124.ir/Inquiries/AsnafGWLicenseInquiry",
"Sec-Ch-Ua":
'"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": '"Windows"',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"X-Requested-With": "XMLHttpRequest",
},
};
const finalInfo = await new Promise((resolve, reject) => {
const request = https.request(requestOptions, (response) => {
const chunks = [];
response.on("data", (chunk) => {
chunks.push(chunk);
});
response.on("end", () => {
try {
const raw = Buffer.concat(chunks);
const jsonData = parseBaJsonResponse(response, raw);
resolve(jsonData);
} catch (error) {
reject(new Error(`Invalid JSON response: ${error.message}`));
}
});
});
request.on("error", (error) => {
reject(error);
});
request.write(payloadData);
request.end();
});
return finalInfo;
}
async function makeLadingRequest(start, end, postal, cookie) {
const payloadData = JSON.stringify({
FromIssuDate: start,
ToIssuDate: end,
CodePosti: postal,
MabdaYaMaghsad: 3,
});
const requestOptions = {
hostname: "ba124.ir",
path: "/Inquiries/CallGetBarnamehInfoByCodePosti",
method: "POST",
headers: {
"Content-Type": "application/json; charset=UTF-8",
"Content-Length": Buffer.byteLength(payloadData),
"User-Agent":
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
Accept: "application/json, text/javascript, */*; q=0.01",
Accept_Encoding: "gzip, deflate, br, zstd",
Accept_Language:
"en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7,ar-AE;q=0.6,ar;q=0.5,en-GB;q=0.4",
Connection: "keep-alive",
Cookie: cookie,
Host: "ba124.ir",
Origin: "https://ba124.ir",
Referer: "https://ba124.ir/Inquiries/GetBarnamehInfoByCodePosti",
"Sec-Ch-Ua":
'"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": '"Linux"',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"X-Requested-With": "XMLHttpRequest",
},
};
const finalInfo = await new Promise((resolve, reject) => {
const request = https.request(requestOptions, (response) => {
const chunks = [];
response.on("data", (chunk) => {
chunks.push(chunk);
});
response.on("end", () => {
try {
const raw = Buffer.concat(chunks);
const jsonData = parseBaJsonResponse(response, raw);
resolve(jsonData);
} catch (error) {
reject(new Error(`Invalid JSON response: ${error.message}`));
}
});
});
request.on("error", (error) => {
reject(error);
});
request.write(payloadData);
request.end();
});
return finalInfo;
}
async function makeVeterinaryTransferRequest(trIDCode, cookie) {
const payloadData = querystring.stringify({
trIDCode,
});
const requestOptions = {
hostname: "ba124.ir",
path: "/Inquiries/CallVeterinaryTransfer",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(payloadData),
"User-Agent":
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
Accept: "application/json, text/javascript, */*; q=0.01",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language":
"en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7,ar-AE;q=0.6,ar;q=0.5,en-GB;q=0.4",
Connection: "keep-alive",
Cookie: cookie,
Host: "ba124.ir",
Origin: "https://ba124.ir",
Referer: "https://ba124.ir/Inquiries/VeterinaryTransfer",
"Sec-Ch-Ua":
'"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": '"Linux"',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"X-Requested-With": "XMLHttpRequest",
},
};
const finalInfo = await new Promise((resolve, reject) => {
const request = https.request(requestOptions, (response) => {
const chunks = [];
response.on("data", (chunk) => {
chunks.push(chunk);
});
response.on("end", () => {
try {
const raw = Buffer.concat(chunks);
const jsonData = parseBaJsonResponse(response, raw);
resolve(jsonData);
} catch (error) {
reject(new Error(`Invalid JSON response: ${error.message}`));
}
});
});
request.on("error", (error) => {
reject(error);
});
request.write(payloadData);
request.end();
});
return finalInfo;
}
async function makeAgriWindowsUnitsRequest(PartIdCode, cookie) {
const payloadData = querystring.stringify({
PartIdCode,
});
const requestOptions = {
hostname: "ba124.ir",
path: "/Inquiries/CallAgriWindowsUnits",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Content-Length": Buffer.byteLength(payloadData),
"User-Agent":
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
Accept: "application/json, text/javascript, */*; q=0.01",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language":
"en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7,ar-AE;q=0.6,ar;q=0.5,en-GB;q=0.4",
Connection: "keep-alive",
Cookie: cookie,
Host: "ba124.ir",
Origin: "https://ba124.ir",
Referer: "https://ba124.ir/Inquiries/VeterinaryTransfer",
"Sec-Ch-Ua":
'"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": '"Linux"',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"X-Requested-With": "XMLHttpRequest",
},
};
const finalInfo = await new Promise((resolve, reject) => {
const request = https.request(requestOptions, (response) => {
const chunks = [];
response.on("data", (chunk) => {
chunks.push(chunk);
});
response.on("end", () => {
try {
const raw = Buffer.concat(chunks);
const jsonData = parseBaJsonResponse(response, raw);
resolve(jsonData);
} catch (error) {
reject(new Error(`Invalid JSON response: ${error.message}`));
}
});
});
request.on("error", (error) => {
reject(error);
});
request.write(payloadData);
request.end();
});
return finalInfo;
}
router.use(verifyToken);
router.get("/national-documents", async (req, res) => {
const { info, type } = req.query;
if (!info) {
return res.status(400).json({
error: "Missing required field: info",
});
}
try {
let finalCookie = await performLogin();
let finalInfo = await makeInquiryRequest(info, type, finalCookie);
while (finalInfo && finalInfo.error) {
console.log("Session expired, retrying login and request...");
finalCookie = await performLogin();
finalInfo = await makeInquiryRequest(info, type, finalCookie);
}
res.json(finalInfo);
} catch (error) {
res.status(500).json({
error: "Failed to fetch person info",
message: error.message,
});
}
});
router.get("/ladinginfo", async (req, res) => {
const { start, end, postal } = req.query;
if (!start || !end || !postal) {
return res.status(400).json({
error: "Missing required fields: start, end, and postal are required",
});
}
try {
let finalCookie = await performLogin();
let finalInfo = await makeLadingRequest(start, end, postal, finalCookie);
while (finalInfo && finalInfo.error) {
console.log("Session expired, retrying login and request...");
finalCookie = await performLogin();
finalInfo = await makeLadingRequest(start, end, postal, finalCookie);
}
res.json(finalInfo);
} catch (error) {
res.status(500).json({
error: "Failed to fetch lading info",
message: error.message,
});
}
});
router.get("/veterinary-transfer", async (req, res) => {
const { trIDCode } = req.query;
if (!trIDCode) {
return res.status(400).json({
error: "Missing required field: trIDCode",
});
}
try {
let finalCookie = await performLogin();
let finalInfo = await makeVeterinaryTransferRequest(trIDCode, finalCookie);
while (finalInfo && finalInfo.error) {
console.log("Session expired, retrying login and request...");
finalCookie = await performLogin();
finalInfo = await makeVeterinaryTransferRequest(trIDCode, finalCookie);
}
res.json(finalInfo);
} catch (error) {
res.status(500).json({
error: "Failed to fetch veterinary transfer info",
message: error.message,
});
}
});
router.get("/inquiry-farm", async (req, res) => {
const { PartIdCode } = req.query;
if (!PartIdCode) {
return res.status(400).json({
error: "Missing required field: PartIdCode",
});
}
try {
let finalCookie = await performLogin();
let finalInfo = await makeAgriWindowsUnitsRequest(PartIdCode, finalCookie);
while (finalInfo && finalInfo.error) {
console.log("Session expired, retrying login and request...");
finalCookie = await performLogin();
finalInfo = await makeAgriWindowsUnitsRequest(PartIdCode, finalCookie);
}
res.json(finalInfo);
} catch (error) {
res.status(500).json({
error: "Failed to fetch inquiry farm info",
message: error.message,
});
}
});
module.exports = router;

359
routes/peopleInfoRoutes.js Normal file
View File

@@ -0,0 +1,359 @@
const express = require("express");
const router = express.Router();
const PeopleInfo = require("../models/peopleInfo");
router.get("/people_info", async (req, res) => {
try {
const { searchfield, value } = req.query;
if (!searchfield || !value) {
return res.status(400).json({
message: "searchfield and value parameters are required",
});
}
let matchQuery = {};
if (searchfield === "mobile") {
let normalizedSearch = value.replace(/\D/g, "");
const withLeadingZero = normalizedSearch.startsWith("0")
? normalizedSearch
: `0${normalizedSearch}`;
const withoutLeadingZero = normalizedSearch.startsWith("0")
? normalizedSearch.substring(1)
: normalizedSearch;
const numericValue = parseInt(withoutLeadingZero, 10);
matchQuery = {
$or: [
{ mobile: withLeadingZero },
{ mobile: withoutLeadingZero },
{ mobile: numericValue },
],
};
} else if (searchfield === "name") {
matchQuery = {
$or: [
{ name: { $regex: value, $options: "i" } },
{ family: { $regex: value, $options: "i" } },
{
$expr: {
$regexMatch: {
input: { $concat: ["$name", " ", "$family"] },
regex: value,
options: "i",
},
},
},
],
};
} else if (searchfield === "nationalcode") {
matchQuery = { nationalcode: value };
} else {
return res.status(400).json({
message:
"Invalid searchfield. Must be 'mobile', 'name', or 'nationalcode'",
});
}
const pipeline = [
{ $match: matchQuery },
{ $limit: 10000 },
{
$group: {
_id: "$nationalcode",
items: {
$push: {
name: "$name",
family: "$family",
mobile: "$mobile",
mellicard: "$mellicard",
mellatcard: "$mellatcard",
father: "$father",
birthdate: "$birthdate",
info1: "$info1",
info2: "$info2",
info3: "$info3",
info4: "$info4",
hasMellatcard: {
$cond: [{ $ne: ["$mellatcard", null] }, true, false],
},
hasMellicard: {
$cond: [{ $ne: ["$mellicard", null] }, true, false],
},
},
},
},
},
{
$project: {
nationalcode: "$_id",
items: 1,
firstWithMellatcard: {
$arrayElemAt: [
{
$filter: {
input: "$items",
as: "item",
cond: { $eq: ["$$item.hasMellatcard", true] },
},
},
0,
],
},
firstWithMellicard: {
$arrayElemAt: [
{
$filter: {
input: "$items",
as: "item",
cond: { $eq: ["$$item.hasMellicard", true] },
},
},
0,
],
},
hasAnyMellatcard: {
$gt: [
{
$size: {
$filter: {
input: "$items",
as: "item",
cond: { $eq: ["$$item.hasMellatcard", true] },
},
},
},
0,
],
},
hasAnyMellicard: {
$gt: [
{
$size: {
$filter: {
input: "$items",
as: "item",
cond: { $eq: ["$$item.hasMellicard", true] },
},
},
},
0,
],
},
},
},
{
$project: {
nationalcode: 1,
name: {
$cond: [
{ $ne: ["$firstWithMellatcard", null] },
"$firstWithMellatcard.name",
{
$cond: [
{ $ne: ["$firstWithMellicard", null] },
"$firstWithMellicard.name",
{ $arrayElemAt: ["$items.name", 0] },
],
},
],
},
family: {
$cond: [
{ $ne: ["$firstWithMellatcard", null] },
"$firstWithMellatcard.family",
{
$cond: [
{ $ne: ["$firstWithMellicard", null] },
"$firstWithMellicard.family",
{ $arrayElemAt: ["$items.family", 0] },
],
},
],
},
father: {
$cond: [
{ $ne: ["$firstWithMellatcard", null] },
"$firstWithMellatcard.father",
{
$cond: [
{ $ne: ["$firstWithMellicard", null] },
"$firstWithMellicard.father",
null,
],
},
],
},
birthdate: {
$cond: [
{ $ne: ["$firstWithMellatcard", null] },
"$firstWithMellatcard.birthdate",
{
$cond: [
{ $ne: ["$firstWithMellicard", null] },
"$firstWithMellicard.birthdate",
null,
],
},
],
},
mobile: {
$filter: {
input: "$items.mobile",
as: "mob",
cond: { $ne: ["$$mob", null] },
},
},
allCards: {
$reduce: {
input: "$items",
initialValue: [],
in: {
$concatArrays: [
"$$value",
{
$filter: {
input: ["$$this.mellatcard", "$$this.mellicard"],
as: "card",
cond: { $ne: ["$$card", null] },
},
},
],
},
},
},
info: {
$reduce: {
input: "$items",
initialValue: [],
in: {
$concatArrays: [
"$$value",
{
$filter: {
input: [
"$$this.info1",
"$$this.info2",
"$$this.info3",
"$$this.info4",
],
as: "inf",
cond: { $ne: ["$$inf", null] },
},
},
],
},
},
},
},
},
{
$project: {
nationalcode: 1,
name: 1,
family: 1,
father: 1,
birthdate: 1,
mobile: 1,
card: "$allCards",
info: 1,
},
},
];
const results = await PeopleInfo.aggregate(pipeline).allowDiskUse(true);
const processedResults = results.map((result) => {
const mobileSet = new Set();
result.mobile.forEach((mob) => {
if (mob == null) return;
const mobStr = String(mob);
const normalized = mobStr.startsWith("0")
? mobStr.substring(1)
: mobStr;
mobileSet.add(`0${normalized}`);
});
result.mobile = Array.from(mobileSet);
if (result.card) {
const cardSet = new Set();
result.card.forEach((card) => {
if (card && typeof card === "string") {
cardSet.add(card.trim());
}
});
result.card = Array.from(cardSet);
}
if (result.birthdate && result.birthdate instanceof Date) {
result.birthdate = result.birthdate.toISOString().split("T")[0];
}
result.info = result.info.map((inf) => {
return typeof inf === "string" ? inf.replace(/\t/g, "") : inf;
});
return result;
});
res.status(200).json({
data: processedResults,
count: processedResults.length,
});
} catch (error) {
console.error("Error fetching people info:", error);
res
.status(500)
.json({ message: "Internal Server Error", error: error.message });
}
});
router.post("/people_info", async (req, res) => {
try {
const {
first_name,
last_name,
mobile,
postal,
province,
city,
nationalcode,
} = req.body;
const newPeopleInfo = new PeopleInfo({
first_name,
last_name,
mobile,
postal,
province,
city,
nationalcode,
});
await newPeopleInfo.save();
res.status(201).json({
message: "People info created successfully",
data: newPeopleInfo,
});
} catch (error) {
console.error("Error creating people info:", error);
res
.status(500)
.json({ message: "Internal Server Error", error: error.message });
}
});
module.exports = router;

159
routes/placeRoutes.js Normal file
View File

@@ -0,0 +1,159 @@
const express = require("express");
const router = express.Router();
const Place = require("../models/place");
const UpdateData = require("../models/UpdateData");
const { verifyToken } = require("../lib/jwtUtils");
router.use(verifyToken);
router.post("/place", async (req, res) => {
try {
const { name, description, location, category } = req.body;
const newPlace = new Place({ name, description, location, category });
await newPlace.save();
res
.status(201)
.json({ message: "Place created successfully", place: newPlace });
} catch (error) {
console.error("Error creating place:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.get("/place_data/:placeId", async (req, res) => {
try {
const placeId = req.params.placeId;
const place = await Place.findById(placeId);
if (!place) {
return res.status(404).json({ message: "Place not found" });
}
res.status(200).json({ place });
} catch (error) {
console.error("Error retrieving place:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.get("/places", async (req, res) => {
try {
const places = await Place.find();
res.status(200).json(places);
} catch (error) {
console.error("Error retrieving places:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.delete("/places/:placeId", async (req, res) => {
try {
const placeId = req.params.placeId;
const deletedPlace = await Place.findByIdAndDelete(placeId);
if (!deletedPlace) {
return res.status(404).json({ message: "Place not found" });
}
res
.status(200)
.json({ message: "Place deleted successfully", place: deletedPlace });
} catch (error) {
console.error("Error deleting place:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.put("/places/:placeId", async (req, res) => {
try {
const placeId = req.params.placeId;
const { name, description, location, category } = req.body;
const updatedPlace = await Place.findByIdAndUpdate(
placeId,
{ name, description, location, category },
{ new: true } // Set { new: true } to return the updated document
);
if (!updatedPlace) {
return res.status(404).json({ message: "Place not found" });
}
res
.status(200)
.json({ message: "Place updated successfully", place: updatedPlace });
} catch (error) {
console.error("Error updating place:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.post("/update-data", async (req, res) => {
const { province } = req.body;
if (!province) {
return res.status(400).send("Province is required");
}
let api = `https://pos.rasadyaar.ir/api/report/pos/${province}`;
console.log("Fetching data from:", api);
try {
const response = await fetch(api);
const newProvinceData = await response.json();
await UpdateData.updateOne(
{},
{ $set: { [`records.${province}`]: newProvinceData } },
{ upsert: true }
);
res.status(200).send(`Data for ${province} successfully updated!`);
} catch (error) {
console.error("Error fetching or updating province data:", error);
res.status(500).send("Failed to update data.");
}
});
router.get("/stewards/:key", async (req, res) => {
const { key } = req.params;
try {
const data = await UpdateData.findOne();
if (data && data.records) {
const recordData = data.records.get(key);
if (recordData) {
res.status(200).json(recordData);
} else {
res.status(404).json({ message: `No data found for key: ${key}` });
}
} else {
res.status(404).json({ message: "No data found" });
}
} catch (error) {
console.error(error);
res.status(500).json({ message: "Server error" });
}
});
module.exports = router;
// router
// .route("/:id")
// .get((req, res) => {
// res.send(`User Get ${req.params.id}`);
// })
// .post((req, res) => {
// res.send(`User Get ${req.params.id}`);
// })
// .put((req, res) => {
// res.send(`User Get ${req.params.id}`);
// })
// .delete((req, res) => {
// res.send(`User Get ${req.params.id}`);
// });
// module.exports = router;

161
routes/userRoutes.js Normal file
View File

@@ -0,0 +1,161 @@
const express = require("express");
const router = express.Router();
const User = require("../models/user");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcrypt");
const { verifyToken, generateToken } = require("../lib/jwtUtils");
router.post("/user", async (req, res) => {
try {
const { mobile, password, fullname, pic, province, permissions, city } =
req.body;
const hashedPassword = await bcrypt.hash(password, 10);
const newUser = new User({
mobile,
password: hashedPassword,
pic,
fullname,
province,
city,
permissions,
});
await newUser.save();
const token = generateToken(newUser._id);
res.status(201).json({
message: "User created successfully",
user: newUser,
token,
});
} catch (error) {
console.error("Error creating user:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.post("/login", async (req, res) => {
try {
const { mobile, password } = req.body;
const user = await User.findOne({ mobile });
if (!user) {
return res.status(403).json({ message: "Invalid credentials" });
}
const passwordMatch = await bcrypt.compare(password, user.password);
if (!passwordMatch) {
return res.status(403).json({ message: "Invalid credentials" });
}
const token = generateToken(user._id);
const userWithoutPassword = { ...user.toObject() };
delete userWithoutPassword.password;
res
.status(200)
.json({ message: "Login successful", token, user: userWithoutPassword });
} catch (error) {
console.error("Error during login:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.use(verifyToken);
router.get("/user_profile/:userId", async (req, res) => {
try {
const userId = req.params.userId;
const user = await User.findById(userId);
if (!user) {
return res.status(404).json({ message: "User not found" });
}
res.status(200).json({ user });
} catch (error) {
console.error("Error retrieving user:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.get("/users/:province", async (req, res) => {
try {
const province = req.params.province;
const users = (await User.find({ province: province })).filter(
(item) => !item.permissions.includes("admin")
);
res.status(200).json(users);
} catch (error) {
console.error("Error retrieving users:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.delete("/users/:userId", async (req, res) => {
try {
const userId = req.params.userId;
const deletedUser = await User.findByIdAndDelete(userId);
if (!deletedUser) {
return res.status(404).json({ message: "User not found" });
}
res
.status(200)
.json({ message: "User deleted successfully", user: deletedUser });
} catch (error) {
console.error("Error deleting user:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
router.put("/user/:userId", async (req, res) => {
try {
const userId = req.params.userId;
const { mobile, password, fullname, pic, province, permissions } = req.body;
const updatedUser = await User.findByIdAndUpdate(
userId,
{ mobile, password, fullname, pic, province, permissions },
{ new: true } // Set { new: true } to return the updated document
);
if (!updatedUser) {
return res.status(404).json({ message: "User not found" });
}
res
.status(200)
.json({ message: "User updated successfully", user: updatedUser });
} catch (error) {
console.error("Error updating user:", error);
res.status(500).json({ message: "Internal Server Error" });
}
});
module.exports = router;
// router
// .route("/:id")
// .get((req, res) => {
// res.send(`User Get ${req.params.id}`);
// })
// .post((req, res) => {
// res.send(`User Get ${req.params.id}`);
// })
// .put((req, res) => {
// res.send(`User Get ${req.params.id}`);
// })
// .delete((req, res) => {
// res.send(`User Get ${req.params.id}`);
// });
// module.exports = router;