feat: Improve code organization
This commit is contained in:
10
src/apps/index.js
Normal file
10
src/apps/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
|
||||
const private = require('./private');
|
||||
const public = require('./public');
|
||||
|
||||
app.use( public );
|
||||
app.use( private );
|
||||
|
||||
module.exports = app;
|
||||
37
src/apps/private/index.js
Normal file
37
src/apps/private/index.js
Normal file
@@ -0,0 +1,37 @@
|
||||
'use strict';
|
||||
const { ROOT_PATH , LIB_PATH } = process.env;
|
||||
|
||||
/// Router instance
|
||||
const router = require('express').Router();
|
||||
const jwtValidator = require( `${ROOT_PATH}/${LIB_PATH}/jwtValidator.js` );
|
||||
|
||||
const loadAttachments = require('./load-attachments/routes.js');
|
||||
const loads = require('./loads/routes.js');
|
||||
const users = require('./users/routes.js');
|
||||
|
||||
router.use( jwtValidator.middleware );
|
||||
|
||||
router.use('/load-attachments', loadAttachments );
|
||||
router.use('/loads', loads);
|
||||
router.use('/users', users);
|
||||
|
||||
/*
|
||||
router.use('/orders', test);
|
||||
router.use('/companies', test);
|
||||
router.use('/vehicles', test);
|
||||
router.use('/mailer', test);
|
||||
router.use('/authmanagement', test);
|
||||
router.use('/memberships', test);
|
||||
router.use('/checkAccount', test);
|
||||
router.use('/proposals', test);
|
||||
router.use('/bootresolvers', test);
|
||||
router.use('/budgets', test);
|
||||
router.use('/news', test);
|
||||
router.use('/branches', test);
|
||||
router.use('/trackings', test);
|
||||
router.use('/upload', test);
|
||||
router.use('/calendars', test);
|
||||
router.use('/dashboard', test);
|
||||
*/
|
||||
|
||||
module.exports = router;
|
||||
11
src/apps/private/load-attachments/routes.js
Normal file
11
src/apps/private/load-attachments/routes.js
Normal file
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
const router = require('express').Router();
|
||||
const services= require('./services.js');
|
||||
|
||||
router.post('/loading/:id', services.postLoadingAttachment );
|
||||
router.post('/downloading/:id', services.postDownloadingAttachment );
|
||||
router.get('/load/:id', services.getLoadAttachmentList );
|
||||
router.get('/:id', services.getAttachment );
|
||||
router.get('/', services.getAttachmentList );
|
||||
|
||||
module.exports = router;
|
||||
150
src/apps/private/load-attachments/services.js
Normal file
150
src/apps/private/load-attachments/services.js
Normal file
@@ -0,0 +1,150 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, LIB_PATH, MODELS_PATH, API_CONFIG } = process.env;
|
||||
const { getPagination , getPage } = require( `${ROOT_PATH}/${LIB_PATH}/Misc.js` );
|
||||
const apiConfig = require( `${ROOT_PATH}/${API_CONFIG}` );
|
||||
|
||||
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
|
||||
const s3Client = new S3Client({
|
||||
region : apiConfig.S3.region,
|
||||
credentials : {
|
||||
accessKeyId : apiConfig.S3.accessKeyId,
|
||||
secretAccessKey : apiConfig.S3.secretAccessKey
|
||||
}
|
||||
});
|
||||
const s3Bucket = apiConfig.S3.bucket;
|
||||
const s3BucketKey = apiConfig.S3.key;
|
||||
|
||||
const Model = require( `${ROOT_PATH}/${MODELS_PATH}/load-attachments.model.js` );
|
||||
const UserModel = require( `${ROOT_PATH}/${MODELS_PATH}/users.model.js` );
|
||||
const LoadsModel = require( `${ROOT_PATH}/${MODELS_PATH}/loads.model.js` );
|
||||
|
||||
async function getAuthorizationFilter( userId ){
|
||||
const user = await UserModel.findById( userId );
|
||||
const companyId = user.company.toString();
|
||||
return {
|
||||
$or: [
|
||||
{ company : companyId },
|
||||
{ carrier : companyId },
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
const getAttachment = async(req, res) => {
|
||||
const attachmentId = req.params.id;
|
||||
const CompanyAccessFilter = await getAuthorizationFilter( req.JWT.payload.sub );
|
||||
const filter = {
|
||||
$and : [
|
||||
{ _id : attachmentId },
|
||||
CompanyAccessFilter
|
||||
]
|
||||
};
|
||||
const retVal = await Model.findOne( filter ) || {};
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const getAttachmentList = async(req, res) => {
|
||||
const filter = await getAuthorizationFilter( req.JWT.payload.sub );
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page, elements, Model, filter );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const getLoadAttachmentList = async(req, res) => {
|
||||
const loadId = req.params.id;
|
||||
const CompanyAccessFilter = await getAuthorizationFilter( req.JWT.payload.sub );
|
||||
console.log( loadId );
|
||||
const filter = {
|
||||
$and : [
|
||||
{ load : loadId },
|
||||
CompanyAccessFilter
|
||||
]
|
||||
};
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page, elements, Model, filter );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
async function getLoadById( loadId , companyId ){
|
||||
const filter = {
|
||||
$and : [
|
||||
{ _id : loadId },
|
||||
{
|
||||
$or: [
|
||||
{ company : companyId },
|
||||
{ carrier : companyId },
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
return await LoadsModel.findOne( filter ) || null;
|
||||
}
|
||||
|
||||
async function createLoadAttachment( type , userId , loadId ){
|
||||
const user = await UserModel.findById( userId );
|
||||
const companyId = user.company.toString();
|
||||
const load = await getLoadById( loadId , companyId );
|
||||
const prevAttachment = (load)? await Model.findOne({ load : loadId , type : type }) : null;
|
||||
|
||||
let attachment = null;
|
||||
|
||||
if( load && !prevAttachment ){
|
||||
attachment = new Model({
|
||||
type : type,
|
||||
carrier : companyId,
|
||||
load : loadId,
|
||||
author : userId
|
||||
});
|
||||
await attachment.save();
|
||||
}
|
||||
else if( load && prevAttachment ){
|
||||
prevAttachment.updatedAt = Date.now();
|
||||
await prevAttachment.save();
|
||||
attachment = prevAttachment;
|
||||
}else{
|
||||
/**
|
||||
* load is not valid => I don't have access to this load!
|
||||
*/
|
||||
attachment = null;
|
||||
}
|
||||
return attachment;
|
||||
}
|
||||
|
||||
async function uploadFile( bucket, key, file , obj_id ){
|
||||
const params = {
|
||||
Bucket: bucket,
|
||||
Key : `${key}/${obj_id}`,
|
||||
ContentType : file.mimetype,
|
||||
Body : file.data
|
||||
};
|
||||
const s3resp = await s3Client.send( new PutObjectCommand( params ) );
|
||||
return s3resp;
|
||||
}
|
||||
const postLoadingAttachment = async(req, res) => {
|
||||
const loadId = req.params.id;
|
||||
const attachment = await createLoadAttachment( "Loading", req.JWT.payload.sub , loadId );
|
||||
const file = req.files.attachment;
|
||||
if( attachment && file ){
|
||||
const s3resp = await uploadFile( s3Bucket, s3BucketKey, file , attachment._id );
|
||||
res.send( attachment );
|
||||
}else if( !file ){
|
||||
res.status(400).send({ error : "attachment file not found" , code: 400 });
|
||||
}else{
|
||||
res.status(401).send({error:"Unauthorized",code:401});
|
||||
}
|
||||
};
|
||||
|
||||
const postDownloadingAttachment = async(req, res) => {
|
||||
const loadId = req.params.id;
|
||||
const attachment = await createLoadAttachment( "Downloading", req.JWT.payload.sub , loadId );
|
||||
const file = req.files.attachment;
|
||||
if( attachment && file ){
|
||||
const s3resp = await uploadFile( s3Bucket, s3BucketKey, file , attachment._id );
|
||||
res.send( attachment );
|
||||
}else if( !file ){
|
||||
res.status(400).send({ error : "attachment file not found" , code: 400 });
|
||||
}else{
|
||||
res.status(401).send({error:"Unauthorized",code:401});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { getAttachment, getAttachmentList, getLoadAttachmentList, postLoadingAttachment, postDownloadingAttachment };
|
||||
8
src/apps/private/loads/routes.js
Normal file
8
src/apps/private/loads/routes.js
Normal file
@@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
const router = require('express').Router();
|
||||
const services= require('./services.js');
|
||||
|
||||
router.get('/', services.getLoadsList);
|
||||
router.get('/:id', services.getLoad);
|
||||
|
||||
module.exports = router;
|
||||
47
src/apps/private/loads/services.js
Normal file
47
src/apps/private/loads/services.js
Normal file
@@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, LIB_PATH, MODELS_PATH, HANDLERS_PATH } = process.env;
|
||||
const { getPagination , queryPage } = require( `${ROOT_PATH}/${LIB_PATH}/Misc.js` );
|
||||
const Model = require( `${ROOT_PATH}/${MODELS_PATH}/loads.model.js` );
|
||||
const UserModel = require( `${ROOT_PATH}/${MODELS_PATH}/users.model.js` );
|
||||
const CompaniesModel = require( `${ROOT_PATH}/${MODELS_PATH}/companies.model.js` );
|
||||
|
||||
async function getAuthorizationFilter( userId ){
|
||||
const user = await UserModel.findById( userId );
|
||||
const companyId = user.company.toString();
|
||||
return {
|
||||
$or: [
|
||||
{ company : companyId },
|
||||
{ carrier : companyId },
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
const getLoadsList = async(req, res) => {
|
||||
const filter = await getAuthorizationFilter( req.JWT.payload.sub );
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const query = await queryPage( page , elements, Model, filter );
|
||||
const list = await query.query.populate('product')
|
||||
.populate('company')
|
||||
.populate('carrier');
|
||||
res.send({
|
||||
total : query.total,
|
||||
limit : elements,
|
||||
skip : query.skip,
|
||||
data : list
|
||||
});
|
||||
};
|
||||
|
||||
const getLoad = async(req, res) => {
|
||||
const loadId = req.params.id;
|
||||
const CompanyAccessFilter = await getAuthorizationFilter( req.JWT.payload.sub );
|
||||
const filter = {
|
||||
$and : [
|
||||
{ _id : loadId },
|
||||
CompanyAccessFilter
|
||||
]
|
||||
};
|
||||
const retVal = await Model.findOne( filter ).populate('product').populate('company').populate('carrier') || {};
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
module.exports = { getLoadsList, getLoad };
|
||||
9
src/apps/private/users/routes.js
Normal file
9
src/apps/private/users/routes.js
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
const router = require('express').Router();
|
||||
const services= require('./services.js');
|
||||
|
||||
router.get('/', services.getProfileData);
|
||||
router.get('/profile', services.getProfileData);
|
||||
router.get('/:userId', services.getProfileData);
|
||||
|
||||
module.exports = router;
|
||||
20
src/apps/private/users/services.js
Normal file
20
src/apps/private/users/services.js
Normal file
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, HANDLERS_PATH, API_CONFIG } = process.env;
|
||||
const UsersHandler = require( `${ROOT_PATH}/${HANDLERS_PATH}/Users.handler.js` );
|
||||
|
||||
const getUsersList = async(req, res) => {
|
||||
console.log( req.params );
|
||||
res.send({ user : "hello world!" });
|
||||
};
|
||||
|
||||
const getUserData = async(req, res) => {
|
||||
console.log( req.params );
|
||||
res.send({ user : "hello world!" });
|
||||
};
|
||||
|
||||
const getProfileData = async(req, res) => {
|
||||
const user = await UsersHandler.getUserData( req.JWT.payload.sub );
|
||||
res.send( user );
|
||||
};
|
||||
|
||||
module.exports = { getUsersList , getUserData , getProfileData};
|
||||
9
src/apps/public/cities/routes.js
Normal file
9
src/apps/public/cities/routes.js
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
const router = require('express').Router();
|
||||
const services= require('./services.js');
|
||||
|
||||
router.get('/', services.getList);
|
||||
router.get('/find', services.findList);
|
||||
router.get('/:id', services.getById);
|
||||
|
||||
module.exports = router;
|
||||
33
src/apps/public/cities/services.js
Normal file
33
src/apps/public/cities/services.js
Normal file
@@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, LIB_PATH, MODELS_PATH, HANDLERS_PATH } = process.env;
|
||||
const { getPagination , getPage } = require( `${ROOT_PATH}/${LIB_PATH}/Misc.js` );
|
||||
const { GenericHandler } = require( `${ROOT_PATH}/${HANDLERS_PATH}/Generic.handler.js` );
|
||||
const Model = require( `${ROOT_PATH}/${MODELS_PATH}/cities.model.js` );
|
||||
|
||||
const generic = new GenericHandler( Model, "city_name" );
|
||||
|
||||
const getList = async(req, res) => {
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await generic.getList(page , elements);
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const findList = async(req, res) => {
|
||||
const findString = req.query.regex || null;
|
||||
const { page , elements } = getPagination( req.query );
|
||||
let retVal;
|
||||
if( findString ){
|
||||
retVal = await generic.findList( findString, page, elements );
|
||||
}else{
|
||||
retVal = await generic.getList(page , elements);
|
||||
}
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const getById = async(req, res) => {
|
||||
const id=req.params.id;
|
||||
const retVal = await generic.getById( id );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
module.exports = { getList , findList , getById };
|
||||
9
src/apps/public/countries/routes.js
Normal file
9
src/apps/public/countries/routes.js
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
const router = require('express').Router();
|
||||
const services= require('./services.js');
|
||||
|
||||
router.get('/', services.getList);
|
||||
router.get('/find', services.findList);
|
||||
router.get('/:id', services.getById);
|
||||
|
||||
module.exports = router;
|
||||
28
src/apps/public/countries/services.js
Normal file
28
src/apps/public/countries/services.js
Normal file
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, LIB_PATH, MODELS_PATH, HANDLERS_PATH } = process.env;
|
||||
const { getPagination , getPage } = require( `${ROOT_PATH}/${LIB_PATH}/Misc.js` );
|
||||
const Model = require( `${ROOT_PATH}/${MODELS_PATH}/countries.model.js` );
|
||||
|
||||
const getList = async(req, res) => {
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page , elements, Model );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const findList = async(req, res) => {
|
||||
let filter=null;
|
||||
if( req.query.regex ){
|
||||
const re = new RegExp( req.query.regex );
|
||||
filter = { "country_name" : { $regex: re, $options: 'i' }};
|
||||
}
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page, elements, Model, filter );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const getById = async(req, res) => {
|
||||
const retVal = await Model.findById( req.params.id );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
module.exports = { getList, findList, getById };
|
||||
30
src/apps/public/index.js
Normal file
30
src/apps/public/index.js
Normal file
@@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
const { ROOT_PATH , LIB_PATH } = process.env;
|
||||
|
||||
/// Router instance
|
||||
const router = require('express').Router();
|
||||
|
||||
const cities = require('./cities/routes.js');
|
||||
const countries = require('./countries/routes.js');
|
||||
const metaData = require('./meta-data/routes.js');
|
||||
const metaGroups = require('./meta-groups/routes.js');
|
||||
const productCategories = require('./product-categories/routes.js');
|
||||
const products = require('./products/routes.js');
|
||||
const publicVehicles = require('./public-vehicles/routes.js');
|
||||
const publicLoadAttachments = require('./public-load-attachments/routes.js');
|
||||
const states = require('./states/routes.js');
|
||||
const test = require('./test/routes.js');
|
||||
|
||||
router.use('/cities', cities);
|
||||
router.use('/countries', countries);
|
||||
router.use('/meta-data', metaData);
|
||||
router.use('/meta-groups', metaGroups);
|
||||
router.use('/product-categories', productCategories);
|
||||
router.use('/products', products);
|
||||
router.use("/public-vehicles", publicVehicles);
|
||||
router.use('/public-load-attachments', publicLoadAttachments );
|
||||
router.use('/states', states);
|
||||
|
||||
router.use("/test", test);
|
||||
|
||||
module.exports = router;
|
||||
9
src/apps/public/meta-data/routes.js
Normal file
9
src/apps/public/meta-data/routes.js
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
const router = require('express').Router();
|
||||
const services= require('./services.js');
|
||||
|
||||
router.get('/', services.getList);
|
||||
router.get('/find', services.findList);
|
||||
router.get('/:id', services.getById);
|
||||
|
||||
module.exports = router;
|
||||
28
src/apps/public/meta-data/services.js
Normal file
28
src/apps/public/meta-data/services.js
Normal file
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, LIB_PATH, MODELS_PATH, HANDLERS_PATH } = process.env;
|
||||
const { getPagination , getPage } = require( `${ROOT_PATH}/${LIB_PATH}/Misc.js` );
|
||||
const Model = require( `${ROOT_PATH}/${MODELS_PATH}/meta-data.model.js` );
|
||||
|
||||
const getList = async(req, res) => {
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page , elements, Model );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const findList = async(req, res) => {
|
||||
let filter=null;
|
||||
if( req.query.regex ){
|
||||
const re = new RegExp( req.query.regex );
|
||||
filter = { "meta_value" : { $regex: re, $options: 'i' }};
|
||||
}
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page, elements, Model, filter );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const getById = async(req, res) => {
|
||||
const retVal = await Model.findById( req.params.id );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
module.exports = { getList, findList, getById };
|
||||
9
src/apps/public/meta-groups/routes.js
Normal file
9
src/apps/public/meta-groups/routes.js
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
const router = require('express').Router();
|
||||
const services= require('./services.js');
|
||||
|
||||
router.get('/', services.getList);
|
||||
router.get('/find', services.findList);
|
||||
router.get('/:id', services.getById);
|
||||
|
||||
module.exports = router;
|
||||
28
src/apps/public/meta-groups/services.js
Normal file
28
src/apps/public/meta-groups/services.js
Normal file
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, LIB_PATH, MODELS_PATH, HANDLERS_PATH } = process.env;
|
||||
const { getPagination , getPage } = require( `${ROOT_PATH}/${LIB_PATH}/Misc.js` );
|
||||
const Model = require( `${ROOT_PATH}/${MODELS_PATH}/meta-groups.model.js` );
|
||||
|
||||
const getList = async(req, res) => {
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page , elements, Model );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const findList = async(req, res) => {
|
||||
let filter=null;
|
||||
if( req.query.regex ){
|
||||
const re = new RegExp( req.query.regex );
|
||||
filter = { "group_label" : { $regex: re, $options: 'i' }};
|
||||
}
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page, elements, Model, filter );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const getById = async(req, res) => {
|
||||
const retVal = await Model.findById( req.params.id );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
module.exports = { getList, findList, getById };
|
||||
9
src/apps/public/product-categories/routes.js
Normal file
9
src/apps/public/product-categories/routes.js
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
const router = require('express').Router();
|
||||
const services= require('./services.js');
|
||||
|
||||
router.get('/', services.getList);
|
||||
router.get('/find', services.findList);
|
||||
router.get('/:id', services.getById);
|
||||
|
||||
module.exports = router;
|
||||
28
src/apps/public/product-categories/services.js
Normal file
28
src/apps/public/product-categories/services.js
Normal file
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, LIB_PATH, MODELS_PATH, HANDLERS_PATH } = process.env;
|
||||
const { getPagination , getPage } = require( `${ROOT_PATH}/${LIB_PATH}/Misc.js` );
|
||||
const Model = require( `${ROOT_PATH}/${MODELS_PATH}/product-categories.model.js` );
|
||||
|
||||
const getList = async(req, res) => {
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page , elements, Model );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const findList = async(req, res) => {
|
||||
let filter=null;
|
||||
if( req.query.regex ){
|
||||
const re = new RegExp( req.query.regex );
|
||||
filter = { "name" : { $regex: re, $options: 'i' }};
|
||||
}
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page, elements, Model, filter );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const getById = async(req, res) => {
|
||||
const retVal = await Model.findById( req.params.id );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
module.exports = { getList, findList, getById };
|
||||
9
src/apps/public/products/routes.js
Normal file
9
src/apps/public/products/routes.js
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
const router = require('express').Router();
|
||||
const services= require('./services.js');
|
||||
|
||||
router.get('/', services.getList);
|
||||
router.get('/find', services.findList);
|
||||
router.get('/:id', services.getById);
|
||||
|
||||
module.exports = router;
|
||||
28
src/apps/public/products/services.js
Normal file
28
src/apps/public/products/services.js
Normal file
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, LIB_PATH, MODELS_PATH, HANDLERS_PATH } = process.env;
|
||||
const { getPagination , getPage } = require( `${ROOT_PATH}/${LIB_PATH}/Misc.js` );
|
||||
const Model = require( `${ROOT_PATH}/${MODELS_PATH}/products.model.js` );
|
||||
|
||||
const getList = async(req, res) => {
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page , elements, Model );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const findList = async(req, res) => {
|
||||
let filter=null;
|
||||
if( req.query.regex ){
|
||||
const re = new RegExp( req.query.regex );
|
||||
filter = { "name" : { $regex: re, $options: 'i' }};
|
||||
}
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page, elements, Model, filter );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const getById = async(req, res) => {
|
||||
const retVal = await Model.findById( req.params.id );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
module.exports = { getList, findList, getById };
|
||||
7
src/apps/public/public-load-attachments/routes.js
Normal file
7
src/apps/public/public-load-attachments/routes.js
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
const router = require('express').Router();
|
||||
const services= require('./services.js');
|
||||
|
||||
router.get('/download/:id', services.getAttachmentFile );
|
||||
|
||||
module.exports = router;
|
||||
38
src/apps/public/public-load-attachments/services.js
Normal file
38
src/apps/public/public-load-attachments/services.js
Normal file
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, LIB_PATH, MODELS_PATH, API_CONFIG } = process.env;
|
||||
const apiConfig = require( `${ROOT_PATH}/${API_CONFIG}` );
|
||||
|
||||
const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3');
|
||||
const s3Client = new S3Client({
|
||||
region : apiConfig.S3.region,
|
||||
credentials : {
|
||||
accessKeyId : apiConfig.S3.accessKeyId,
|
||||
secretAccessKey : apiConfig.S3.secretAccessKey
|
||||
}
|
||||
});
|
||||
const s3Bucket = apiConfig.S3.bucket;
|
||||
const s3BucketKey = apiConfig.S3.key;
|
||||
|
||||
async function downloadFile( bucket, key, obj_id ){
|
||||
const params = {
|
||||
Bucket: bucket,
|
||||
Key : `${key}/${obj_id}`
|
||||
};
|
||||
const s3resp = await s3Client.send( new GetObjectCommand( params ) );
|
||||
const chunks = []
|
||||
for await (const chunk of s3resp.Body) {
|
||||
chunks.push(chunk)
|
||||
}
|
||||
const body = Buffer.concat(chunks);
|
||||
s3resp.Body = body;
|
||||
return s3resp;
|
||||
}
|
||||
const getAttachmentFile = async(req, res) => {
|
||||
const attachmentId = req.params.id;
|
||||
const file = await downloadFile( s3Bucket, s3BucketKey, attachmentId );
|
||||
res.attachment( attachmentId );
|
||||
res.setHeader('Content-Type', file.ContentType );
|
||||
res.send( file.Body );
|
||||
}
|
||||
|
||||
module.exports = { getAttachmentFile };
|
||||
7
src/apps/public/public-vehicles/routes.js
Normal file
7
src/apps/public/public-vehicles/routes.js
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
const router = require('express').Router();
|
||||
const services= require('./services.js');
|
||||
|
||||
router.get('/', services.getPublicVehiclesList);
|
||||
|
||||
module.exports = router;
|
||||
25
src/apps/public/public-vehicles/services.js
Normal file
25
src/apps/public/public-vehicles/services.js
Normal file
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, LIB_PATH, MODELS_PATH, HANDLERS_PATH } = process.env;
|
||||
const { getPagination , getPage } = require( `${ROOT_PATH}/${LIB_PATH}/Misc.js` );
|
||||
const Model = require( `${ROOT_PATH}/${MODELS_PATH}/vehicles.model.js` );
|
||||
|
||||
const getPublicVehiclesList = async(req, res) => {
|
||||
const filter = { status : "Free" };
|
||||
const select = [
|
||||
"city",
|
||||
"state",
|
||||
"truck_type",
|
||||
"tyre_type",
|
||||
"destino",
|
||||
"available_date",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"published_date",
|
||||
"status"
|
||||
];
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page , elements, Model, filter, select );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
module.exports = { getPublicVehiclesList };
|
||||
9
src/apps/public/states/routes.js
Normal file
9
src/apps/public/states/routes.js
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
const router = require('express').Router();
|
||||
const services= require('./services.js');
|
||||
|
||||
router.get('/', services.getList);
|
||||
router.get('/find', services.findList);
|
||||
router.get('/:id', services.getById);
|
||||
|
||||
module.exports = router;
|
||||
28
src/apps/public/states/services.js
Normal file
28
src/apps/public/states/services.js
Normal file
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, LIB_PATH, MODELS_PATH, HANDLERS_PATH } = process.env;
|
||||
const { getPagination , getPage } = require( `${ROOT_PATH}/${LIB_PATH}/Misc.js` );
|
||||
const Model = require( `${ROOT_PATH}/${MODELS_PATH}/states.model.js` );
|
||||
|
||||
const getList = async(req, res) => {
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page , elements, Model );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const findList = async(req, res) => {
|
||||
let filter=null;
|
||||
if( req.query.regex ){
|
||||
const re = new RegExp( req.query.regex );
|
||||
filter = { "state_name" : { $regex: re, $options: 'i' }};
|
||||
}
|
||||
const { page , elements } = getPagination( req.query );
|
||||
const retVal = await getPage( page, elements, Model, filter );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
const getById = async(req, res) => {
|
||||
const retVal = await Model.findById( req.params.id );
|
||||
res.send( retVal );
|
||||
};
|
||||
|
||||
module.exports = { getList, findList, getById };
|
||||
8
src/apps/public/test/routes.js
Normal file
8
src/apps/public/test/routes.js
Normal file
@@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
const router = require('express').Router();
|
||||
const services= require('./services.js');
|
||||
|
||||
router.post('/apitest', services.postTest);
|
||||
router.get('/version', services.getVersion);
|
||||
|
||||
module.exports = router;
|
||||
20
src/apps/public/test/services.js
Normal file
20
src/apps/public/test/services.js
Normal file
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, LIB_PATH, API_CONFIG } = process.env;
|
||||
const apiConfig = require( `${ROOT_PATH}/${API_CONFIG}` );
|
||||
|
||||
const postTest = async(req, res) => {
|
||||
res.send({
|
||||
msg:"Hello world!",
|
||||
data:{
|
||||
apiQuery:req.query,
|
||||
apiParams:req.params.params,
|
||||
body:req.body,
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const getVersion = async(req, res) => {
|
||||
res.send( apiConfig.version );
|
||||
};
|
||||
|
||||
module.exports = { postTest , getVersion };
|
||||
36
src/config/apiConfig.json
Normal file
36
src/config/apiConfig.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"authentication": {
|
||||
"jwtSecret":"9o3BBz0EsrwXliwEJ/SFuywZoN8=",
|
||||
"jwtTimeout":720,
|
||||
"tokenSecret":"9Z'jMt|(h_f(&/S+zv.K",
|
||||
"jwtOptions": {
|
||||
"header": {
|
||||
"typ": "access"
|
||||
},
|
||||
"audience": "https://www.etaviaporte.com",
|
||||
"issuer": "etaviaporte",
|
||||
"algorithm": "HS256",
|
||||
"expiresIn": "1d"
|
||||
}
|
||||
},
|
||||
"version" : {
|
||||
"version" : "1.0.14",
|
||||
"name": "ETA Beta",
|
||||
"date":"10/2023"
|
||||
},
|
||||
"S3" : {
|
||||
"accessKeyId": "AKIAXTQEUF6MLCHTUIKW",
|
||||
"secretAccessKey": "QhM8gQ5O3hVDIf41YeO5/A6Wo58D1xQz8pzxBB2W",
|
||||
"bucket": "enruta",
|
||||
"key":"loadattachments",
|
||||
"region": "us-west-1"
|
||||
},
|
||||
"sendgrid" : {
|
||||
"HOST": "smtp.sendgrid.net",
|
||||
"PORT": "465",
|
||||
"username": "apikey",
|
||||
"API_KEY": "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",
|
||||
"FROM": "noreply@etaviaporte.com"
|
||||
},
|
||||
"mongodb": "mongodb+srv://enruta_admin:NeptFx4RUZG8OsfA@enruta.vwofshy.mongodb.net/enrutaviaporte?retryWrites=true&w=majority"
|
||||
}
|
||||
35
src/config/apiConfig_local.json
Normal file
35
src/config/apiConfig_local.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"authentication": {
|
||||
"jwtSecret":"9o3BBz0EsrwXliwEJ/SFuywZoN8=",
|
||||
"jwtTimeout":720,
|
||||
"tokenSecret":"9Z'jMt|(h_f(&/S+zv.K",
|
||||
"jwtOptions": {
|
||||
"header": {
|
||||
"typ": "access"
|
||||
},
|
||||
"audience": "https://www.etaviaporte.com",
|
||||
"issuer": "etaviaporte",
|
||||
"algorithm": "HS256",
|
||||
"expiresIn": "1d"
|
||||
}
|
||||
},
|
||||
"version" : {
|
||||
"version" : "1.0.14",
|
||||
"name": "ETA Beta",
|
||||
"date":"10/2023"
|
||||
},
|
||||
"S3" : {
|
||||
"accessKeyId": "AKIAXTQEUF6MLCHTUIKW",
|
||||
"secretAccessKey": "QhM8gQ5O3hVDIf41YeO5/A6Wo58D1xQz8pzxBB2W",
|
||||
"bucket": "enruta",
|
||||
"region": "us-west-1"
|
||||
},
|
||||
"sendgrid" : {
|
||||
"HOST": "smtp.sendgrid.net",
|
||||
"PORT": "465",
|
||||
"username": "apikey",
|
||||
"API_KEY": "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",
|
||||
"FROM": "noreply@etaviaporte.com"
|
||||
},
|
||||
"mongodb": "mongodb://localhost/etaviaporte?retryWrites=true&w=majority"
|
||||
}
|
||||
71
src/index.js
Normal file
71
src/index.js
Normal file
@@ -0,0 +1,71 @@
|
||||
'use strict';
|
||||
require('dotenv').config();
|
||||
const { ROOT_PATH, LIB_PATH, API_CONFIG } = process.env;
|
||||
const apiConfig = require( `${ROOT_PATH}/${API_CONFIG}` );
|
||||
const apps = require('./apps');
|
||||
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const compression = require('compression');
|
||||
const morgan = require('morgan');
|
||||
const helmet = require('helmet');
|
||||
const bodyParser = require('body-parser');
|
||||
const fileUpload = require('express-fileupload');
|
||||
const middlewares = require( `${ROOT_PATH}/${LIB_PATH}/Middlewares.js` );
|
||||
|
||||
const mongoose = require('mongoose');
|
||||
mongoose.connect(
|
||||
apiConfig.mongodb,
|
||||
{ useNewUrlParser: true }
|
||||
).then( ( val ) => {
|
||||
console.log( `MongoDB Connected : ${ apiConfig.mongodb }` );
|
||||
});//catch throw error so service stops!
|
||||
|
||||
const app = express();
|
||||
const serverPort = process.env.SERVER_PORT || 3000;
|
||||
|
||||
app.use( middlewares.Auth );
|
||||
app.use(
|
||||
fileUpload({
|
||||
limits: { fileSize: 4 * 1024 * 1024 },
|
||||
abortOnLimit: true,
|
||||
limitHandler: (req,res,next) => {
|
||||
req.limitSize = true;
|
||||
},
|
||||
})
|
||||
);
|
||||
app.use((req, res, next) => {
|
||||
if (req.limitSize) {
|
||||
res.status(413).send({message:"File size limit has been reached",status:"PAYLOAD_TOO_LARGE"});
|
||||
}else{
|
||||
next()
|
||||
}
|
||||
|
||||
});
|
||||
app.use(bodyParser.urlencoded({ extended: true, limit: '50mb' }));
|
||||
app.use(bodyParser.json({ limit: '50mb' }));
|
||||
app.use(morgan('dev'));
|
||||
app.use(helmet());
|
||||
app.use(compression());
|
||||
app.use(cors({
|
||||
origin: '*',
|
||||
methods: [
|
||||
'GET',
|
||||
'POST',
|
||||
'PATCH',
|
||||
'PUT',
|
||||
'DELETE'
|
||||
],
|
||||
allowedHeaders: ['Content-Type', 'Authorization']
|
||||
}));
|
||||
app.use( middlewares.errorJSON );
|
||||
app.use( apps );
|
||||
app.use( middlewares.error404 );
|
||||
|
||||
app.listen( serverPort , function(err){
|
||||
if( !err ){
|
||||
console.log('API listen on port', serverPort );
|
||||
}else{
|
||||
console.log( err );
|
||||
}
|
||||
});
|
||||
59
src/lib/Handlers/Generic.handler.js
Normal file
59
src/lib/Handlers/Generic.handler.js
Normal file
@@ -0,0 +1,59 @@
|
||||
"use strict";
|
||||
const { ROOT_PATH, LIB_PATH, MODELS_PATH, HANDLERS_PATH } = process.env;
|
||||
|
||||
async function getPage( page, elements, Model, filter=null, projection=null){
|
||||
const skip = elements * page;
|
||||
const total = await Model.count( filter );
|
||||
const list = await Model.find( filter , projection, { skip : skip , limit : elements } );
|
||||
return {
|
||||
total : total,
|
||||
limit : elements,
|
||||
skip : skip,
|
||||
data : list
|
||||
}
|
||||
}
|
||||
|
||||
async function getPageQuery(page, elements, Model, filter=null, projection=null){
|
||||
const skip = elements * page;
|
||||
const total = await Model.count( filter );
|
||||
return {
|
||||
query : Model.find( filter , projection, { skip : skip , limit : elements } ),
|
||||
total : total,
|
||||
skip : skip
|
||||
};
|
||||
}
|
||||
|
||||
class GenericHandler{
|
||||
constructor( Model, search_param, populate_list=null ) {
|
||||
this.Model = Model;
|
||||
this.search_param = search_param;
|
||||
this.populate_list = populate_list || [];
|
||||
}
|
||||
|
||||
async populateQuey( query ){
|
||||
if( this.populate_list.length > 0 ){
|
||||
query.populate( this.populate_list );
|
||||
}
|
||||
return await query.exec();
|
||||
}
|
||||
|
||||
async getList( page, elements, filter=null, projection=null ){
|
||||
const { query } = await getPageQuery( page , elements, this.Model, filter, projection );
|
||||
return await this.populateQuey( query );
|
||||
}
|
||||
|
||||
async findList( find_string, page, elements, projection=null ){
|
||||
const search_param = this.search_param;
|
||||
const re = new RegExp( find_string );
|
||||
const filter = {};
|
||||
filter[ search_param ] = { $regex: re, $options: 'i' };
|
||||
return await this.getList( page, elements, filter, projection );
|
||||
}
|
||||
|
||||
async getById( id, projection=null ){
|
||||
const query = Model.findById( id, projection );
|
||||
return await this.populateQuey( query );
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { getPage, getPageQuery, GenericHandler };
|
||||
9
src/lib/Handlers/Users.handler.js
Normal file
9
src/lib/Handlers/Users.handler.js
Normal file
@@ -0,0 +1,9 @@
|
||||
'user strict';
|
||||
const { ROOT_PATH, HANDLERS_PATH, MODELS_PATH, API_CONFIG } = process.env;
|
||||
const usersModel = require( `${ROOT_PATH}/${MODELS_PATH}/users.model.js` );
|
||||
|
||||
async function getUserData( id ){
|
||||
return await usersModel.findById( id , { password : 0 } );
|
||||
}
|
||||
|
||||
module.exports = { getUserData };
|
||||
87
src/lib/Middlewares.js
Normal file
87
src/lib/Middlewares.js
Normal file
@@ -0,0 +1,87 @@
|
||||
'use strict';
|
||||
/**
|
||||
* HASH
|
||||
*****************************************************
|
||||
* DEPENDENCIES
|
||||
*****************************************************
|
||||
* Based on Express Framework
|
||||
* System
|
||||
*****************************************************
|
||||
* PUBLIC METHODS
|
||||
*****************************************************
|
||||
* Auth( req, res, next)
|
||||
* Extract JWT or BasicAuth data
|
||||
* errorJSON( error , request , response , next )
|
||||
* Generate error response on bad JSON format
|
||||
* error404( request , response , next )
|
||||
* Generate error 404 response
|
||||
* apiKey( request , response , next )
|
||||
* Generate error on invalid apikey
|
||||
**/
|
||||
|
||||
/// Extract JWT or BasicAuth
|
||||
function Auth( req, res , next ){
|
||||
///
|
||||
/// Try to extract the authorization data from headers
|
||||
///
|
||||
let auth;
|
||||
if( req.headers.hasOwnProperty( "authorization" ) ){
|
||||
auth = req.headers.authorization;
|
||||
auth = auth.split(" ")[1];
|
||||
if( !auth ){ console.log( "NO HEADER AUTH available" ); return next(); }
|
||||
//console.log( auth );
|
||||
/// Try BasicAuth {
|
||||
try{
|
||||
let ba = Buffer.from( auth , 'base64' ).toString()
|
||||
//const [user,pass] = ba.split(':');
|
||||
ba = ba.split(':');
|
||||
if( ba.length == 2 ){
|
||||
req.basicAuth = { user : ba[0] , password : ba[1] };
|
||||
}
|
||||
}catch(error){
|
||||
console.log("MIDDLEWARE_AUTH_ERR_BA",error);
|
||||
}
|
||||
/// Try BasicAuth }
|
||||
}else if( req.query.access_token ){
|
||||
auth = req.query.access_token;
|
||||
if( !auth ){ console.log( "NO QUERY AUTH available" ); return next(); }
|
||||
}
|
||||
if( auth ){
|
||||
/// Try JWT {
|
||||
try{
|
||||
let jwt = auth.split(".");
|
||||
if( jwt.length == 3 ){
|
||||
req.JWT = {};
|
||||
req.JWT.raw = auth;
|
||||
}
|
||||
}catch( error ){
|
||||
console.log("MIDDLEWARE_AUTH_ERR_JWT",error);
|
||||
}
|
||||
/// Try JWT }
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
function errorJSON( error , request , response , next ){
|
||||
console.log(error);
|
||||
if( error !== null ){
|
||||
/// For body-parser errors
|
||||
if( error instanceof SyntaxError && error.status === 400 && 'body' in error ){
|
||||
return response.status(400).json({ error : 'Invalid json' , code : 400 });
|
||||
}
|
||||
/// For any error
|
||||
return response.status(500).send( { error: "Internal server error" , code : 500 } );
|
||||
}else{
|
||||
return next();
|
||||
}
|
||||
}
|
||||
|
||||
function error404( request , response , next ){
|
||||
return response.status(404).send( { error : "Page not found", code : 404 } );
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Auth,
|
||||
errorJSON,
|
||||
error404,
|
||||
};
|
||||
50
src/lib/Misc.js
Normal file
50
src/lib/Misc.js
Normal file
@@ -0,0 +1,50 @@
|
||||
"use strict";
|
||||
|
||||
function getPagination( query ){
|
||||
let limit = {
|
||||
page : 0,
|
||||
elements : 10
|
||||
};
|
||||
|
||||
if( query.page ){
|
||||
limit.page = parseInt( query.page ) || 0;
|
||||
if( limit.page < 0 ){
|
||||
limit.page = 0;
|
||||
}
|
||||
}
|
||||
if( query.elements ){
|
||||
limit.elements = parseInt( query.elements ) || 10;
|
||||
/** Safe pagination limit */
|
||||
if( limit.elements > 1000 ){
|
||||
limit.elements = 1000;
|
||||
}
|
||||
else if( limit.elements < 0 ){
|
||||
limit.elements = 10;
|
||||
}
|
||||
}
|
||||
return limit;
|
||||
}
|
||||
|
||||
async function getPage( page, elements, model, filter=null, projection=null){
|
||||
const skip = elements * page;
|
||||
const total = await model.count( filter );
|
||||
const list = await model.find( filter , projection, { skip : skip , limit : elements } );
|
||||
return {
|
||||
total : total,
|
||||
limit : elements,
|
||||
skip : skip,
|
||||
data : list
|
||||
}
|
||||
}
|
||||
|
||||
async function queryPage(page, elements, model, filter=null, projection=null){
|
||||
const skip = elements * page;
|
||||
const total = await model.count( filter );
|
||||
return {
|
||||
query : model.find( filter , projection, { skip : skip , limit : elements } ),
|
||||
total : total,
|
||||
skip : skip
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = { getPagination , getPage, queryPage };
|
||||
16
src/lib/Models/branches.model.js
Normal file
16
src/lib/Models/branches.model.js
Normal file
@@ -0,0 +1,16 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
categories: [{ type: Schema.Types.ObjectId, ref: 'product-categories' }],
|
||||
company: { type: Schema.Types.ObjectId, ref: 'companies' },
|
||||
branch_name: { type: String },
|
||||
phone: { type: String },
|
||||
city: { type: String },
|
||||
state: { type: String },
|
||||
truck_type: [{ type: String }],
|
||||
description:{type: String},
|
||||
address : { type: String }
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "branches", schema );
|
||||
33
src/lib/Models/budgets.model.js
Normal file
33
src/lib/Models/budgets.model.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
company: { type: Schema.Types.ObjectId, ref: 'companies', required: true},
|
||||
client: { type: String, required: true },
|
||||
material: { type: String },
|
||||
origin: { type: String },
|
||||
destination: { type: String },
|
||||
truck_type: { type: String },
|
||||
num_tons: { type: Number },
|
||||
price_per_ton: { type: Number },
|
||||
tonnage: { type: String },
|
||||
pickup_distance: { type: Number },
|
||||
delivery_distance: { type: Number },
|
||||
warehouse_distance: { type: Number },
|
||||
total_km_travel: { type: Number },
|
||||
cost_per_liter: { type: Number },
|
||||
fuel_price_per_liter: { type: Number },
|
||||
other_fuel_expenses: { type: Number },
|
||||
total_fuel_consumed: { type: Number },
|
||||
total_cost_fuel: { type: Number },
|
||||
driver_salary: { type: Number },
|
||||
accomadation_allowance: { type: Number },
|
||||
other_administrative_expenses: { type: Number },
|
||||
total_before_tax: { type: Number },
|
||||
total_utility_per_km: { type: Number },
|
||||
total_profit: { type: Number },
|
||||
profit_percentage: { type: Number },
|
||||
total_administrative_expenses: { type: Number }
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "budgets", schema );
|
||||
11
src/lib/Models/cities.model.js
Normal file
11
src/lib/Models/cities.model.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
country_name: { type: String },
|
||||
country_code: { type: String },
|
||||
state_name: { type: String },
|
||||
city_name: { type: String, required: true }
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "cities", schema );
|
||||
65
src/lib/Models/companies.model.js
Normal file
65
src/lib/Models/companies.model.js
Normal file
@@ -0,0 +1,65 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const meta_data = new Schema({
|
||||
meta_group: { type: String },
|
||||
meta_key: { type: String },
|
||||
meta_value: { type: String },
|
||||
});
|
||||
|
||||
|
||||
const company_contacts = new Schema({
|
||||
meta_key: { type: String },
|
||||
meta_value: { type: String },
|
||||
});
|
||||
|
||||
const address = new Schema({
|
||||
street_address1: { type: String },
|
||||
street_address2: { type: String },
|
||||
city: { type: String },
|
||||
state: { type: String },
|
||||
country: { type: String },
|
||||
zipcode: { type: String },
|
||||
landmark: { type: String },
|
||||
lat: { type: String },
|
||||
lng: { type: String },
|
||||
});
|
||||
|
||||
const schema = new Schema({
|
||||
company_serial_number: { type: String },
|
||||
company_code: { type: String },
|
||||
is_company: { type: String }, //1000
|
||||
company_name: { type: String, required: true },
|
||||
company_legal_name: { type: String },
|
||||
company_description: { type: String },
|
||||
rfc: { type: String },
|
||||
|
||||
|
||||
company_type: [{ type: String }], // SHIPPER , CARRIER
|
||||
is_broker: { type: Boolean, default: false },
|
||||
membership: { type: String },
|
||||
membership_start_at: { type: Date },
|
||||
|
||||
meta_data: [meta_data],
|
||||
categories: [{ type: Schema.Types.ObjectId, ref: 'productcategories' }],
|
||||
products: { type: Schema.Types.ObjectId, ref: 'products' },
|
||||
users: [{ type: Schema.Types.ObjectId, ref: 'users' }],
|
||||
branches: [{ type: Schema.Types.ObjectId, ref: 'branches' }],
|
||||
company_city: [{ type: String }],
|
||||
company_state: [{ type: String }],
|
||||
truck_type: [{ type: String }],
|
||||
|
||||
street_address1: { type: String },
|
||||
street_address2: { type: String },
|
||||
city: { type: String },
|
||||
state: { type: String },
|
||||
country: { type: String },
|
||||
zipcode: { type: String },
|
||||
landmark: { type: String },
|
||||
lat: { type: String },
|
||||
lng: { type: String },
|
||||
|
||||
is_hidden: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "companies", schema );
|
||||
10
src/lib/Models/countries.model.js
Normal file
10
src/lib/Models/countries.model.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
country_name: { type: String, required: true },
|
||||
country_code: { type: String, required: true },
|
||||
phone_code: { type: String, required: true }
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "countries", schema );
|
||||
19
src/lib/Models/load-attachments.model.js
Normal file
19
src/lib/Models/load-attachments.model.js
Normal file
@@ -0,0 +1,19 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
status: { type: String, default: 'Draft', enum: ['Draft', 'Done'] },/*Once in Done state, no changes are allowed.*/
|
||||
updatedAt: {
|
||||
type: Date,
|
||||
default : () => Date.now()
|
||||
},
|
||||
type: { type: String, enum: ['Loading', 'Downloading'], required : true },
|
||||
company: { type: Schema.Types.ObjectId, ref: 'companies' }, //shipper
|
||||
carrier: { type: Schema.Types.ObjectId, ref: 'companies', required: true }, // carrier
|
||||
load: { type: Schema.Types.ObjectId, ref: 'loads', required: true },
|
||||
author: { type: Schema.Types.ObjectId, ref: 'users', required: true },
|
||||
doneAt: { type: Date }
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "loadattachments", schema );
|
||||
|
||||
90
src/lib/Models/loads.model.js
Normal file
90
src/lib/Models/loads.model.js
Normal file
@@ -0,0 +1,90 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const address = new Schema({
|
||||
company_name: { type: String },
|
||||
|
||||
street_address1: { type: String },
|
||||
street_address2: { type: String },
|
||||
city: { type: String },
|
||||
state: { type: String },
|
||||
country: { type: String },
|
||||
zipcode: { type: String },
|
||||
|
||||
landmark: { type: String },
|
||||
|
||||
lat: { type: String },
|
||||
lng: { type: String },
|
||||
});
|
||||
|
||||
|
||||
const pointSchema = new Schema({
|
||||
type: {
|
||||
type: String,
|
||||
enum: ['Point'],
|
||||
required: true
|
||||
},
|
||||
coordinates: {
|
||||
type: [Number],
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const schema = new Schema({
|
||||
shipment_code: { type: String },
|
||||
company: { type: Schema.Types.ObjectId, ref: 'companies', required: true }, //shipper
|
||||
carrier: { type: Schema.Types.ObjectId, ref: 'companies' }, // carrier
|
||||
vehicle: { type: Schema.Types.ObjectId, ref: 'vehicles' },
|
||||
driver: { type: Schema.Types.ObjectId, ref: 'users' },
|
||||
posted_by: { type: Schema.Types.ObjectId, ref: 'users' }, // shipper
|
||||
posted_by_name: { type: String }, // search purpose
|
||||
bidder: { type: Schema.Types.ObjectId, ref: 'users' },
|
||||
|
||||
origin: address,
|
||||
origin_geo: {
|
||||
type: pointSchema,
|
||||
},
|
||||
destination: address,
|
||||
destination_geo: {
|
||||
type: pointSchema,
|
||||
},
|
||||
|
||||
categories: [{ type: Schema.Types.ObjectId, ref: 'productcategories' }],
|
||||
product: { type: Schema.Types.ObjectId, ref: 'products' },
|
||||
|
||||
truck_type: { type: String },
|
||||
tyre_type: { type: String },
|
||||
weight: { type: Number },
|
||||
estimated_cost: { type: Number },
|
||||
|
||||
distance: { type: Number },
|
||||
actual_cost: { type: Number },
|
||||
|
||||
// 1. Posted Shipments (Posted)
|
||||
// 2. Shipments Loading (Loading)
|
||||
// 3. Enroute Shipments (In Transit)
|
||||
// 4. Shipments in Unloading (Unloading)
|
||||
// 5. Shipments pending finding truck
|
||||
status: { type: String, default: 'Draft', enum: ['Draft', 'Published', 'Completed', 'Closed'] },
|
||||
load_status: { type: String, enum: ['Published', 'Loading', 'Transit', 'Downloading', 'Delivered'] },
|
||||
|
||||
|
||||
contract_start_date: { type: Date },
|
||||
contract_end_date: { type: Date },
|
||||
|
||||
est_loading_date: { type: Date },
|
||||
est_unloading_date: { type: Date },
|
||||
|
||||
published_date: { type: Date },
|
||||
loaded_date: { type: Date },
|
||||
transit_date: { type: Date },
|
||||
delivered_date: { type: Date },
|
||||
load_status_updated: { type: Date, default: () => Date.now() },
|
||||
notes: { type: String },
|
||||
|
||||
payment_term: { type: String },
|
||||
terms_and_conditions: { type: String },
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "loads", schema );
|
||||
8
src/lib/Models/mailer.model.js
Normal file
8
src/lib/Models/mailer.model.js
Normal file
@@ -0,0 +1,8 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
text: { type: String, required: true }
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "mailer", schema );
|
||||
10
src/lib/Models/memberships.model.js
Normal file
10
src/lib/Models/memberships.model.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
name: { type: String, required: true }, // free, pro
|
||||
price: { type: Number },
|
||||
validity : { type: Number }, // number 0f days
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "memberships", schema );
|
||||
10
src/lib/Models/meta-data.model.js
Normal file
10
src/lib/Models/meta-data.model.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
meta_group: { type: Schema.Types.ObjectId, ref: 'metagroups'},// settings, terms, collaborator
|
||||
meta_key: { type: String, required: true }, // collaborator
|
||||
meta_value: { type: String }
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "metadatas", schema );
|
||||
11
src/lib/Models/meta-groups.model.js
Normal file
11
src/lib/Models/meta-groups.model.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
group_label: { type: String, required: true },
|
||||
group_key: { type: String, required: true },
|
||||
group_field_type: { type: String,default:'text' }, // text, textarea, html, select
|
||||
group_options: [{ type: String }]
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "metagroups", schema );
|
||||
26
src/lib/Models/news.model.js
Normal file
26
src/lib/Models/news.model.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const attachFile = new Schema({
|
||||
file:{ type: String },
|
||||
originalname:{ type: String },
|
||||
mimetype:{ type: String },
|
||||
focus_point:[{
|
||||
thumbnail:{ type: String, default:"main" },
|
||||
x:{ type: Number },
|
||||
y:{ type: Number },
|
||||
w:{ type: Number },
|
||||
h:{ type: Number },
|
||||
s:{ type: Number }
|
||||
}]
|
||||
});
|
||||
|
||||
const schema = new Schema({
|
||||
title : { type: String, required: true },
|
||||
description : { type: String, required: true },
|
||||
link_text : { type: String, required: true },
|
||||
link_url : { type: String, required: true },
|
||||
news_image: attachFile,
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "news", schema );
|
||||
11
src/lib/Models/orders.model.js
Normal file
11
src/lib/Models/orders.model.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
load: { type: Schema.Types.ObjectId, ref: 'loads' },
|
||||
shipper: { type: Schema.Types.ObjectId, ref: 'companies' }, // how offers load
|
||||
carrier: { type: Schema.Types.ObjectId, ref: 'companies' }, // how transport the load
|
||||
vehicle: { type: Schema.Types.ObjectId, ref: 'vehicles' },
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "orders", schema );
|
||||
8
src/lib/Models/product-categories.model.js
Normal file
8
src/lib/Models/product-categories.model.js
Normal file
@@ -0,0 +1,8 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
name: { type: String, required: true } // fruit, boxes, wood
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "productcategories", schema );
|
||||
9
src/lib/Models/products.model.js
Normal file
9
src/lib/Models/products.model.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
name: { type: String, required: true },
|
||||
segment: { type: String},
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "products", schema );
|
||||
21
src/lib/Models/proposals.model.js
Normal file
21
src/lib/Models/proposals.model.js
Normal file
@@ -0,0 +1,21 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
load: { type: Schema.Types.ObjectId, ref: 'loads' },
|
||||
shipper: { type: Schema.Types.ObjectId, ref: 'companies' }, // how offers load
|
||||
carrier: { type: Schema.Types.ObjectId, ref: 'companies' }, // how transport the load
|
||||
vehicle: { type: Schema.Types.ObjectId, ref: 'vehicles' },
|
||||
|
||||
bidder: { type: Schema.Types.ObjectId, ref: 'users' },
|
||||
|
||||
comment: { type: String },
|
||||
|
||||
is_withdrawn: { type: Boolean, default: false },
|
||||
|
||||
accepted_by: { type: Schema.Types.ObjectId, ref: 'users' },
|
||||
accepted_date: { type: Date },
|
||||
is_accepted: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "proposals", schema );
|
||||
12
src/lib/Models/states.model.js
Normal file
12
src/lib/Models/states.model.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
country_name: { type: String},
|
||||
country_code: { type: String },
|
||||
state_name: { type: String, required: true },
|
||||
state_code: { type: String }
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "states", schema );
|
||||
|
||||
12
src/lib/Models/trackings.model.js
Normal file
12
src/lib/Models/trackings.model.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const schema = new Schema({
|
||||
lat: { type: String },
|
||||
lng: { type: String },
|
||||
user: { type: Schema.Types.ObjectId, ref: 'users' },
|
||||
load: { type: Schema.Types.ObjectId, ref: 'loads' },
|
||||
vehicle: { type: Schema.Types.ObjectId, ref: 'vehicles' },
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "trackings", schema );
|
||||
64
src/lib/Models/users.model.js
Normal file
64
src/lib/Models/users.model.js
Normal file
@@ -0,0 +1,64 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const pointSchema = new Schema({
|
||||
type: {
|
||||
type: String,
|
||||
enum: ['Point'],
|
||||
required: true
|
||||
},
|
||||
coordinates: {
|
||||
type: [Number],
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const schema = new Schema({
|
||||
first_name: { type: String },
|
||||
last_name: { type: String },
|
||||
middle_name: { type: String },
|
||||
email: { type: String, unique: true, lowercase: true },
|
||||
password: { type: String },
|
||||
phone: { type: String },
|
||||
phone2: { type: String },
|
||||
permissions: [{ type: String, default: 'role_admin' }],
|
||||
gender: { type: String },
|
||||
address: { type: String },
|
||||
dob: { type: String },
|
||||
|
||||
// vehicle_status: { type: String, enum: ['Free', 'Loading', 'Moving', 'Downloading'] },
|
||||
job_role: { type: String }, // admin, owner, driver, staff
|
||||
|
||||
employee_id: { type: String }, //EM-1000-1 EM-1000-2
|
||||
company: { type: Schema.Types.ObjectId, ref: 'companies' },
|
||||
branch: { type: Schema.Types.ObjectId, ref: 'branches' },
|
||||
|
||||
vehicle: { type: Schema.Types.ObjectId, ref: 'vehicles' },
|
||||
|
||||
active_load: { type: Schema.Types.ObjectId, ref: 'loads' },
|
||||
|
||||
categories: [{ type: Schema.Types.ObjectId, ref: 'product-categories' }],
|
||||
user_city: [{ type: String }],
|
||||
user_state: [{ type: String }],
|
||||
user_description: { type: String },
|
||||
truck_type: [{ type: String }],
|
||||
|
||||
last_location_lat: { type: String },
|
||||
last_location_lng: { type: String },
|
||||
last_location_geo: { type: pointSchema },
|
||||
last_location_time: { type: Date },
|
||||
|
||||
isVerified: { type: Boolean },
|
||||
verifyToken: { type: String },
|
||||
verifyShortToken: { type: String },
|
||||
verifyExpires: { type: Date }, // or a long integer
|
||||
verifyChanges: { type: Object }, // an object (key-value map), e.g. { field: "value" }
|
||||
resetToken: { type: String },
|
||||
resetShortToken: { type: String },
|
||||
resetExpires: { type: Date }, // or a long integer
|
||||
resetAttempts: { type: Number },
|
||||
|
||||
is_hidden: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "users", schema );
|
||||
55
src/lib/Models/vehicles.model.js
Normal file
55
src/lib/Models/vehicles.model.js
Normal file
@@ -0,0 +1,55 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const pointSchema = new Schema({
|
||||
type: {
|
||||
type: String,
|
||||
enum: ['Point'],
|
||||
required: true
|
||||
},
|
||||
coordinates: {
|
||||
type: [Number],
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const schema = new Schema({
|
||||
company: { type: Schema.Types.ObjectId, ref: 'companies' }, // carrier
|
||||
|
||||
vehicle_code: { type: String },
|
||||
vehicle_name: { type: String },
|
||||
vehicle_number: { type: String }, //camion001 002 etc
|
||||
circulation_serial_number: { type: String },
|
||||
trailer_plate_1: { type: String },
|
||||
trailer_plate_2: { type: String },
|
||||
truck_type: { type: String },
|
||||
tyre_type: { type: String },
|
||||
city: { type: String },
|
||||
state: { type: String },
|
||||
|
||||
background_tracking: { type: Boolean, default: false },
|
||||
|
||||
status: { type: String, enum: ['Free', 'Loading', 'Transit', 'Downloading'] },
|
||||
|
||||
categories: [{ type: Schema.Types.ObjectId, ref: 'product-categories' }],
|
||||
|
||||
published_date: { type: Date },
|
||||
available_date: { type: String },
|
||||
is_available: { type: Boolean, default: false },
|
||||
|
||||
active_load: { type: Schema.Types.ObjectId, ref: 'loads' },
|
||||
load_shipper: { type: Schema.Types.ObjectId, ref: 'companies' },
|
||||
|
||||
available_in: [{ type: String }],
|
||||
|
||||
destino: { type: String },
|
||||
driver: { type: Schema.Types.ObjectId, ref: 'users' },
|
||||
notes: { type: String },
|
||||
|
||||
last_location_lat: { type: String },
|
||||
last_location_lng: { type: String },
|
||||
last_location_geo: { type: pointSchema },
|
||||
last_location_time: { type: Date },
|
||||
});
|
||||
|
||||
module.exports = mongoose.model( "vehicles", schema );
|
||||
28
src/lib/jwtValidator.js
Normal file
28
src/lib/jwtValidator.js
Normal file
@@ -0,0 +1,28 @@
|
||||
'user strict';
|
||||
const { ROOT_PATH, API_CONFIG } = process.env;
|
||||
const apiConfig = require( `${ROOT_PATH}/${API_CONFIG}` );
|
||||
const jwt = require('jsonwebtoken');
|
||||
const jwtSecret = apiConfig.authentication.jwtSecret;
|
||||
|
||||
function middleware( req, res, next ){
|
||||
if( req.JWT ){
|
||||
req.JWT.isValid = false;
|
||||
try{
|
||||
req.JWT.payload = jwt.verify( req.JWT.raw, jwtSecret );
|
||||
if( !req.JWT.payload ){
|
||||
return res.status(401).send({error:"Unauthorized",code:401});
|
||||
}else{
|
||||
req.JWT.isValid = true;
|
||||
}
|
||||
}catch( err ){
|
||||
return res.status(401).send({error:"Unauthorized",code:401});
|
||||
}
|
||||
next();
|
||||
}else{
|
||||
return res.status(401).send({error:"Unauthorized",code:401});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
middleware
|
||||
};
|
||||
Reference in New Issue
Block a user