feat: Adding load-templates endpoint

This commit is contained in:
Josepablo Cruz
2026-03-30 19:58:00 -06:00
parent 30cd506862
commit 4310d3a0c3
5 changed files with 181 additions and 1 deletions

View File

@@ -84,7 +84,7 @@ Public resources:
Private resources: Private resources:
- Company and members: `/companies`, `/users` - Company and members: `/companies`, `/users`
- Operations: `/loads`, `/proposals`, `/vehicles`, `/branches`, `/budgets` - Operations: `/loads`, `/load-templates`, `/proposals`, `/vehicles`, `/branches`, `/budgets`
- Files and alerts: `/load-attachments`, `/notifications` - Files and alerts: `/load-attachments`, `/notifications`
- Company private list: `/groups` - Company private list: `/groups`
@@ -308,6 +308,7 @@ Get public fields from registered vehicles.
The following list of endpoints requires a JWT. The following list of endpoints requires a JWT.
- `GET /loads`: List loads related to my company. - `GET /loads`: List loads related to my company.
- `GET /load-templates/all`: List load templates from my company.
- `GET /load-attachments`: List load attachments related to my company or load id. - `GET /load-attachments`: List load attachments related to my company or load id.
- `GET /groups/private`: Get the private group for my company. - `GET /groups/private`: Get the private group for my company.
@@ -445,6 +446,34 @@ This endpoint is part of /loads endpoint
- `GET /:id` : Get attachment file. - `GET /:id` : Get attachment file.
- `GET /` : Get attachment list from company. - `GET /` : Get attachment list from company.
### /load-templates
- `POST /new` : Create a new load template for my company.
- `GET /all` : Get all load templates from my company.
- `GET /:id` : Get a single load template by id.
- `PATCH /:id` : Update a load template by id.
- `DELETE /:id` : Delete a load template by id.
Fields accepted for create/update:
- template_name
- alert_list
- origin_warehouse
- destination_warehouse
- origin
- origin_geo
- destination
- destination_geo
- categories
- product
- truck_type
- tyre_type
- weight
- estimated_cost
- distance
- actual_cost
- notes
### /loads ### /loads
- `GET /find` : Find a list of elements with any of the following fields: - `GET /find` : Find a list of elements with any of the following fields:

View File

@@ -13,6 +13,7 @@ const companies = require('./companies/routes.js');
const loadAttachments = require('./load-attachments/routes.js'); const loadAttachments = require('./load-attachments/routes.js');
const loads = require('./loads/routes.js'); const loads = require('./loads/routes.js');
const loads_driver = require('./loads_driver/routes.js'); const loads_driver = require('./loads_driver/routes.js');
const loadTemplates = require('./load-templates/routes.js');
const proposals = require('./proposals/routes.js'); const proposals = require('./proposals/routes.js');
const users = require('./users/routes.js'); const users = require('./users/routes.js');
const vehicles = require('./vehicles/routes.js'); const vehicles = require('./vehicles/routes.js');
@@ -30,6 +31,7 @@ router.use('/groups', company_groups);
router.use('/load-attachments', loadAttachments ); router.use('/load-attachments', loadAttachments );
router.use('/loads', loads); router.use('/loads', loads);
router.use('/loads_driver', loads_driver); router.use('/loads_driver', loads_driver);
router.use('/load-templates', loadTemplates );
router.use('/notifications', notifications); router.use('/notifications', notifications);
router.use('/proposals', proposals); router.use('/proposals', proposals);
router.use('/users', users); router.use('/users', users);

View File

@@ -0,0 +1,11 @@
'use strict';
const router = require('express').Router();
const services= require('./services.js');
router.post('/new', services.createTemplate);
router.get('/all', services.getAllTemplates);
router.get('/:id', services.getTemplate);
router.patch('/:id', services.updateTemplate);
router.delete('/:id', services.deleteTemplate);
module.exports = router;

View File

@@ -0,0 +1,137 @@
"use strict";
const { getModel } = require( '../../../lib/Models' );
const { getPagination } = require( '../../../lib/Misc.js' );
const LoadTemplatesModel = getModel('load_templates');
function cleanUpData( data ){
/**
* Take the only fields from model that
* should be modifiable by the client.
* The rest are populated on demand by the event handlers.
*/
let data_fields = {
template_name: null,
alert_list: null,
origin_warehouse: null,
destination_warehouse: null,
origin: null,
origin_geo: null,
destination: null,
destination_geo: null,
categories: null,
product: null,
truck_type: null,
tyre_type: null,
weight: null,
estimated_cost: null,
distance: null,
actual_cost: null,
notes: null,
};
let filtered_data = {};
if( Object.keys( data_fields ).length === 0 ){
throw "no data to add";
}
for ( const [key, value] of Object.entries( data_fields ) ) {
if( Object.hasOwn( data, key ) ){
filtered_data[ key ] = data[ key ];
}
}
if( Object.keys( filtered_data ).length === 0 ){
throw "no data to add";
}
return filtered_data;
}
async function createTemplate( req , res ) {
try{
const companyId = req.context.companyId;
const data = cleanUpData( req.body );
data.company = companyId;
const template = new LoadTemplatesModel( data );
await template.save();
res.send( template );
}catch(error){
console.error( error );
return res.status( 500 ).send({ error });
}
}
async function updateTemplate( req , res ) {
try{
const templateId = req.params.id;
const companyId = req.context.companyId;
const data = cleanUpData( req.body );
data.company = companyId;
await LoadTemplatesModel.findByIdAndUpdate( templateId , data );
const template = await LoadTemplatesModel.findById( templateId );
res.send( template );
}catch(error){
console.error( error );
return res.status( 500 ).send({ error });
}
}
async function getTemplate( req, res ){
try{
const templateId = req.params.id;
const template = await LoadTemplatesModel.findById( templateId );
if( ! template ){
return res.status(400).send({ error : "invalid template id"});
}
res.send( template );
}catch(error){
console.error( error );
return res.status( 500 ).send({ error });
}
}
async function deleteTemplate( req, res ){
try{
const companyId = req.context.companyId;
const templateId = req.params.id;
await LoadTemplatesModel.findOneAndDelete({
_id: templateId,
company : companyId
});
res.send({ msg: "item removed successfully" });
}catch(error){
console.error( error );
return res.status( 500 ).send({ error });
}
}
async function getAllTemplates( req, res ){
try{
const companyId = req.context.companyId;
const templateList = await LoadTemplatesModel.find( {
company : companyId
} );
res.send( templateList );
}catch(error){
console.error( error );
return res.status( 500 ).send({ error });
}
}
module.exports = {
createTemplate,
getTemplate,
getAllTemplates,
updateTemplate,
deleteTemplate,
};

View File

@@ -33,6 +33,7 @@ const pointSchema = new Schema({
const schema = new Schema({ const schema = new Schema({
company: { type: Schema.Types.ObjectId, ref: 'companies', required: true }, company: { type: Schema.Types.ObjectId, ref: 'companies', required: true },
template_name : { type: String },
alert_list: [{ type: String, lowercase: true }], alert_list: [{ type: String, lowercase: true }],