feat: Adding missing event handlers (templates)

This commit is contained in:
Josepablo C
2025-07-22 22:19:20 -06:00
parent e10bf050a2
commit b5e9ced8ad
11 changed files with 371 additions and 43 deletions

View File

@@ -0,0 +1,40 @@
'user strict';
const { emailEvent , EMAIL_EVENTS } = require( '../../../MailClient' );
async function sendEmailEvent( EVENT_ID, load, carrier, product, vehicle, driver ){
const driver_name = `${driver.first_name} ${driver.last_name}`;
/** Get the list of emails from the load alert_list field */
const list_of_emails = load.alert_list || [];
for( const observer_email of list_of_emails ){
emailEvent(
EVENT_ID,
observer_email,
{
code : load.shipment_code,
date : new Date( load.est_loading_date ).toLocaleString("es-MX",{year: 'numeric', month: '2-digit', day: '2-digit'}),
company: carrier.company_name,
product: product.name,
plate: vehicle.circulation_serial_number,
truck_type: vehicle.truck_type,
driver: driver_name,
note: load.notes,
}
);
}
}
async function onProposalAccepted( load, carrier, product, vehicle, driver ){
await sendEmailEvent( EMAIL_EVENTS.CLIENT_PROPOSAL_ACCEPTED, load, carrier, product, vehicle, driver );
}
async function onProposalDriverChanged( load, carrier, product, vehicle, driver ){
await sendEmailEvent( EMAIL_EVENTS.CLIENT_PROPOSAL_DRIVER_CHANGED, load, carrier, product, vehicle, driver );
}
async function onProposalVehicleChanged( load, carrier, product, vehicle, driver ){
await sendEmailEvent( EMAIL_EVENTS.CLIENT_PROPOSAL_VEHICLE_CHANGED, load, carrier, product, vehicle, driver );
}
module.exports = { onProposalAccepted, onProposalDriverChanged, onProposalVehicleChanged };

View File

@@ -0,0 +1,40 @@
'user strict';
const { emailEvent , EMAIL_EVENTS } = require( '../../../MailClient' );
async function sendEmailEvent( EVENT_ID, warehouse, load, carrier, product, vehicle, driver ){
const driver_name = `${driver.first_name} ${driver.last_name}`;
/** Get the list of emails from the warehouse alert_list field */
const list_of_emails = warehouse.alert_list || [];
for( const observer_email of list_of_emails ){
emailEvent(
EVENT_ID,
observer_email,
{
code : load.shipment_code,
date : new Date( load.est_loading_date ).toLocaleString("es-MX",{year: 'numeric', month: '2-digit', day: '2-digit'}),
company: carrier.company_name,
product: product.name,
plate: vehicle.circulation_serial_number,
truck_type: vehicle.truck_type,
driver: driver_name,
note: load.notes,
}
);
}
}
async function onProposalAccepted( warehouse, load, carrier, product, vehicle, driver ){
await sendEmailEvent( EMAIL_EVENTS.WAREHOUSE_PROPOSAL_ACCEPTED, warehouse, load, carrier, product, vehicle, driver );
}
async function onProposalDriverChanged( warehouse, load, carrier, product, vehicle, driver ){
await sendEmailEvent( EMAIL_EVENTS.WAREHOUSE_PROPOSAL_DRIVER_CHANGED, warehouse, load, carrier, product, vehicle, driver );
}
async function onProposalVehicleChanged( warehouse, load, carrier, product, vehicle, driver ){
await sendEmailEvent( EMAIL_EVENTS.WAREHOUSE_PROPOSAL_VEHICLE_CHANGED, warehouse, load, carrier, product, vehicle, driver );
}
module.exports = { onProposalAccepted, onProposalDriverChanged, onProposalVehicleChanged };

View File

@@ -0,0 +1,59 @@
'user strict';
const ClientEvents = require('./Client');
const WarehouseEvents = require('./Warehouse');
const NOTIFICATION_TYPE={
CLIENT:0,
WAREHOUSE:1,
BOTH:2,
}
async function onProposalAccepted( notification_type, content ){
const { warehouse, load, carrier, product, vehicle, driver } = content;
switch ( notification_type ){
case NOTIFICATION_TYPE.CLIENT:
return await ClientEvents.onProposalAccepted( load, carrier, product, vehicle, driver );
case NOTIFICATION_TYPE.WAREHOUSE:
return await WarehouseEvents.onProposalAccepted( warehouse, load, carrier, product, vehicle, driver );
case NOTIFICATION_TYPE.BOTH:
await WarehouseEvents.onProposalAccepted( warehouse, load, carrier, product, vehicle, driver );
await ClientEvents.onProposalAccepted( load, carrier, product, vehicle, driver );
default:
return;
}
}
async function onProposalDriverChanged( notification_type, content ){
const { warehouse, load, carrier, product, vehicle, driver } = content;
switch ( notification_type ){
case NOTIFICATION_TYPE.CLIENT:
return await ClientEvents.onProposalDriverChanged( load, carrier, product, vehicle, driver );
case NOTIFICATION_TYPE.WAREHOUSE:
return await WarehouseEvents.onProposalDriverChanged( warehouse, load, carrier, product, vehicle, driver );
case NOTIFICATION_TYPE.BOTH:
await WarehouseEvents.onProposalDriverChanged( warehouse, load, carrier, product, vehicle, driver );
await ClientEvents.onProposalDriverChanged( load, carrier, product, vehicle, driver );
default:
return;
}
}
async function onProposalVehicleChanged( notification_type, content ){
const { warehouse, load, carrier, product, vehicle, driver } = content;
switch ( notification_type ){
case NOTIFICATION_TYPE.CLIENT:
return await ClientEvents.onProposalVehicleChanged( load, carrier, product, vehicle, driver );
case NOTIFICATION_TYPE.WAREHOUSE:
return await WarehouseEvents.onProposalVehicleChanged( warehouse, load, carrier, product, vehicle, driver );
case NOTIFICATION_TYPE.BOTH:
await WarehouseEvents.onProposalVehicleChanged( warehouse, load, carrier, product, vehicle, driver );
await ClientEvents.onProposalVehicleChanged( load, carrier, product, vehicle, driver );
default:
return;
}
}
module.exports = { NOTIFICATION_TYPE, onProposalAccepted, onProposalDriverChanged, onProposalVehicleChanged };

View File

@@ -2,6 +2,7 @@
const { getModel } = require( '../../../Models' ); const { getModel } = require( '../../../Models' );
const onAcceptedEvents = require('./onAccepted'); const onAcceptedEvents = require('./onAccepted');
const onVehicleChanged = require('./onVehicleChanged');
const branchesModel = getModel('branches') const branchesModel = getModel('branches')
const vehiclesModel = getModel('vehicles'); const vehiclesModel = getModel('vehicles');
@@ -98,11 +99,12 @@ async function onProposalAccepted( userId, proposalId ){
const driver = await usersModel.findById( load.driver ) || {}; const driver = await usersModel.findById( load.driver ) || {};
if( origin_warehouse ){ if( origin_warehouse ){
await onAcceptedEvents.sendWarehouseEmail( origin_warehouse, load, carrier, product, vehicle, driver ); await onAcceptedEvents.sendWarehouseNotification( origin_warehouse, load, carrier, product, vehicle, driver );
} }
if( destination_warehouse ){ if( destination_warehouse ){
await onAcceptedEvents.sendWarehouseEmail( destination_warehouse, load, carrier, product, vehicle, driver ); await onAcceptedEvents.sendWarehouseNotification( destination_warehouse, load, carrier, product, vehicle, driver );
} }
await onAcceptedEvents.sendClientNotification( load, carrier, product, vehicle, driver );
} }
/** /**
@@ -136,6 +138,21 @@ async function onProposalVehicleChanged( userId, proposalId ){
} }
); );
} }
const load = await loadsModel.findById( proposal.load );
const origin_warehouse = await branchesModel.findById( load.origin_warehouse );
const destination_warehouse = await branchesModel.findById( load.destination_warehouse );
const carrier = await companiesModel.findById( load.carrier ) || {};
const product = await productsModel.findById( load.product ) || {};
const driver = await usersModel.findById( load.driver ) || {};
if( origin_warehouse ){
await onVehicleChanged.sendWarehouseNotification( origin_warehouse, load, carrier, product, vehicle, driver );
}
if( destination_warehouse ){
await onVehicleChanged.sendWarehouseNotification( destination_warehouse, load, carrier, product, vehicle, driver );
}
await onVehicleChanged.sendClientNotification( load, carrier, product, vehicle, driver )
} }
module.exports = { onProposalCreate, onProposalRejected, onProposalAccepted, onProposalVehicleChanged }; module.exports = { onProposalCreate, onProposalRejected, onProposalAccepted, onProposalVehicleChanged };

View File

@@ -1,6 +1,6 @@
'user strict'; 'user strict';
const { getModel } = require( '../../../Models' ); const { getModel } = require( '../../../Models' );
const warehouseEvents = require('../Warehouse'); const ObserversEvents = require('../Observers');
const notificationsModel = getModel('notifications'); const notificationsModel = getModel('notifications');
/** /**
@@ -22,8 +22,22 @@ async function sendNotification( proposal, load ){
await notification.save(); await notification.save();
} }
async function sendWarehouseEmail( warehouse, load, carrier, product, vehicle, driver ){ async function sendWarehouseNotification( warehouse, load, carrier, product, vehicle, driver ){
await warehouseEvents.onProposalAccepted( warehouse, load, carrier, product, vehicle, driver ); await ObserversEvents.onProposalAccepted(
ObserversEvents.NOTIFICATION_TYPE.WAREHOUSE,
{ warehouse, load, carrier, product, vehicle, driver }
);
} }
module.exports = { sendNotification, sendWarehouseEmail }; async function sendClientNotification( load, carrier, product, vehicle, driver ){
await ObserversEvents.onProposalAccepted(
ObserversEvents.NOTIFICATION_TYPE.CLIENT,
{ load, carrier, product, vehicle, driver }
);
}
module.exports = {
sendNotification,
sendWarehouseNotification,
sendClientNotification
};

View File

@@ -0,0 +1,21 @@
'user strict';
const ObserversEvents = require('../Observers');
async function sendWarehouseNotification( warehouse, load, carrier, product, vehicle, driver ){
await ObserversEvents.onProposalVehicleChanged(
ObserversEvents.NOTIFICATION_TYPE.WAREHOUSE,
{ warehouse, load, carrier, product, vehicle, driver }
);
}
async function sendClientNotification( load, carrier, product, vehicle, driver ){
await ObserversEvents.onProposalVehicleChanged(
ObserversEvents.NOTIFICATION_TYPE.CLIENT,
{ load, carrier, product, vehicle, driver }
);
}
module.exports = {
sendWarehouseNotification,
sendClientNotification
};

View File

@@ -1,5 +1,6 @@
'user strict'; 'user strict';
const { getModel } = require( '../../../Models' ); const { getModel } = require( '../../../Models' );
const onDriverChanged = require('./onDriverChanged');
const usersModel = getModel('users'); const usersModel = getModel('users');
const vehiclesModel = getModel('vehicles'); const vehiclesModel = getModel('vehicles');
@@ -19,6 +20,10 @@ async function onVehicleDriverChanged( userId, vehicleId ){
is_completed: false is_completed: false
}); });
/*********************************************
* Data update process
*********************************************/
/// Update proposals related to this load. Ideally, just one. /// Update proposals related to this load. Ideally, just one.
for( const proposal of proposal_list ){ for( const proposal of proposal_list ){
/// Update Load: /// Update Load:
@@ -28,6 +33,33 @@ async function onVehicleDriverChanged( userId, vehicleId ){
vehicle : vehicle vehicle : vehicle
} ); } );
} }
/*********************************************
* Notifications process:
* Separating this loop from the data update allows
* to catch problems on the notification
* wihtout affecting the data population.
* If notification doesn't work is not that big of a deal
* compared with if the data is not populated propertly.
*********************************************/
/// Send the email to the warehouse only if the proposal is already accepted and associated to the vehicle.
for( const proposal of proposal_list ){
if( proposal.is_accepted === true ){
const load = await loadsModel.findById( proposal.load );
const origin_warehouse = await branchesModel.findById( load.origin_warehouse );
const destination_warehouse = await branchesModel.findById( load.destination_warehouse );
const carrier = await companiesModel.findById( load.carrier ) || {};
const product = await productsModel.findById( load.product ) || {};
if( origin_warehouse ){
await onDriverChanged.sendWarehouseNotification( origin_warehouse, load, carrier, product, vehicle, driver );
}
if( destination_warehouse ){
await onDriverChanged.sendWarehouseNotification( destination_warehouse, load, carrier, product, vehicle, driver );
}
}
}
} }
module.exports = { onVehicleDriverChanged }; module.exports = { onVehicleDriverChanged };

View File

@@ -0,0 +1,13 @@
'user strict';
const ObserversEvents = require('../Observers');
async function sendWarehouseNotification( warehouse, load, carrier, product, vehicle, driver ){
await ObserversEvents.onProposalDriverChanged(
ObserversEvents.NOTIFICATION_TYPE.WAREHOUSE,
{ warehouse, load, carrier, product, vehicle, driver }
);
}
module.exports = {
sendWarehouseNotification
};

View File

@@ -1,31 +0,0 @@
'user strict';
const { getModel } = require( '../../../Models' );
const { emailEvent , EMAIL_EVENTS } = require( '../../MailClient' );
const usersModel = getModel('users');
async function onProposalAccepted( warehouse, load, carrier, product, vehicle, driver ){
const driver_name = `${driver.first_name} ${driver.last_name}`;
/** Get the list of emails from the warehouse alert_list field */
const list_of_warehouse_emails = warehouse.alert_list || [];
for( const warehouse_email of list_of_warehouse_emails ){
emailEvent(
EMAIL_EVENTS.WAREHOUSE_DRIVER_ASSIGNED,
warehouse_email,
{
code : load.shipment_code,
date : new Date( load.est_loading_date ).toLocaleString("es-MX",{year: 'numeric', month: '2-digit', day: '2-digit'}),
company: carrier.company_name,
product: product.name,
plate: vehicle.circulation_serial_number,
truck_type: vehicle.truck_type,
driver: driver_name,
note: load.notes,
}
);
}
}
module.exports = { onProposalAccepted };

View File

@@ -91,11 +91,64 @@ async function ContactEmail( receiver, content ){
return await sendMailTemplate( receiver, subject, html ); return await sendMailTemplate( receiver, subject, html );
} }
async function WarehouseDriverAssignedNotification( receiver, content ){ async function WarehouseProposalAccepted( receiver, content ){
const subject = "[ETA] Warehouse Notification"; const subject = "[ETA] Warehouse Notification";
const { code, date, company, product, plate, truck_type, driver, note } = content; const { code, date, company, product, plate, truck_type, driver, note } = content;
const html = warehouseNotificationTemplate( code, date, company, product, plate, truck_type, driver, note ); const html = warehouseNotificationTemplate( code, date, company, product, plate, truck_type, driver, note );
return await sendMailTemplate( receiver, subject, html ); return await sendMailTemplate( receiver, subject, html );
} }
module.exports = { AccountVerifyEmail, AccountConfirmed, AccountPwdResetEmail, ContactEmail, StandAloneContactEmail, WarehouseDriverAssignedNotification }; async function WarehouseProposalDriverChanged( receiver, content ){
console.log("WarehouseProposalDriverChanged email event not yet implemented");
}
async function WarehouseProposalVehicleChanged( receiver, content ){
console.log("WarehouseProposalVehicleChanged email event not yet implemented");
}
async function ClientProposalAccepted( receiver, content ){
console.log("ClientProposalAccepted email event not yet implemented");
}
async function ClientProposalDriverChanged( receiver, content ){
console.log("ClientProposalDriverChanged email event not yet implemented");
}
async function ClientProposalVehicleChanged( receiver, content ){
console.log("ClientProposalVehicleChanged email event not yet implemented");
}
async function ClientLoadOnLoading( receiver, content ){
console.log("ClientLoadOnLoading email event not yet implemented");
}
async function ClientLoadInTransit( receiver, content ){
console.log("ClientLoadInTransit email event not yet implemented");
}
async function ClientLoadOnDownload( receiver, content ){
console.log("ClientLoadOnDownload email event not yet implemented");
}
async function ClientLoadDelivered( receiver, content ){
console.log("ClientLoadDelivered email event not yet implemented");
}
module.exports = {
AccountVerifyEmail,
AccountConfirmed,
AccountPwdResetEmail,
ContactEmail,
StandAloneContactEmail,
WarehouseProposalAccepted,
WarehouseProposalDriverChanged,
WarehouseProposalVehicleChanged,
ClientProposalAccepted,
ClientProposalDriverChanged,
ClientProposalVehicleChanged,
ClientLoadOnLoading,
ClientLoadInTransit,
ClientLoadOnDownload,
ClientLoadDelivered
};

View File

@@ -1,12 +1,37 @@
'user strict'; 'user strict';
const { AccountVerifyEmail, AccountConfirmed, AccountPwdResetEmail, ContactEmail, StandAloneContactEmail, WarehouseDriverAssignedNotification } = require('./StandAlone.handler'); const {
AccountVerifyEmail,
AccountConfirmed,
AccountPwdResetEmail,
ContactEmail,
StandAloneContactEmail,
WarehouseProposalAccepted,
WarehouseProposalDriverChanged,
WarehouseProposalVehicleChanged,
ClientProposalAccepted,
ClientProposalDriverChanged,
ClientProposalVehicleChanged,
ClientLoadOnLoading,
ClientLoadInTransit,
ClientLoadOnDownload,
ClientLoadDelivered
} = require('./StandAlone.handler');
const EMAIL_EVENTS={ const EMAIL_EVENTS={
ACCOUNT_VERIFY:1, ACCOUNT_VERIFY:1,
ACCOUNT_CONFIRMED:2, ACCOUNT_CONFIRMED:2,
ACCOUNT_PWD_RESET:3, ACCOUNT_PWD_RESET:3,
CONTACT_EMAIL:4, CONTACT_EMAIL:4,
WAREHOUSE_DRIVER_ASSIGNED:5, WAREHOUSE_PROPOSAL_ACCEPTED:5,
WAREHOUSE_PROPOSAL_DRIVER_CHANGED:6,
WAREHOUSE_PROPOSAL_VEHICLE_CHANGED:7,
CLIENT_PROPOSAL_ACCEPTED:8,
CLIENT_PROPOSAL_DRIVER_CHANGED:9,
CLIENT_PROPOSAL_VEHICLE_CHANGED:10,
CLIENT_LOAD_ON_LOADING:11,
CLIENT_LOAD_IN_TRANSIT:12,
CLIENT_LOAD_ON_DOWNLOAD:13,
CLIENT_LOAD_DELIVERED:14,
} }
/** /**
@@ -38,9 +63,54 @@ async function emailEvent( eventId, receiver , content ){
return await ContactEmail( receiver, content ); return await ContactEmail( receiver, content );
} }
break; break;
case EMAIL_EVENTS.WAREHOUSE_DRIVER_ASSIGNED: case EMAIL_EVENTS.WAREHOUSE_PROPOSAL_ACCEPTED:
{ {
return await WarehouseDriverAssignedNotification( receiver, content ); return await WarehouseProposalAccepted( receiver, content );
}
break;
case EMAIL_EVENTS.WAREHOUSE_PROPOSAL_DRIVER_CHANGED:
{
return await WarehouseProposalDriverChanged( receiver, content );
}
break;
case EMAIL_EVENTS.WAREHOUSE_PROPOSAL_VEHICLE_CHANGED:
{
return await WarehouseProposalVehicleChanged( receiver, content );
}
break;
case EMAIL_EVENTS.CLIENT_PROPOSAL_ACCEPTED:
{
return await ClientProposalAccepted( receiver, content );
}
break;
case EMAIL_EVENTS.CLIENT_PROPOSAL_DRIVER_CHANGED:
{
return await ClientProposalDriverChanged( receiver, content );
}
break;
case EMAIL_EVENTS.CLIENT_PROPOSAL_VEHICLE_CHANGED:
{
return await ClientProposalVehicleChanged( receiver, content );
}
break;
case EMAIL_EVENTS.CLIENT_LOAD_ON_LOADING:
{
return await ClientLoadOnLoading( receiver, content );
}
break;
case EMAIL_EVENTS.CLIENT_LOAD_IN_TRANSIT:
{
return await ClientLoadInTransit( receiver, content );
}
break;
case EMAIL_EVENTS.CLIENT_LOAD_ON_DOWNLOAD:
{
return await ClientLoadOnDownload( receiver, content );
}
break;
case EMAIL_EVENTS.CLIENT_LOAD_DELIVERED:
{
return await ClientLoadDelivered( receiver, content );
} }
break; break;
default: default: