Init
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
PORT=6060
|
||||
SECRET=fs4ebJ87dfyu87sdHdfgd
|
||||
ACCESS_TOKEN_SECERT=J78fsd7fd8f9M8fdfJDSOW0fd
|
||||
ACCESS_TOKEN_SECERT_ADMIN=J78fF4fsFHf9Mdfsdf54fFeW0fdds
|
||||
CONNECTION_STRING=mongodb://root:K0W9aON8qOTYVui28Ir4qeFn@robin.iran.liara.ir:30448/asan-market?authSource=admin
|
||||
CONNECTION_STRING_LOCAL=mongodb://127.0.0.1:27017/asan-market?authSource=admin
|
||||
MERCHANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
EMAIL_HOST=
|
||||
EMAIL_PORT=
|
||||
EMAIL_USER=
|
||||
EMAIL_PASS=
|
||||
EMAIL_ADDRESS=
|
||||
SMS_USER=
|
||||
SMS_PASS=
|
||||
SMS_NUMBER=
|
||||
URLIMAGE=https://api-asanmarket.iran.liara.run
|
||||
@@ -0,0 +1,23 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
jquery: true
|
||||
},
|
||||
parserOptions: {
|
||||
parser: '@babel/eslint-parser',
|
||||
requireConfigFile: false
|
||||
},
|
||||
extends: ['@nuxtjs', 'plugin:nuxt/recommended', 'prettier'],
|
||||
plugins: [],
|
||||
// add your custom rules here
|
||||
rules: {
|
||||
'no-console': 'off',
|
||||
camelcase: 'off',
|
||||
'no-async-promise-executor': 'off',
|
||||
'vue/no-v-html': 'off',
|
||||
'vue/prop-name-casing': 'off'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
@@ -0,0 +1,6 @@
|
||||
/node_modules
|
||||
.png
|
||||
.jpg
|
||||
.web
|
||||
|
||||
*.png
|
||||
@@ -0,0 +1,19 @@
|
||||
const mongoose = require("mongoose");
|
||||
const db = async () => {
|
||||
try {
|
||||
const connect = await mongoose.connect(process.env.CONNECTION_STRING);
|
||||
console.log(
|
||||
"Database connected: ",
|
||||
connect.connection.host,
|
||||
connect.connection.name
|
||||
);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
setTimeout(() => {
|
||||
console.log("Retry for DB");
|
||||
db();
|
||||
}, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = db;
|
||||
@@ -0,0 +1,26 @@
|
||||
const nodemailer = require("nodemailer");
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: process.env.EMAIL_HOST,
|
||||
port: process.env.EMAIL_PORT,
|
||||
secure: true,
|
||||
auth: {
|
||||
user: process.env.EMAIL_USER,
|
||||
pass: process.env.EMAIL_PASS,
|
||||
},
|
||||
});
|
||||
|
||||
const email = async (to, subject, text, html) => {
|
||||
|
||||
const info = await transporter.sendMail({
|
||||
from: `"Asan Market" ${process.env.EMAIL_ADDRESS}`, // sender address
|
||||
to: to, // list of receivers
|
||||
subject: subject, // Subject line
|
||||
text: text, // plain text body
|
||||
html: html, // html body
|
||||
});
|
||||
|
||||
|
||||
|
||||
};
|
||||
module.exports = email;
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
const axios = require('axios')
|
||||
|
||||
const accountInfo = {
|
||||
Username: '000',
|
||||
Password: '000',
|
||||
Number: '000',
|
||||
url: 'http://www.afe.ir/WebService/V4/BoxService.asmx'
|
||||
}
|
||||
|
||||
/////// http post soap method
|
||||
module.exports.sms = (mobileNumbersArray, message) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
function renderMobileNumbers(array) {
|
||||
if (Array.isArray(array)) {
|
||||
return array.map(item => `<string>${item}</string>`).join('')
|
||||
} else {
|
||||
return `<string>${array}</string>`
|
||||
}
|
||||
}
|
||||
|
||||
const xml = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<soap:Body>
|
||||
<SendMessage xmlns="http://www.afe.ir/">
|
||||
<Username>${accountInfo.Username}</Username>
|
||||
<Password>${accountInfo.Password}</Password>
|
||||
<Number>${accountInfo.Number}</Number>
|
||||
<Mobile>
|
||||
${renderMobileNumbers(mobileNumbersArray)}
|
||||
</Mobile>
|
||||
<Message>${message}</Message>
|
||||
<Type>1</Type>
|
||||
</SendMessage>
|
||||
</soap:Body>
|
||||
</soap:Envelope>`
|
||||
|
||||
axios
|
||||
.post(accountInfo.url, xml, {
|
||||
headers: {
|
||||
'Content-Type': 'text/xml; charset=utf-8',
|
||||
SOAPAction: 'http://www.afe.ir/SendMessage'
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
resolve(res)
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(
|
||||
'this is sms module error ------------------ status code: %s error message: %s ',
|
||||
err.response.status,
|
||||
err.response.data
|
||||
)
|
||||
resolve(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
exports.constants = {
|
||||
VALIDATION_ERROR: 400,
|
||||
UNAUTHORIZED: 401,
|
||||
FORBIDOEN: 403,
|
||||
NOT_FOUND: 404,
|
||||
SERVER_ERROR: 500,
|
||||
SITE_UNAUTHORIZED: 422,
|
||||
TOO_MANY: 429,
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
const asyncHandler = require("express-async-handler");
|
||||
const News = require("../models/newsModels");
|
||||
const { email } = require("../config/emailConnection");
|
||||
const { checkValidations } = require("../plugins/HelperFunctions")
|
||||
const { body, validationResult } = require('express-validator')
|
||||
const { _sr } = require("../plugins/resServer")
|
||||
const { rateLimit } = require('express-rate-limit')
|
||||
|
||||
const limiter = rateLimit({
|
||||
windowMs: 24 * 60 * 60 * 1000, // 1 minutes
|
||||
limit: 1, // Limit each IP to 100 requests per `window` (here, per 15 minutes).
|
||||
standardHeaders: 'draft-7', // draft-6: `RateLimit-*` headers; draft-7: combined `RateLimit` header
|
||||
legacyHeaders: false, // Disable the `X-RateLimit-*` headers.
|
||||
message: { msg: "Too many requests, please try again later." }
|
||||
})
|
||||
|
||||
/**
|
||||
*@desc Add new email
|
||||
*@route POST /api/news/
|
||||
*@access private
|
||||
*/
|
||||
const addEmail = [
|
||||
[
|
||||
body('email').notEmpty().isEmail().withMessage(_sr.fa.required.email),
|
||||
],
|
||||
checkValidations(validationResult),
|
||||
limiter,
|
||||
asyncHandler(async (req, res) => {
|
||||
const { email } = req.body
|
||||
const alreadyEmail = await News.findOne({ email })
|
||||
if (alreadyEmail) {
|
||||
res.status(400);
|
||||
throw new Error(_sr.fa.duplicated.email);
|
||||
}
|
||||
const emailAdded = await News.create({
|
||||
email
|
||||
})
|
||||
res.status(200).json(emailAdded)
|
||||
})
|
||||
]
|
||||
|
||||
|
||||
module.exports = {
|
||||
baseRoute: "/news",
|
||||
items: [
|
||||
{
|
||||
off: false,
|
||||
route: "/",
|
||||
method: "post",
|
||||
middleware: [],
|
||||
use: addEmail
|
||||
},
|
||||
|
||||
]
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
const asyncHandler = require("express-async-handler");
|
||||
const Site = require("../models/siteModels");
|
||||
const { _sr } = require("../plugins/resServer")
|
||||
|
||||
|
||||
/**
|
||||
*@desc Get all site
|
||||
*@route GET /api/sites/
|
||||
*@access Public
|
||||
*/
|
||||
const getSite = asyncHandler(async (req, res) => {
|
||||
const profile = await Site.findOne({ profile: "main" });
|
||||
res.status(200).json(profile);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
*@desc Update a site
|
||||
*@route PUT /api/sites/
|
||||
*@access private
|
||||
*/
|
||||
const updateSite = [
|
||||
asyncHandler(async (req, res) => {
|
||||
const site = await Site.findOneAndUpdate(
|
||||
{ profile: "main" },
|
||||
req.body,
|
||||
{ new: true }
|
||||
);
|
||||
|
||||
if (!site) {
|
||||
res.status(404);
|
||||
throw new Error(_sr.fa.not_found.item_id);
|
||||
}
|
||||
res.status(200).json(site);
|
||||
})
|
||||
]
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
baseRoute: "/sites",
|
||||
items: [
|
||||
{
|
||||
off: false,
|
||||
route: "/",
|
||||
method: "get",
|
||||
middleware: ['validateAdminToken', 'hasPermission'],
|
||||
permission: "SITE",
|
||||
use: getSite
|
||||
},
|
||||
{
|
||||
off: false,
|
||||
route: "/id/:id",
|
||||
method: "put",
|
||||
middleware: ['validateAdminToken', 'hasPermission'],
|
||||
permission: "SITE",
|
||||
use: updateSite
|
||||
},
|
||||
]
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": ["./*"],
|
||||
"@/*": ["./*"],
|
||||
"~~/*": ["./*"],
|
||||
"@@/*": ["./*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"app":"api-asanmarket",
|
||||
"port":"5050",
|
||||
"disks":[
|
||||
{
|
||||
"name": "uploads",
|
||||
"mountTo": "uploads"
|
||||
}
|
||||
],
|
||||
"node": {
|
||||
"version": "18"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
const { constants } = require("../constants");
|
||||
const errorHandler = (err, req, res, next) => {
|
||||
const statusCode = res.statusCode ? res.statusCode : 500;
|
||||
|
||||
switch (statusCode) {
|
||||
case constants.VALIDATION_ERROR:
|
||||
res.status(statusCode).json({
|
||||
title: "Validation Failed ",
|
||||
msg: err.message,
|
||||
stackTrace: err.stack,
|
||||
});
|
||||
break;
|
||||
case constants.NOT_FOUND:
|
||||
res.status(statusCode).json({
|
||||
title: "Not found ",
|
||||
msg: err.message,
|
||||
stackTrace: err.stack,
|
||||
});
|
||||
break;
|
||||
case constants.FORBIDOEN:
|
||||
res.status(statusCode).json({
|
||||
title: "Forbidoen ",
|
||||
msg: err.message,
|
||||
stackTrace: err.stack,
|
||||
});
|
||||
break;
|
||||
case constants.SERVER_ERROR:
|
||||
res.status(statusCode).json({
|
||||
title: "Server Error ",
|
||||
msg: err.message,
|
||||
stackTrace: err.stack,
|
||||
});
|
||||
break;
|
||||
case constants.UNAUTHORIZED:
|
||||
res.status(statusCode).json({
|
||||
title: "Unauthorized ",
|
||||
msg: err.message,
|
||||
stackTrace: err.stack,
|
||||
});
|
||||
break;
|
||||
case constants.SITE_UNAUTHORIZED:
|
||||
res.status(statusCode).json({
|
||||
title: "Site Unauthorized ",
|
||||
msg: err.message,
|
||||
stackTrace: err.stack,
|
||||
});
|
||||
break;
|
||||
case constants.TOO_MANY:
|
||||
res.status(statusCode).json({
|
||||
title: "Too many request",
|
||||
msg: err.message,
|
||||
stackTrace: err.stack,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
console.log(err);
|
||||
res.status(500).json({ err: err.message, msg: "Unhandled error" })
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { name: "errorHandler", run: errorHandler };
|
||||
@@ -0,0 +1,17 @@
|
||||
const asyncHandler = require("express-async-handler");
|
||||
const User = require("../models/userModels");
|
||||
|
||||
|
||||
const hasPerma = (perm) => {
|
||||
return asyncHandler(async (req, res, next) => {
|
||||
const user = await User.findId(req.user.id)
|
||||
if (user && (user.permissions.includes(perm) || !user.permissions.includes("ADMIN"))) {
|
||||
return next()
|
||||
} else {
|
||||
res.status(401); throw new Error('کاربر مجوز لازم را ندارد');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
module.exports = { name: "hasPermission", run: hasPerma };
|
||||
@@ -0,0 +1,28 @@
|
||||
const asyncHandler = require("express-async-handler");
|
||||
const jwt = require("jsonwebtoken");
|
||||
const Admin = require("../models/adminModels");
|
||||
const validateAdminToken = asyncHandler(async (req, res, next) => {
|
||||
let token = req.headers.siteuser || req.headers.SiteUser;
|
||||
|
||||
if (!token) {
|
||||
res.status(401);
|
||||
throw new Error("User is not authorized(N)");
|
||||
} else {
|
||||
const tokenA = await Admin.findOne({ token })
|
||||
if (tokenA) {
|
||||
jwt.verify(token, process.env.ACCESS_TOKEN_SECERT_ADMIN, (err, decoded) => {
|
||||
if (err) {
|
||||
res.status(401);
|
||||
throw new Error("User is not authorized(JWT E)");
|
||||
}
|
||||
req.admin = decoded.user;
|
||||
next();
|
||||
});
|
||||
} else {
|
||||
res.status(401);
|
||||
throw new Error("User is not authorized(DB N)");
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
module.exports = { name: "validateAdminToken", run: validateAdminToken };
|
||||
@@ -0,0 +1,28 @@
|
||||
const asyncHandler = require("express-async-handler");
|
||||
const jwt = require("jsonwebtoken");
|
||||
const User = require("../models/userModels");
|
||||
|
||||
const validateToken = asyncHandler(async (req, res, next) => {
|
||||
let token = req.headers.authorization || req.headers.Authorization;
|
||||
|
||||
if (!token) {
|
||||
res.status(401);
|
||||
throw new Error("User is not authorized(N)");
|
||||
} else {
|
||||
const tokenA = await User.findOne({ token })
|
||||
if (tokenA) {
|
||||
jwt.verify(token, process.env.ACCESS_TOKEN_SECERT, (err, decoded) => {
|
||||
if (err) {
|
||||
res.status(401);
|
||||
throw new Error("User is not authorized(JWT E)");
|
||||
}
|
||||
req.user = decoded.user;
|
||||
next();
|
||||
});
|
||||
} else {
|
||||
res.status(401);
|
||||
throw new Error("User is not authorized(DB N)");
|
||||
}
|
||||
}
|
||||
});
|
||||
module.exports = { name: "validateToken", run: validateToken };
|
||||
@@ -0,0 +1,15 @@
|
||||
const mongoose = require("mongoose");
|
||||
|
||||
const newsSchema = new mongoose.Schema({
|
||||
email: {
|
||||
type: String,
|
||||
unique: true
|
||||
}
|
||||
},
|
||||
{
|
||||
timestamps: true,
|
||||
versionKey: false
|
||||
}
|
||||
);
|
||||
|
||||
module.exports = mongoose.model("News", newsSchema);
|
||||
@@ -0,0 +1,59 @@
|
||||
const mongoose = require("mongoose");
|
||||
|
||||
const siteSchema = new mongoose.Schema(
|
||||
{
|
||||
profile: {
|
||||
type: String,
|
||||
default: "main",
|
||||
unique: true
|
||||
},
|
||||
name:{
|
||||
type: String,
|
||||
default: "Dlearn",
|
||||
},
|
||||
desc:{
|
||||
type: String,
|
||||
default: "Dlearn, marketplace core by Swift",
|
||||
},
|
||||
logo:{
|
||||
type: String,
|
||||
default: "/upload/Default.png",
|
||||
},
|
||||
tel1:{
|
||||
type: String,
|
||||
default: "+9391885657",
|
||||
},
|
||||
tel2:{
|
||||
type: String,
|
||||
default: "+9391885657",
|
||||
},
|
||||
address:{
|
||||
type: String,
|
||||
default: "Iran, Markazi",
|
||||
},
|
||||
socialMedia:[
|
||||
{
|
||||
kind: String,
|
||||
address:String
|
||||
}
|
||||
],
|
||||
emailHost:String,
|
||||
emailPort:String,
|
||||
emailUser:String,
|
||||
emailPass:String,
|
||||
smsNumber:String,
|
||||
smsUser:String,
|
||||
smsPass:String,
|
||||
underConstruction:{
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
|
||||
},
|
||||
{
|
||||
timestamps: true,
|
||||
versionKey: false
|
||||
}
|
||||
);
|
||||
|
||||
module.exports = mongoose.model("Site", siteSchema);
|
||||
Generated
+4648
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "asanmarket",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"dev": "nodemon server.js"
|
||||
},
|
||||
"author": "swift",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "^1.6.2",
|
||||
"bcrypt": "^5.1.0",
|
||||
"cors": "^2.8.5",
|
||||
"cron": "^3.1.6",
|
||||
"dotenv": "^16.3.1",
|
||||
"express": "^4.18.2",
|
||||
"express-async-handler": "^1.2.0",
|
||||
"express-fileupload": "^1.4.1",
|
||||
"express-rate-limit": "^7.2.0",
|
||||
"express-route-detector": "^1.1.0",
|
||||
"express-sharp": "^4.2.41",
|
||||
"express-validator": "^7.0.1",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"moment": "^2.29.4",
|
||||
"mongodb": "^5.6.0",
|
||||
"mongoose": "^7.3.1",
|
||||
"mongoose-sequence": "^6.0.1",
|
||||
"nodemailer": "^6.9.4",
|
||||
"nodemon": "^2.0.22",
|
||||
"swiftly-tools": "1.2.82"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
|
||||
|
||||
const checkValidations = validationResult => {
|
||||
return (req, res, next) => {
|
||||
const errors = validationResult(req)
|
||||
if (!errors.isEmpty()) {
|
||||
const msg = {}
|
||||
errors.errors.forEach(err => {
|
||||
msg[err.path] = err.msg
|
||||
});
|
||||
res.status(422).json(msg)
|
||||
} else next()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function filterDatesWithinDays(data, days, status) {
|
||||
const currentDate = new Date();
|
||||
const sevenDaysAgo = new Date(currentDate.getTime() - days * 24 * 60 * 60 * 1000);
|
||||
if (status) {
|
||||
return data.orders.filter(item => {
|
||||
const itemDate = new Date(item.orderDate);
|
||||
return itemDate >= sevenDaysAgo && itemDate <= currentDate && item.status == status;
|
||||
});
|
||||
} else {
|
||||
return data.orders.filter(item => {
|
||||
const itemDate = new Date(item.orderDate);
|
||||
return itemDate >= sevenDaysAgo && itemDate <= currentDate;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function filterWithStatus(data, status) {
|
||||
return data.orders.filter(item => {
|
||||
return item.status == status;
|
||||
});
|
||||
}
|
||||
|
||||
const sumProductsById = (data) => {
|
||||
const sumArray = [];
|
||||
const map = {};
|
||||
|
||||
data.forEach(item => {
|
||||
item.products.forEach(pd=>{
|
||||
const productId = pd.product.uid;
|
||||
const product = pd.product;
|
||||
const price = pd.price;
|
||||
|
||||
if (!map[productId]) {
|
||||
map[productId] = { product, total: 0, quantity: 0 };
|
||||
sumArray.push(map[productId]);
|
||||
}
|
||||
|
||||
map[productId].total += price;
|
||||
map[productId].quantity = product.stockQuantity;
|
||||
|
||||
})
|
||||
});
|
||||
|
||||
return (sumArray.sort((a, b) => a - b)).slice(0, 5);
|
||||
};
|
||||
|
||||
function filterQuantityHigh3(data) {
|
||||
return data.products.filter(item => {
|
||||
return item.stockQuantity > 0
|
||||
});
|
||||
}
|
||||
|
||||
function filterQuantityLow3(data) {
|
||||
return data.products.filter(item => {
|
||||
return item.stockQuantity <= 3
|
||||
});
|
||||
}
|
||||
|
||||
function filterZeroStock(data) {
|
||||
return data.products.filter(item => {
|
||||
return item.stockQuantity == 0
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
filterDatesWithinDays,
|
||||
sumProductsById,
|
||||
filterWithStatus,
|
||||
filterQuantityHigh3,
|
||||
filterQuantityLow3,
|
||||
filterZeroStock,
|
||||
checkValidations
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
module.exports = {
|
||||
populate: {
|
||||
productPopAdmin: 'comments shopID sub brandID'
|
||||
},
|
||||
select: {
|
||||
userCustom: 'firstName lastName phoneNumber cellNumber',
|
||||
user: 'firstName lastName',
|
||||
auther: 'firstName lastName',
|
||||
comment: 'firstName lastName',
|
||||
productCard: 'title price specialPrice specialSell category coverImage coverPath stars orderRange uid',
|
||||
productCard2: 'title category coverImage coverPath uid',
|
||||
blogCard: 'link title coverImage content',
|
||||
shop: 'shopName active rate desc',
|
||||
brand: 'title link description logo',
|
||||
category: 'main ordering link name',
|
||||
shopProduct: 'title uid link price category specialPrice stockQuantity coverImage order confirmToShow createdAt updatedAt',
|
||||
userMinus: '-password -token -createdAt -updatedAt -otp -otpTime -attempOtp -lastAttemp',
|
||||
userProfile: 'favoriteProducts notifications',
|
||||
productCart: 'title uid price specialPrice category coverImage shopID itemInBox boxSeller localSend warranty orderRange'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const moment = require("moment");
|
||||
const date = moment();
|
||||
|
||||
const uploadImage = (image, res, type) => {
|
||||
const maxSize = 15 * 1024 * 1024; // 15MB (example limit)
|
||||
|
||||
if (image.size > maxSize) {
|
||||
res.status(500)
|
||||
throw new Error("Image file size exceeds the limit")
|
||||
}
|
||||
let imageName =
|
||||
date.format("YYYY-MM-DD") +
|
||||
"-Img-" +
|
||||
Math.floor(Math.random() * 900) +
|
||||
100 +
|
||||
image.name;
|
||||
|
||||
let saveToPath
|
||||
let preFile
|
||||
|
||||
switch (type) {
|
||||
case "1":
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/products", imageName);
|
||||
preFile = "/uploads/products/"
|
||||
break;
|
||||
|
||||
case "2":
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/blogs", imageName);
|
||||
preFile = "/uploads/blogs/"
|
||||
break;
|
||||
|
||||
case "3":
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/personal", imageName);
|
||||
preFile = "/uploads/personal/"
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/none", imageName);
|
||||
preFile = "/uploads/none/"
|
||||
break;
|
||||
}
|
||||
|
||||
fs.writeFile(saveToPath, image.data, (err) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ msg: "Error saving the image" });
|
||||
} else {
|
||||
res.status(201).json({ url: `${preFile}${imageName}` });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
const uploadImages = (images, res, type) => {
|
||||
const maxSize = 15 * 1024 * 1024; // 15MB (example limit)
|
||||
const imageUrls = [];
|
||||
|
||||
if (!Array.isArray(images)) {
|
||||
|
||||
if (images.size > maxSize) {
|
||||
res.status(500)
|
||||
throw new Error("Image file size exceeds the limit")
|
||||
}
|
||||
|
||||
let imageName =
|
||||
date.format("YYYY-MM-DD") +
|
||||
"-Img-" +
|
||||
Math.floor(Math.random() * 900) +
|
||||
100 +
|
||||
images.name;
|
||||
|
||||
let saveToPath
|
||||
let preFile
|
||||
|
||||
switch (type) {
|
||||
case "1":
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/products", imageName);
|
||||
preFile = "/uploads/products/"
|
||||
break;
|
||||
|
||||
case "2":
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/blogs", imageName);
|
||||
preFile = "/uploads/blogs/"
|
||||
break;
|
||||
|
||||
case "3":
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/personal", imageName);
|
||||
preFile = "/uploads/personal/"
|
||||
break;
|
||||
|
||||
case "4":
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/slider", imageName);
|
||||
preFile = "/uploads/slider/"
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/none", imageName);
|
||||
preFile = "/uploads/none/"
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
fs.writeFile(saveToPath, images.data, (err) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ msg: "Error saving the image" });
|
||||
} else {
|
||||
imageUrls.push(`${preFile}${imageName}`)
|
||||
res.status(201).json({ urls: imageUrls });
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
images.forEach(async (image) => {
|
||||
if (image.size > maxSize) {
|
||||
res.status(400)
|
||||
throw new Error("Image file size exceeds the limit")
|
||||
}
|
||||
|
||||
let imageName =
|
||||
date.format("YYYY-MM-DD") +
|
||||
"-Img-" +
|
||||
Math.floor(Math.random() * 900) +
|
||||
100 +
|
||||
image.name;
|
||||
|
||||
let saveToPath
|
||||
let preFile
|
||||
|
||||
|
||||
switch (type) {
|
||||
case "1":
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/products", imageName);
|
||||
preFile = "/uploads/products/"
|
||||
break;
|
||||
|
||||
case "2":
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/blogs", imageName);
|
||||
preFile = "/uploads/blogs/"
|
||||
break;
|
||||
|
||||
case "3":
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/personal", imageName);
|
||||
preFile = "/uploads/personal/"
|
||||
break;
|
||||
|
||||
case "4":
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/slider", imageName);
|
||||
preFile = "/uploads/slider/"
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
// Specify the save location
|
||||
saveToPath = path.join(__dirname, "..", "uploads/none", imageName);
|
||||
preFile = "/uploads/none/"
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
imageUrls.push(`${preFile}${imageName}`);
|
||||
|
||||
|
||||
fs.writeFile(saveToPath, image.data, (err) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
res.status(500)
|
||||
throw new Error("Can't save images")
|
||||
okd = false
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
res.status(201).json({ urls: imageUrls });
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
const deleteImage = (address, res) => {
|
||||
const addressOf = path.join(__dirname, "..", address);
|
||||
|
||||
fs.unlink(addressOf, (err) => {
|
||||
if (err) {
|
||||
console.error("Error removing image:", err);
|
||||
return;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
deleteImage,
|
||||
uploadImage,
|
||||
uploadImages,
|
||||
};
|
||||
@@ -0,0 +1,758 @@
|
||||
module.exports._sr = {
|
||||
fa: {
|
||||
required: {
|
||||
token: 'توکن را وارد کنید',
|
||||
field: 'این فیلد نباید خالی باشد',
|
||||
// developer validations
|
||||
remember_me: 'پارامتر remember_me الزامی است',
|
||||
// registration validations
|
||||
name: 'نام را وارد کنید',
|
||||
first_name: 'نام را وارد کنید',
|
||||
last_name: 'نام خانوادگی را وارد کنید',
|
||||
email: 'ایمیل را وارد کنید',
|
||||
national_code: 'کد ملی الزامی است',
|
||||
email_personal: 'ایمیل شخصی الزامی است',
|
||||
email_company: 'ایمیل کمپانی برای اشخاص حقوقی الزامی است',
|
||||
company_name: 'درصورتی که شخص حقوقی هستید، نام کمپانی را وارد کنید',
|
||||
username: 'نام کاربری را وارد کنید',
|
||||
phone_number: 'شماره تماس را وارد کنید',
|
||||
gender: "جنسیت خود را انتخاب کنید",
|
||||
password: 'پسورد را وارد کنید',
|
||||
birthdate: 'تاریخ تولد را وارد کنید',
|
||||
permissions: 'مقدار دسترسی را وارد کنید',
|
||||
// addressing validations
|
||||
country: 'کشور را وارد کنید',
|
||||
province: 'استان را وارد کنید',
|
||||
city: 'شهر را وارد کنید',
|
||||
address: 'آدرس را وارد کنید',
|
||||
postal_code: 'کد پستی را وارد کنید',
|
||||
plaque: 'پلاک را وارد کنید',
|
||||
receiver_first_name: 'نام گیرنده را وارد کنید',
|
||||
receiver_last_name: 'نام خانوادگی گیرنده را وارد کنید',
|
||||
receiver_mobile: 'شماره موبایل گیرنده را وارد کنید',
|
||||
// global (post - gallery - ...)
|
||||
title: 'عنوان را وارد کنید',
|
||||
caption: 'متن را وارد کنید',
|
||||
description: 'توضیحات را وارد کنید',
|
||||
category: 'دسته بندی را انتخاب کنید',
|
||||
image: 'عکس اجباری است',
|
||||
cover: 'کاور اجباری است',
|
||||
file: 'فایل اجباری است',
|
||||
message: 'پیام را بنویسید',
|
||||
quantity: 'تعداد را وارد کنید',
|
||||
date: 'تاریخ را وارد کنید',
|
||||
reason: 'دلیل را انتخاب کنید',
|
||||
question: 'سوال را بنویسید',
|
||||
answer: 'جواب را بنویسید',
|
||||
price: 'قیمت را وارد کنید',
|
||||
type: 'نوع را انتخاب کنید',
|
||||
discount_code: 'کد تخفیف را وارد کنید',
|
||||
discount_amount: 'مقدار تخفیف را وارد کنید',
|
||||
discount_expire_date: 'تاریخ انقضای کد تخفیف را مشخص کنید',
|
||||
user_id: 'کاربر را انتخاب کنید',
|
||||
video: 'ویدیو اجباری است',
|
||||
setting_name: 'نام تنظیمات اجباری است',
|
||||
setting_value: 'مقدار تنظیمات اجباری است'
|
||||
},
|
||||
format: {
|
||||
phone_number: 'فرمت شماره تماس صحیح نیست',
|
||||
email: 'فرمت ایمیل قابل قبول نیست',
|
||||
number: 'مقدار باید از جنس عدد باشد',
|
||||
boolean: 'مقدار باید از جنس Boolean باشد',
|
||||
image: 'فرمت عکس قابل قبول نیست',
|
||||
video: 'فرمت ویدیو قابل قبول نیست',
|
||||
national_code: 'کد ملی صحیح نیست'
|
||||
},
|
||||
min_char: {
|
||||
min2: 'حداقل 2 کاراکتر',
|
||||
min4: 'حداقل 4 کاراکتر',
|
||||
min8: 'حداقل 8 کاراکتر',
|
||||
min10: 'حداقل 10 کاراکتر',
|
||||
min20: 'حداقل 20 کاراکتر',
|
||||
min30: 'حداقل 30 کاراکتر',
|
||||
min40: 'حداقل 40 کاراکتر',
|
||||
min50: 'حداقل 50 کاراکتر',
|
||||
min60: 'حداقل 60 کاراکتر',
|
||||
min100: 'حداقل 100 کاراکتر',
|
||||
min120: 'حداقل 120 کاراکتر',
|
||||
min150: 'حداقل 150 کاراکتر',
|
||||
min200: 'حداقل 200 کاراکتر',
|
||||
data_size: 'حجم قابل قبول حداقل: ',
|
||||
image_width_size: 'عرض حداقل: ',
|
||||
image_height_size: 'ارتفاع حداقل: '
|
||||
},
|
||||
max_char: {
|
||||
max4: 'حداکثر 4 کاراکتر',
|
||||
max8: 'حداکثر 8 کاراکتر',
|
||||
max10: 'حداکثر 10 کاراکتر',
|
||||
max15: 'حداکثر 15 کاراکتر',
|
||||
max20: 'حداکثر 20 کاراکتر',
|
||||
max30: 'حداکثر 30 کاراکتر',
|
||||
max40: 'حداکثر 40 کاراکتر',
|
||||
max50: 'حداکثر 50 کاراکتر',
|
||||
max60: 'حداکثر 60 کاراکتر',
|
||||
max100: 'حداکثر 100 کاراکتر',
|
||||
max120: 'حداکثر 120 کاراکتر',
|
||||
max150: 'حداکثر 150 کاراکتر',
|
||||
max200: 'حداکثر 200 کاراکتر',
|
||||
data_size: 'حجم قابل قبول حداکثر: ',
|
||||
image_width_size: 'عرض حداکثر: ',
|
||||
image_height_size: 'ارتفاع حداکثر: '
|
||||
},
|
||||
not_found: {
|
||||
user_id: 'کاربری با این مشخصات وجود ندارد',
|
||||
admin_id: 'ادمینی با این مشخصات وجود ندارد',
|
||||
order_id: 'سفارشی با این مشخصات وجود ندارد',
|
||||
item_id: 'موردی با این مشخصات وجود ندارد',
|
||||
password: 'رمز عبور یا آیدی درست نیست',
|
||||
user_not_exist: 'اطلاعات یوزر موجود نیست'
|
||||
},
|
||||
duplicated: {
|
||||
username: 'این نام کاربری از قبل وجود دارد',
|
||||
email: 'این ایمیل از قبل وجود دارد',
|
||||
name: 'نام تکراری است',
|
||||
title: 'عنوان تکراری است',
|
||||
phone_number: 'این شماره تماس از قبل وجود دارد',
|
||||
link: 'این لینک تکراری است',
|
||||
code: ' این کد تکراری است',
|
||||
item: 'این مورد تگراری است',
|
||||
shop: 'این فروشگاه وجود دارد'
|
||||
},
|
||||
response: {
|
||||
permissions: 'شما مجوز کافی ندارید ',
|
||||
logged_in: 'شما وارد سیستم شدید',
|
||||
not_logged_in: 'شما وارد سیستم نشدید',
|
||||
logged_out: 'شما از سیستم خارج شدید',
|
||||
unauthenticated: 'غیرمجاز',
|
||||
recovery_link: 'لینک بازیابی فرستاده شد',
|
||||
success_save: 'با موفقیت ثبت شد',
|
||||
success_remove: 'با موفقیت حذف شد',
|
||||
cart_empty: 'سبد خرید خالی است',
|
||||
already_has_address: 'آدرس قبلا اضافه شده',
|
||||
activation_code: 'کد فعالسازی برای شما ارسال شد',
|
||||
activation_email: 'ایمیل فعال سازی برای شما ارسال شد',
|
||||
expired_reset_link: 'این لینک بازیابی منقضی شده است',
|
||||
email_not_confirmed: 'ابتدا ایمیل خود را تایید کنید،لینک فعال سازی قبلا برای شما فرستاده شده است.',
|
||||
expired_activation_link: 'این لینک فعال سازی منقضی شده است',
|
||||
success_activation: 'اکانت شما با موفقیت فعال شد',
|
||||
passwords_not_match: 'پسورد ها یکی نیست',
|
||||
problem: 'مشکلی پیش آمده، لطفا دوباره تلاش کنید.',
|
||||
latinChar: 'لطفا با حروف لاتین بنویسید',
|
||||
persianChar: 'لطفا با حروف فارسی بنویسید',
|
||||
whiteSpace: 'بین حروف و کلمات نباید فاصله باشد',
|
||||
wrongLoginEmail: 'ایمیل یا رمز ورود اشتباه است',
|
||||
wrongLoginNumber: 'شماره یا رمز ورود اشتباه است',
|
||||
user_not_valid: 'اطلاعات یوزر معتبر نیست',
|
||||
otp: 'کد اشتباه است'
|
||||
},
|
||||
file_types: {
|
||||
jpg: 'فقط فرمت jpg قابل قبول است',
|
||||
png: 'فقط فرمت png قابل قبول است',
|
||||
gif: 'فقط فرمت gif قابل قبول است',
|
||||
pdf: 'فقط فرمت pdf قابل قبول است',
|
||||
txt: 'فقط فرمت txt قابل قبول است',
|
||||
log: 'فقط فرمت log قابل قبول است',
|
||||
mp3: 'فقط فرمت mp3 قابل قبول است',
|
||||
ogg: 'فقط فرمت ogg قابل قبول است',
|
||||
wmv: 'فقط فرمت wmv قابل قبول است',
|
||||
mp4: 'فقط فرمت mp4 قابل قبول است',
|
||||
mov: 'فقط فرمت mov قابل قبول است',
|
||||
mkv: 'فقط فرمت mkv قابل قبول است',
|
||||
flv: 'فقط فرمت flv قابل قبول است'
|
||||
}
|
||||
},
|
||||
en: {
|
||||
required: {
|
||||
token: 'Token is required',
|
||||
field: 'This field is required',
|
||||
// developer validations
|
||||
remember_me: 'Remember_me parameter required',
|
||||
// registration validations
|
||||
name: 'Enter name',
|
||||
first_name: 'Enter first name',
|
||||
last_name: 'Enter last name',
|
||||
national_code: 'National code is required',
|
||||
email: 'Enter email',
|
||||
email_personal: 'Personal email is required',
|
||||
email_company: 'Company email is required for legal entities',
|
||||
company_name: 'Enter company name if you are a legal entity',
|
||||
username: 'Enter username',
|
||||
phone_number: 'Enter phone number',
|
||||
password: 'Enter password',
|
||||
birthdate: 'Enter birthdate',
|
||||
// addressing validations
|
||||
country: 'Enter country',
|
||||
province: 'Enter province',
|
||||
city: 'Enter city',
|
||||
address: 'Enter address',
|
||||
postal_code: 'Enter postal code',
|
||||
plaque: 'Enter plaque',
|
||||
receiver_first_name: 'Enter recipient name',
|
||||
receiver_last_name: 'Enter recipient surname',
|
||||
receiver_mobile: "Enter recipient's mobile number",
|
||||
// global (post - gallery - ...)
|
||||
title: 'Enter title',
|
||||
caption: 'Enter caption',
|
||||
description: 'Enter description',
|
||||
category: 'Select category',
|
||||
image: 'Image is required',
|
||||
cover: 'Cover is required',
|
||||
file: 'File is required',
|
||||
message: 'Write message',
|
||||
quantity: 'Enter quantity',
|
||||
date: 'Enter date',
|
||||
reason: 'Select reason',
|
||||
question: 'Write the question',
|
||||
answer: 'Write the answer',
|
||||
price: 'Enter Price',
|
||||
type: 'Select type',
|
||||
discount_code: 'Enter discount code',
|
||||
discount_amount: 'Enter discount amount',
|
||||
discount_expire_date: 'Specify discount code expiration date',
|
||||
user_id: 'Select user',
|
||||
video: 'Video is required'
|
||||
},
|
||||
format: {
|
||||
phone_number: 'Phone number format in incorrect',
|
||||
email: 'Email format is not correct',
|
||||
number: 'Value must be number',
|
||||
boolean: 'Value must be Boolean',
|
||||
image: 'Photo format is not acceptable',
|
||||
video: 'Video format is not acceptable',
|
||||
national_code: 'National code format is not correct'
|
||||
},
|
||||
min_char: {
|
||||
min2: 'At least 2 characters',
|
||||
min4: 'At least 4 characters',
|
||||
min8: 'At least 8 characters',
|
||||
min10: 'At least 10 characters',
|
||||
min20: 'At least 20 characters',
|
||||
min30: 'At least 30 characters',
|
||||
min40: 'At least 40 characters',
|
||||
min50: 'At least 50 characters',
|
||||
min60: 'At least 60 characters',
|
||||
min100: 'At least 100 characters',
|
||||
min120: 'At least 120 characters',
|
||||
min150: 'At least 150 characters',
|
||||
min200: 'At least 200 characters',
|
||||
data_size: 'Acceptable minimum size: ',
|
||||
image_width_size: 'Minimum width: ',
|
||||
image_height_size: 'Minimum height: '
|
||||
},
|
||||
max_char: {
|
||||
max4: 'Maximum 4 characters',
|
||||
max8: 'Maximum 8 characters',
|
||||
max10: 'Maximum 10 characters',
|
||||
max15: 'Maximum 15 characters',
|
||||
max20: 'Maximum 20 characters',
|
||||
max30: 'Maximum 30 characters',
|
||||
max40: 'Maximum 40 characters',
|
||||
max50: 'Maximum 50 characters',
|
||||
max60: 'Maximum 60 characters',
|
||||
max100: 'Maximum 100 characters',
|
||||
max120: 'Maximum 120 characters',
|
||||
max150: 'Maximum 150 characters',
|
||||
max200: 'Maximum 200 characters',
|
||||
data_size: 'Maximum acceptable size: ',
|
||||
image_width_size: 'Maximum width: ',
|
||||
image_height_size: 'Maximum height: '
|
||||
},
|
||||
not_found: {
|
||||
user_id: 'There is no user with this profile',
|
||||
admin_id: 'There is no admin with this profile',
|
||||
order_id: 'There is no order with this profile',
|
||||
item_id: 'There is no item with this specification',
|
||||
password: 'Password or ID is incorrect'
|
||||
},
|
||||
duplicated: {
|
||||
username: 'This username already exists',
|
||||
email: 'This email already exists',
|
||||
name: 'Name already exists',
|
||||
title: 'Title already exists',
|
||||
phone_number: 'Phone number already exists'
|
||||
},
|
||||
response: {
|
||||
logged_in: 'You are logged in',
|
||||
not_logged_in: 'You are not logged in',
|
||||
logged_out: 'You are logged out',
|
||||
unauthenticated: 'unauthenticated',
|
||||
recovery_link: 'Recovery link sent',
|
||||
success_save: 'Successfully saved',
|
||||
success_remove: 'Successfully removed',
|
||||
cart_empty: 'Cart is empty',
|
||||
already_has_address: 'Already has address',
|
||||
activation_code: 'Activation code sent to you',
|
||||
activation_email: 'Activation email sent to you',
|
||||
expired_reset_link: 'The current reset pass link has been expired',
|
||||
email_not_confirmed: 'Confirm your email first, the activation link has already been sent to you.',
|
||||
expired_activation_link: 'This activation link has expired',
|
||||
success_activation: 'Your account has been successfully activated',
|
||||
passwords_not_match: 'Passwords are not the same',
|
||||
problem: 'There is a problem, please try again.',
|
||||
latinChar: 'Please write in Latin letters',
|
||||
persianChar: 'Please write in Persian letters',
|
||||
whiteSpace: 'There should be no space between letters and words'
|
||||
},
|
||||
file_types: {
|
||||
jpg: 'Only jpg format is acceptable',
|
||||
png: 'Only png format is acceptable',
|
||||
gif: 'Only gif format is acceptable',
|
||||
pdf: 'Only pdf format is acceptable',
|
||||
txt: 'Only txt format is acceptable',
|
||||
log: 'Only log format is acceptable',
|
||||
mp3: 'Only mp3 format is acceptable',
|
||||
ogg: 'Only ogg format is acceptable',
|
||||
wmv: 'Only wmv format is acceptable',
|
||||
mp4: 'Only mp4 format is acceptable',
|
||||
mov: 'Only mov format is acceptable',
|
||||
mkv: 'Only mkv format is acceptable',
|
||||
flv: 'Only flv format is acceptable'
|
||||
}
|
||||
},
|
||||
de: {
|
||||
required: {
|
||||
token: 'Token is required',
|
||||
field: 'This field is required',
|
||||
// developer validations
|
||||
remember_me: 'Remember_me-Parameter erforderlich',
|
||||
// registration validations
|
||||
name: 'Name eingeben',
|
||||
first_name: 'Name eingeben',
|
||||
last_name: 'Nachnamen eingeben',
|
||||
national_code: 'Nationaler Code ist erforderlich',
|
||||
email: 'Email eingeben',
|
||||
email_personal: 'Persönliche E-Mail ist erforderlich',
|
||||
email_company: 'Für juristische Personen ist eine Unternehmens-E-Mail erforderlich',
|
||||
company_name: 'Geben Sie den Firmennamen ein, wenn Sie eine juristische Person sind',
|
||||
username: 'Geben Sie den Benutzernamen ein',
|
||||
phone_number: 'Telefonnummer eingeben',
|
||||
password: 'Passwort eingeben',
|
||||
birthdate: 'Enter birthdate',
|
||||
// addressing validations
|
||||
country: 'Land eingeben',
|
||||
province: 'Stadt betreten',
|
||||
city: 'Stadt betreten',
|
||||
address: 'Adresse eingeben',
|
||||
postal_code: 'Postleitzahl eingeben',
|
||||
plaque: 'Plakette eingeben',
|
||||
receiver_first_name: 'Empfängername eingeben',
|
||||
receiver_last_name: 'Nachname des Empfängers eingeben',
|
||||
receiver_mobile: 'Handynummer des Empfängers eingebenr',
|
||||
// global (post - gallery - ...)
|
||||
title: 'Titel eingeben',
|
||||
caption: 'Beschriftung eingeben',
|
||||
description: 'Beschreibung eingeben',
|
||||
category: 'Kategorie wählen',
|
||||
image: 'Bild ist erforderlich',
|
||||
cover: 'Bild ist erforderlich Abdeckung ist erforderlich',
|
||||
file: 'Datei ist erforderlich',
|
||||
message: 'Nachricht schreiben',
|
||||
quantity: 'Menge eingeben',
|
||||
date: 'Enter date',
|
||||
reason: 'Grund auswählen',
|
||||
question: 'Schreibe die Frage',
|
||||
answer: 'Schreibe die Antwort',
|
||||
price: 'Enter Price',
|
||||
type: 'Select type',
|
||||
discount_code: 'Enter discount code',
|
||||
discount_amount: 'Enter discount amount',
|
||||
discount_expire_date: 'Specify discount code expiration date',
|
||||
user_id: 'Select user',
|
||||
video: 'Video is required'
|
||||
},
|
||||
format: {
|
||||
phone_number: 'Telefonnummernformat falsch',
|
||||
email: 'E-Mail-Format nicht korrekt',
|
||||
number: 'Wert muss Nummer sein',
|
||||
boolean: 'Wert muss Boolescher Wert sein',
|
||||
image: 'Photo format is not acceptable',
|
||||
video: 'Video format is not acceptable',
|
||||
national_code: 'Nationales Codeformat ist nicht korrekt'
|
||||
},
|
||||
min_char: {
|
||||
min2: 'Mindestens 2 Zeichen',
|
||||
min4: 'Mindestens 4 Zeichen',
|
||||
min8: 'Mindestens 8 Zeichen',
|
||||
min10: 'Mindestens 10 Zeichen',
|
||||
min20: 'Mindestens 20 Zeichen',
|
||||
min30: 'Mindestens 30 Zeichen',
|
||||
min40: 'Mindestens 40 Zeichen',
|
||||
min50: 'Mindestens 50 Zeichen',
|
||||
min60: 'Mindestens 60 Zeichen',
|
||||
min100: 'Mindestens 100 Zeichen',
|
||||
min120: 'Mindestens 120 Zeichen',
|
||||
min150: 'Mindestens 150 Zeichen',
|
||||
min200: 'Mindestens 200 Zeichen',
|
||||
data_size: 'Akzeptable Mindestgröße: ',
|
||||
image_width_size: 'Mindestbreite: ',
|
||||
image_height_size: 'Mindesthöhe: '
|
||||
},
|
||||
max_char: {
|
||||
max4: 'Maximal 4 Zeichen',
|
||||
max8: 'Maximal 8 Zeichen',
|
||||
max10: 'Maximal 10 Zeichen',
|
||||
max15: 'Maximal 15 Zeichen',
|
||||
max20: 'Maximal 20 Zeichen',
|
||||
max30: 'Maximal 30 Zeichen',
|
||||
max40: 'Maximal 40 Zeichen',
|
||||
max50: 'Maximal 50 Zeichen',
|
||||
max60: 'Maximal 60 Zeichen',
|
||||
max100: 'Maximal 100 Zeichen',
|
||||
max120: 'Maximal 120 Zeichen',
|
||||
max150: 'Maximal 150 Zeichen',
|
||||
max200: 'Maximal 200 Zeichen',
|
||||
data_size: 'Maximal zulässige Größe: ',
|
||||
image_width_size: 'Maximale Breite: ',
|
||||
image_height_size: 'Maximale Höhe: '
|
||||
},
|
||||
not_found: {
|
||||
user_id: 'Es gibt keinen Benutzer mit diesem Profil',
|
||||
admin_id: 'Es gibt keinen Administrator mit diesem Profil',
|
||||
order_id: 'Es gibt keine Bestellung mit diesem Profil',
|
||||
item_id: 'Es gibt keinen Artikel mit dieser Spezifikation',
|
||||
password: 'Passwort oder ID ist falsch'
|
||||
},
|
||||
duplicated: {
|
||||
username: 'Dieser Benutzername existiert bereits',
|
||||
email: 'Diese E-Mail existiert bereits',
|
||||
name: 'Name ist doppelt',
|
||||
title: 'Titel ist doppelt',
|
||||
phone_number: 'Phone number already exists'
|
||||
},
|
||||
response: {
|
||||
logged_in: 'Sie sind angemeldet',
|
||||
not_logged_in: 'Sie sind nicht angemeldet',
|
||||
logged_out: 'Sie sind abgemeldet',
|
||||
unauthenticated: 'nicht authentifiziert',
|
||||
recovery_link: 'Wiederherstellungslink gesendet',
|
||||
success_save: 'Erfolgreich gespeichert',
|
||||
success_remove: 'Erfolgreich entfernt',
|
||||
cart_empty: 'Warenkorb ist leer',
|
||||
ready_has_address: 'Hat bereits Adresse',
|
||||
activation_code: 'Activation code sent to you',
|
||||
activation_email: 'Activation email sent to you',
|
||||
expired_reset_link: 'Der aktuelle Reset-Pass-Link ist abgelaufen',
|
||||
email_not_confirmed: 'Bestätigen Sie zuerst Ihre E-Mail, der Aktivierungslink wurde bereits an Sie gesendet.',
|
||||
expired_activation_link: 'Dieser Aktivierungslink ist abgelaufen',
|
||||
success_activation: 'Ihr Konto wurde erfolgreich aktiviert',
|
||||
passwords_not_match: 'Passwörter sind nicht dasselbe',
|
||||
problem: 'Es gibt ein Problem, bitte versuchen Sie es erneut.',
|
||||
latinChar: 'Please write in Latin letters',
|
||||
persianChar: 'Please write in Persian letters',
|
||||
whiteSpace: 'There should be no space between letters and words'
|
||||
},
|
||||
file_types: {
|
||||
jpg: 'Nur das jpg-Format ist akzeptabel',
|
||||
png: 'Nur das png-Format ist akzeptabel',
|
||||
gif: 'Nur das gif-Format ist akzeptabel',
|
||||
pdf: 'Nur das PDF-Format ist akzeptabel',
|
||||
txt: 'Nur das txt-Format ist akzeptabel',
|
||||
log: 'Nur das log-Format ist akzeptabel',
|
||||
mp3: 'Nur das mp3-Format ist akzeptabel',
|
||||
ogg: 'Nur das ogg-Format ist akzeptabel',
|
||||
wmv: 'Nur das wmv-Format ist akzeptabel',
|
||||
mp4: 'Nur das mp4-Format ist akzeptabel',
|
||||
mov: 'Nur das mov-Format ist akzeptabel',
|
||||
mkv: 'Nur das mkv-Format ist akzeptabel',
|
||||
flv: 'Nur das flv-Format ist akzeptabel'
|
||||
}
|
||||
},
|
||||
tr: {
|
||||
required: {
|
||||
token: 'Token is required',
|
||||
field: 'This field is required',
|
||||
// geliştirici doğrulamaları
|
||||
Remember_me: 'Remember_me parametresi gerekli',
|
||||
// kayıt doğrulamaları
|
||||
name: 'Adı girin',
|
||||
first_name: 'Adı girin',
|
||||
last_name: 'Soyadı girin',
|
||||
national_code: 'Nationaler Kodu erforderlich',
|
||||
email: 'E-posta girin',
|
||||
email_personal: 'Kişisel e-posta gereklidir',
|
||||
email_company: 'Tüzel kişiler için şirket e-postası gereklidir',
|
||||
company_name: 'Tüzel kişiyseniz şirket adını girin',
|
||||
username: 'Kullanıcı adını girin',
|
||||
phone_number: 'Telefon numarasını girin',
|
||||
password: 'Şifre girin',
|
||||
birthdate: 'Enter birthdate',
|
||||
// doğrulamaları adresleme
|
||||
country: 'Ülke girin',
|
||||
province: 'İl girin',
|
||||
city: 'Şehir girin',
|
||||
address: 'Adres girin',
|
||||
postal_code: 'Posta kodunu girin',
|
||||
plaque: 'Plak girin',
|
||||
receiver_first_name: 'Alıcı adını girin',
|
||||
receiver_last_name: 'Alıcının soyadını girin',
|
||||
receiver_mobile: 'Alıcının cep telefonu numarasını girin',
|
||||
// global (post - galeri - ...)
|
||||
title: 'Başlığı girin',
|
||||
caption: 'Başlık girin',
|
||||
description: 'Açıklama girin',
|
||||
category: 'Kategori seçin',
|
||||
image: 'Resim gerekli',
|
||||
cover: 'Kapak gereklidir',
|
||||
file: 'Dosya gerekli',
|
||||
message: 'Mesaj yaz',
|
||||
quantity: 'Miktar girin',
|
||||
date: 'Enter date',
|
||||
reason: 'Nedeni seçin',
|
||||
question: 'Soruyu yazın',
|
||||
answer: 'Cevabı yaz',
|
||||
price: 'Enter Price',
|
||||
type: 'Select type',
|
||||
discount_code: 'Enter discount code',
|
||||
discount_amount: 'Enter discount amount',
|
||||
discount_expire_date: 'Specify discount code expiration date',
|
||||
user_id: 'Select user',
|
||||
video: 'Video is required'
|
||||
},
|
||||
format: {
|
||||
phone_number: 'Telefon numarası biçimi yanlış',
|
||||
email: 'E-posta formatı doğru değil',
|
||||
number: 'Değer sayı olmalıdır',
|
||||
boolean: 'Değer Boole olmalıdır',
|
||||
image: 'Photo format is not acceptable',
|
||||
video: 'Video format is not acceptable',
|
||||
national_code: 'Ulusal kod formatı doğru değil'
|
||||
},
|
||||
min_char: {
|
||||
min2: 'En az 2 karakter',
|
||||
min4: 'En az 4 karakter',
|
||||
min8: 'En az 8 karakter',
|
||||
min10: 'En az 10 karakter',
|
||||
min20: 'En az 20 karakter',
|
||||
min30: 'En az 30 karakter',
|
||||
min40: 'En az 40 karakter',
|
||||
min50: 'En az 50 karakter',
|
||||
min60: 'En az 60 karakter',
|
||||
min100: 'En az 100 karakter',
|
||||
min120: 'En az 120 karakter',
|
||||
min150: 'En az 150 karakter',
|
||||
min200: 'En az 200 karakter',
|
||||
data_size: 'Kabul edilebilir minimum boyut: ',
|
||||
image_width_size: 'Minimum genişlik: ',
|
||||
image_height_size: 'Minimum yükseklik: '
|
||||
},
|
||||
max_char: {
|
||||
max4: 'Maksimum 4 karakter',
|
||||
max8: 'Maksimum 8 karakter',
|
||||
max10: 'Maksimum 10 karakter',
|
||||
max15: 'Maksimum 15 karakter',
|
||||
max20: 'Maksimum 20 karakter',
|
||||
max30: 'Maksimum 30 karakter',
|
||||
max40: 'Maksimum 40 karakter',
|
||||
max50: 'Maksimum 50 karakter',
|
||||
max60: 'Maksimum 60 karakter',
|
||||
max100: 'Maksimum 100 karakter',
|
||||
max120: 'Maksimum 120 karakter',
|
||||
max150: 'Maksimum 150 karakter',
|
||||
max200: 'Maksimum 200 karakter',
|
||||
data_size: 'Kabul edilebilir maksimum boyut: ',
|
||||
image_width_size: 'Maksimum genişlik: ',
|
||||
image_height_size: 'Maksimum yükseklik: '
|
||||
},
|
||||
not_found: {
|
||||
user_id: 'Bu profile sahip kullanıcı yok',
|
||||
admin_id: 'Bu profile sahip yönetici yok',
|
||||
order_id: 'Bu profilde sipariş yok',
|
||||
item_id: 'Bu spesifikasyona sahip hiçbir öğe yok',
|
||||
password: 'Şifre veya kimlik yanlış'
|
||||
},
|
||||
duplicated: {
|
||||
username: 'Bu kullanıcı adı zaten mevcut',
|
||||
email: 'Bu email zaten var',
|
||||
name: 'Ad çift',
|
||||
title: 'Başlık yineleniyor',
|
||||
phone_number: 'Phone number already exists'
|
||||
},
|
||||
response: {
|
||||
logged_in: 'Giriş yaptınız',
|
||||
not_logged_in: 'Giriş yapmadınız',
|
||||
logged_out: 'Çıkış yaptınız',
|
||||
unauthenticated: 'unauthenticated',
|
||||
recovery_link: 'Kurtarma bağlantısı gönderildi',
|
||||
success_save: 'Başarıyla kaydedildi',
|
||||
success_remove: 'Başarıyla kaldırıldı',
|
||||
cart_empty: 'Sepet boş',
|
||||
already_has_address: 'Zaten adresi var',
|
||||
activation_code: 'Activation code sent to you',
|
||||
activation_email: 'Activation email sent to you',
|
||||
expired_reset_link: 'Mevcut sıfırlama geçiş bağlantısının süresi doldu',
|
||||
email_not_confirmed: 'Önce e-postanızı onaylayın, aktivasyon bağlantısı size zaten gönderildi.',
|
||||
expired_activation_link: 'Bu aktivasyon bağlantısının süresi doldu',
|
||||
success_activation: 'Hesabınız başarıyla etkinleştirildi',
|
||||
passwords_not_match: 'Şifreler aynı değil',
|
||||
problem: 'Bir sorun var, lütfen tekrar deneyin.',
|
||||
latinChar: 'Please write in Latin letters',
|
||||
persianChar: 'Please write in Persian letters',
|
||||
whiteSpace: 'There should be no space between letters and words'
|
||||
},
|
||||
file_types: {
|
||||
jpg: 'Yalnızca jpg formatı kabul edilebilir',
|
||||
png: 'Sadece png formatı kabul edilebilir',
|
||||
gif: 'Yalnızca gif formatı kabul edilebilir',
|
||||
pdf: 'Yalnızca pdf formatı kabul edilebilir',
|
||||
txt: 'Yalnızca txt formatı kabul edilebilir',
|
||||
log: 'Yalnızca log formatı kabul edilebilir',
|
||||
mp3: 'Yalnızca mp3 formatı kabul edilebilir',
|
||||
ogg: 'Yalnızca ogg formatı kabul edilebilir',
|
||||
wmv: 'Yalnızca wmv formatı kabul edilebilir',
|
||||
mp4: 'Yalnızca mp4 formatı kabul edilebilir',
|
||||
mov: 'Yalnızca mov formatı kabul edilebilir',
|
||||
mkv: 'Yalnızca mkv formatı kabul edilebilir',
|
||||
flv: 'Yalnızca flv biçimi kabul edilebilir'
|
||||
}
|
||||
},
|
||||
it: {
|
||||
required: {
|
||||
token: 'Token is required',
|
||||
field: 'This field is required',
|
||||
// convalide dello sviluppatore
|
||||
Remember_me: 'Remember_me parameter required',
|
||||
// convalide della registrazione
|
||||
name: 'Inserisci nome',
|
||||
first_name: 'Inserisci nome',
|
||||
last_name: 'Inserisci il cognome',
|
||||
national_code: 'Il codice Nationaler è comune',
|
||||
email: 'Enter email',
|
||||
email_personal: "L'email personale è obbligatoria",
|
||||
email_company: "L'email aziendale è obbligatoria per le persone giuridiche",
|
||||
company_name: "Inserisci il nome dell'azienda se sei una persona giuridica",
|
||||
username: 'Inserisci nome utente',
|
||||
phone_number: 'Inserisci numero di telefono',
|
||||
password: 'Inserisci password',
|
||||
birthdate: 'Enter birthdate',
|
||||
// indirizzamento delle convalide
|
||||
country: 'Inserisci paese',
|
||||
province: 'Inserisci provincia',
|
||||
city: 'Inserisci città',
|
||||
address: 'Inserisci indirizzo',
|
||||
postal_code: 'Inserisci codice postale',
|
||||
plaque: 'Inserisci targa',
|
||||
receiver_first_name: 'Inserisci il nome del destinatario',
|
||||
receiver_last_name: 'Inserisci il cognome del destinatario',
|
||||
receiver_mobile: 'Inserisci il numero di cellulare del destinatario',
|
||||
// globale (post - gallery - ...)
|
||||
title: 'Inserisci titolo',
|
||||
caption: 'Inserisci didascalia',
|
||||
description: 'Inserisci descrizione',
|
||||
category: 'Seleziona categoria',
|
||||
image: "L'immagine è obbligatoria",
|
||||
cover: 'Cover is required',
|
||||
file: 'Il file è obbligatorio',
|
||||
message: 'Scrivi messaggio',
|
||||
quantity: 'Inserisci quantità',
|
||||
date: 'Enter date',
|
||||
reason: 'Seleziona motivo',
|
||||
question: 'Scrivi la domanda',
|
||||
answer: 'Scrivi la risposta',
|
||||
price: 'Enter Price',
|
||||
type: 'Select type',
|
||||
discount_code: 'Enter discount code',
|
||||
discount_amount: 'Enter discount amount',
|
||||
discount_expire_date: 'Specify discount code expiration date',
|
||||
user_id: 'Select user',
|
||||
video: 'Video is required'
|
||||
},
|
||||
format: {
|
||||
phone_number: 'Formato del numero di telefono non corretto',
|
||||
email: 'Formato email non corretto',
|
||||
number: 'Il valore deve essere un numero',
|
||||
boolean: 'Il valore deve essere booleano',
|
||||
image: 'Photo format is not acceptable',
|
||||
video: 'Video format is not acceptable',
|
||||
national_code: 'Il formato del codice nazionale non è corretto'
|
||||
},
|
||||
min_char: {
|
||||
min2: 'Almeno 2 caratteri',
|
||||
min4: 'Almeno 4 caratteri',
|
||||
min8: 'Almeno 8 caratteri',
|
||||
min10: 'Almeno 10 caratteri',
|
||||
min20: 'Almeno 20 caratteri',
|
||||
min30: 'Almeno 30 caratteri',
|
||||
min40: 'Almeno 40 caratteri',
|
||||
min50: 'Almeno 50 caratteri',
|
||||
min60: 'Almeno 60 caratteri',
|
||||
min100: 'Almeno 100 caratteri',
|
||||
min120: 'Almeno 120 caratteri',
|
||||
min150: 'Almeno 150 caratteri',
|
||||
min200: 'Almeno 200 caratteri',
|
||||
data_size: 'Dimensione minima accettabile: ',
|
||||
image_width_size: 'Larghezza minima: ',
|
||||
image_height_size: 'Altezza minima: '
|
||||
},
|
||||
max_char: {
|
||||
max4: 'Massimo 4 caratteri',
|
||||
max8: 'Massimo 8 caratteri',
|
||||
max10: 'Massimo 10 caratteri',
|
||||
max15: 'Massimo 15 caratteri',
|
||||
max20: 'Massimo 20 caratteri',
|
||||
max30: 'Massimo 30 caratteri',
|
||||
max40: 'Massimo 40 caratteri',
|
||||
max50: 'Massimo 50 caratteri',
|
||||
max60: 'Massimo 60 caratteri',
|
||||
max100: 'Massimo 100 caratteri',
|
||||
max120: 'Massimo 120 caratteri',
|
||||
max150: 'Massimo 150 caratteri',
|
||||
max200: 'Massimo 200 caratteri',
|
||||
data_size: 'Dimensione massima accettabile: ',
|
||||
image_width_size: 'Larghezza massima: ',
|
||||
image_height_size: 'Altezza massima: '
|
||||
},
|
||||
not_found: {
|
||||
user_id: 'Nessun utente con questo profilo',
|
||||
admin_id: 'Nessun amministratore con questo profilo',
|
||||
order_id: 'Nessun ordine con questo profilo',
|
||||
item_id: 'Nessun articolo con questa specifica',
|
||||
password: "La password o l'ID non sono corretti"
|
||||
},
|
||||
duplicated: {
|
||||
username: 'Questo nome utente esiste già',
|
||||
email: 'Questa email esiste già',
|
||||
name: 'Il nome è duplicato',
|
||||
title: 'Il titolo è duplicato',
|
||||
phone_number: 'Phone number already exists'
|
||||
},
|
||||
response: {
|
||||
logged_in: "Hai effettuato l'accesso",
|
||||
not_logged_in: 'Non sei loggato',
|
||||
logged_out: 'Sei disconnesso',
|
||||
unauthenticated: 'unauthenticated',
|
||||
recovery_link: 'Link di ripristino inviato',
|
||||
success_save: 'Salvataggio riuscito',
|
||||
success_remove: 'Rimosso con successo',
|
||||
cart_empty: 'Il carrello è vuoto',
|
||||
already_has_address: 'Ha già indirizzo',
|
||||
activation_code: 'Activation code sent to you',
|
||||
activation_email: 'Activation email sent to you',
|
||||
expired_reset_link: "L'attuale link del passaggio di reimpostazione è scaduto",
|
||||
email_not_confirmed: 'Conferma prima la tua email, il link di attivazione ti è già stato inviato.',
|
||||
expired_activation_link: 'Questo link di attivazione è scaduto',
|
||||
success_activation: 'Il tuo account è stato attivato con successo',
|
||||
passwords_not_match: 'Le password non sono le stesse',
|
||||
problem: 'Si è verificato un problema, riprova.',
|
||||
latinChar: 'Please write in Latin letters',
|
||||
persianChar: 'Please write in Persian letters',
|
||||
whiteSpace: 'There should be no space between letters and words'
|
||||
},
|
||||
file_types: {
|
||||
jpg: 'È accettabile solo il formato jpg',
|
||||
png: 'È accettabile solo il formato png',
|
||||
gif: 'È accettabile solo il formato GIF',
|
||||
pdf: 'È accettabile solo il formato pdf',
|
||||
txt: 'È accettabile solo il formato txt',
|
||||
log: 'È accettabile solo il formato log',
|
||||
mp3: 'È accettabile solo il formato mp3',
|
||||
ogg: 'È accettabile solo il formato ogg',
|
||||
wmv: 'È accettabile solo il formato wmv',
|
||||
mp4: 'È accettabile solo il formato mp4',
|
||||
mov: 'È accettabile solo il formato mov',
|
||||
mkv: 'È accettabile solo il formato mkv',
|
||||
flv: 'È accettabile solo il formato flv'
|
||||
}
|
||||
},
|
||||
supportedImageFormats: ['jpg', 'jpeg', 'png', 'svg', 'svg+xml', 'webp'],
|
||||
supportedVideoFormats: ['mp4', 'wmv']
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
const express = require("express");
|
||||
const errorHandler = require("./middleware/errorHandler");
|
||||
const db = require("./config/dbConnectoin");
|
||||
const fileUpload = require("express-fileupload");
|
||||
const path = require("path");
|
||||
const swiftly = require("swiftly-tools");
|
||||
const cron = require("cron").CronJob;
|
||||
const { expressSharp, FsAdapter } = require('express-sharp')
|
||||
const { functions } = require("./controllers/Users");
|
||||
const { autoFetch } = require('express-route-detector')
|
||||
var cors = require('cors')
|
||||
require("dotenv").config();
|
||||
|
||||
// Init database
|
||||
db();
|
||||
|
||||
const app = express();
|
||||
const port = process.env.PORT || 6060;
|
||||
|
||||
// Middleware
|
||||
app.use(cors())
|
||||
app.use(fileUpload());
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: false }));
|
||||
app.use(swiftly.middleware.hsts)
|
||||
app.use(swiftly.middleware.sign("Mr Swift"))
|
||||
|
||||
// The scheduled job
|
||||
const job = new cron("0 0 * * *", function () {
|
||||
functions.deleteUsers();
|
||||
});
|
||||
job.start();
|
||||
|
||||
// Routes
|
||||
app.use(autoFetch(express))
|
||||
app.use('/uploads', expressSharp({
|
||||
imageAdapter: new FsAdapter(path.join(__dirname, 'uploads')),
|
||||
}));
|
||||
|
||||
//Error handler
|
||||
app.use(errorHandler.run);
|
||||
|
||||
//Init site data
|
||||
Site.findOne({ profile: "main" }).then(async (data) => {
|
||||
if (!data) {
|
||||
await Site.create({
|
||||
profile: "main",
|
||||
});
|
||||
}
|
||||
}).catch(async (err) => {
|
||||
await Site.create({
|
||||
profile: "main",
|
||||
});
|
||||
})
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server runing on port: ${port}`);
|
||||
});
|
||||
@@ -0,0 +1,157 @@
|
||||
const createOrder = [
|
||||
asyncHandler(async (req, res) => {
|
||||
const {
|
||||
discountCode,
|
||||
} = req.body;
|
||||
|
||||
const userID = req.user.id;
|
||||
|
||||
const userData = await User.findById(req.user.id)
|
||||
if (userData.cart.length <= 0) {
|
||||
res.status(400)
|
||||
throw new Error("سبد خرید خالی است")
|
||||
}
|
||||
const shippingAddress = userData.state + " - " + userData.city + " - " + userData.address + " - " + userData.postCode + " - " + userData.phoneNumber
|
||||
const orderDate = new Date()
|
||||
const data = {
|
||||
userID,
|
||||
totalAmount: 0,
|
||||
shippingAddress,
|
||||
orderDate,
|
||||
status: "Pending",
|
||||
};
|
||||
|
||||
let myPromise = new Promise(async function (myResolve, myReject) {
|
||||
try {
|
||||
let products = []
|
||||
// Use Promise.all to wait for all asynchronous operations to complete
|
||||
await Promise.all(
|
||||
userData.cart.map(async (product) => {
|
||||
const pd = await Product.findById(product.product);
|
||||
if (pd.specialPrice) {
|
||||
data.totalAmount = pd.specialPrice * product.quantity + data.totalAmount;
|
||||
} else {
|
||||
data.totalAmount = pd.price * product.quantity + data.totalAmount;
|
||||
}
|
||||
products.push({ product: pd.id, quantity: product.quantity, price: pd.price, specialPrice: pd.specialPrice })
|
||||
})
|
||||
);
|
||||
|
||||
data.products = products
|
||||
// Resolve the main promise after all asynchronous operations are finished
|
||||
myResolve(data);
|
||||
} catch (error) {
|
||||
// Reject the promise if an error occurs
|
||||
myReject(error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (discountCode) {
|
||||
const discount = await Discount.findOne({ discountCode });
|
||||
if (!discount) {
|
||||
res.status(404);
|
||||
throw new Error(_sr.fa.not_found.item_id);
|
||||
}
|
||||
if (discount.expirationDate <= Date.now()) {
|
||||
res.status(404);
|
||||
throw new Error("این کد منقضی شده");
|
||||
}
|
||||
if (discount.use >= usageLimit) {
|
||||
res.status(404);
|
||||
throw new Error("این کد منقضی شده");
|
||||
}
|
||||
if (discount.usedBy.length > 0) {
|
||||
let thisUser = true;
|
||||
discount.usedBy.forEach((user) => {
|
||||
if (user === userID) {
|
||||
thisUser = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (thisUser) {
|
||||
res.status(404);
|
||||
throw new Error("این کد منقضی شده");
|
||||
}
|
||||
}
|
||||
if (discount.applicableProducts.length > 0) {
|
||||
let thisProducts = true;
|
||||
discount.applicableProducts.forEach((product) => {
|
||||
userData.cart.forEach((productX) => {
|
||||
if (product === productX) {
|
||||
thisProducts = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
if (thisProducts) {
|
||||
res.status(404);
|
||||
throw new Error("این کد منقضی شده");
|
||||
}
|
||||
}
|
||||
switch (discount.type) {
|
||||
case "f":
|
||||
data.priceWithDiscount = data.totalAmount - discount.amount;
|
||||
|
||||
break;
|
||||
|
||||
case "p":
|
||||
const darsad = discount.amount / 100;
|
||||
|
||||
const manfi = data.totalAmount * darsad;
|
||||
|
||||
data.priceWithDiscount = data.totalAmount - manfi;
|
||||
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
data.priceWithDiscount = data.totalAmount
|
||||
}
|
||||
|
||||
var order
|
||||
myPromise.then(async () => {
|
||||
order = await Order.create(data);
|
||||
let findOrder = await Order.findById(order._id).populate('products.product', ' title uid').populate('userID', sp.select.userCustom)
|
||||
|
||||
userData.cart.map(async (productData) => {
|
||||
var pusher = productData
|
||||
pusher.status = "Pending"
|
||||
pusher.date = Date.now()
|
||||
pusher.orderDate = Date.now()
|
||||
const product = await Product.findById(productData.product)
|
||||
pusher.price = product?.specialPrice || product.price
|
||||
await Product.findByIdAndUpdate(
|
||||
productData.product, {
|
||||
order: product?.order + 1 || 1
|
||||
}
|
||||
)
|
||||
|
||||
await Shop.findByIdAndUpdate(
|
||||
product.shopID,
|
||||
{
|
||||
$push: { pendingProductss: pusher },
|
||||
},
|
||||
{ new: true }
|
||||
);
|
||||
|
||||
|
||||
});
|
||||
|
||||
const emailInfo = await Email.findOne({ status: data.status });
|
||||
const smsInfo = await Sms.findOne({ status: data.status });
|
||||
|
||||
if (emailInfo.send) {
|
||||
// email(userData.email, "Asan Market Order", emailInfo.body, emailInfo.html);
|
||||
}
|
||||
if (smsInfo.send) {
|
||||
await sms(userData.phoneNumber, `سفارش شما با ایدیه ${findOrder?._id} در آسان مارکت ثبت شد و در انتظار پرداخت میباشد`);
|
||||
}
|
||||
|
||||
userData.cart = []
|
||||
userData.orders.push(order)
|
||||
userData.save()
|
||||
res.status(201).json(findOrder);
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
]
|
||||
@@ -0,0 +1,3 @@
|
||||
# Asanmarket
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Asanmarket
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
# Asanmarket
|
||||
@@ -0,0 +1,3 @@
|
||||
# Asanmarket
|
||||
|
||||
|
||||
Reference in New Issue
Block a user