diff --git a/v1/src/lib/Handlers/Events/Observers/Client/index.js b/v1/src/lib/Handlers/Events/Observers/Client/index.js new file mode 100644 index 0000000..45db14b --- /dev/null +++ b/v1/src/lib/Handlers/Events/Observers/Client/index.js @@ -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 }; diff --git a/v1/src/lib/Handlers/Events/Observers/Warehouse/index.js b/v1/src/lib/Handlers/Events/Observers/Warehouse/index.js new file mode 100644 index 0000000..d54b594 --- /dev/null +++ b/v1/src/lib/Handlers/Events/Observers/Warehouse/index.js @@ -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 }; diff --git a/v1/src/lib/Handlers/Events/Observers/index.js b/v1/src/lib/Handlers/Events/Observers/index.js new file mode 100644 index 0000000..811e2b3 --- /dev/null +++ b/v1/src/lib/Handlers/Events/Observers/index.js @@ -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 }; diff --git a/v1/src/lib/Handlers/Events/Proposals/index.js b/v1/src/lib/Handlers/Events/Proposals/index.js index 6fa9ac6..41c71ce 100644 --- a/v1/src/lib/Handlers/Events/Proposals/index.js +++ b/v1/src/lib/Handlers/Events/Proposals/index.js @@ -2,6 +2,7 @@ const { getModel } = require( '../../../Models' ); const onAcceptedEvents = require('./onAccepted'); +const onVehicleChanged = require('./onVehicleChanged'); const branchesModel = getModel('branches') const vehiclesModel = getModel('vehicles'); @@ -98,11 +99,12 @@ async function onProposalAccepted( userId, proposalId ){ const driver = await usersModel.findById( load.driver ) || {}; 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 ){ - 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 }; diff --git a/v1/src/lib/Handlers/Events/Proposals/onAccepted.js b/v1/src/lib/Handlers/Events/Proposals/onAccepted.js index f75f580..f773b10 100644 --- a/v1/src/lib/Handlers/Events/Proposals/onAccepted.js +++ b/v1/src/lib/Handlers/Events/Proposals/onAccepted.js @@ -1,6 +1,6 @@ 'user strict'; const { getModel } = require( '../../../Models' ); -const warehouseEvents = require('../Warehouse'); +const ObserversEvents = require('../Observers'); const notificationsModel = getModel('notifications'); /** @@ -22,8 +22,22 @@ async function sendNotification( proposal, load ){ await notification.save(); } -async function sendWarehouseEmail( warehouse, load, carrier, product, vehicle, driver ){ - await warehouseEvents.onProposalAccepted( warehouse, load, carrier, product, vehicle, driver ); +async function sendWarehouseNotification( 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 +}; diff --git a/v1/src/lib/Handlers/Events/Proposals/onVehicleChanged.js b/v1/src/lib/Handlers/Events/Proposals/onVehicleChanged.js new file mode 100644 index 0000000..a399462 --- /dev/null +++ b/v1/src/lib/Handlers/Events/Proposals/onVehicleChanged.js @@ -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 +}; diff --git a/v1/src/lib/Handlers/Events/Vehicles/index.js b/v1/src/lib/Handlers/Events/Vehicles/index.js index 2d155e3..b0bc43c 100644 --- a/v1/src/lib/Handlers/Events/Vehicles/index.js +++ b/v1/src/lib/Handlers/Events/Vehicles/index.js @@ -1,5 +1,6 @@ 'user strict'; const { getModel } = require( '../../../Models' ); +const onDriverChanged = require('./onDriverChanged'); const usersModel = getModel('users'); const vehiclesModel = getModel('vehicles'); @@ -19,6 +20,10 @@ async function onVehicleDriverChanged( userId, vehicleId ){ is_completed: false }); + /********************************************* + * Data update process + *********************************************/ + /// Update proposals related to this load. Ideally, just one. for( const proposal of proposal_list ){ /// Update Load: @@ -28,6 +33,33 @@ async function onVehicleDriverChanged( userId, vehicleId ){ 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 }; diff --git a/v1/src/lib/Handlers/Events/Vehicles/onDriverChanged.js b/v1/src/lib/Handlers/Events/Vehicles/onDriverChanged.js new file mode 100644 index 0000000..5238375 --- /dev/null +++ b/v1/src/lib/Handlers/Events/Vehicles/onDriverChanged.js @@ -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 +}; diff --git a/v1/src/lib/Handlers/Events/Warehouse/index.js b/v1/src/lib/Handlers/Events/Warehouse/index.js deleted file mode 100644 index d5ba548..0000000 --- a/v1/src/lib/Handlers/Events/Warehouse/index.js +++ /dev/null @@ -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 }; diff --git a/v1/src/lib/Handlers/MailClient/StandAlone.handler.js b/v1/src/lib/Handlers/MailClient/StandAlone.handler.js index 632ade6..b1d630a 100644 --- a/v1/src/lib/Handlers/MailClient/StandAlone.handler.js +++ b/v1/src/lib/Handlers/MailClient/StandAlone.handler.js @@ -91,11 +91,64 @@ async function ContactEmail( receiver, content ){ return await sendMailTemplate( receiver, subject, html ); } -async function WarehouseDriverAssignedNotification( receiver, content ){ +async function WarehouseProposalAccepted( receiver, content ){ const subject = "[ETA] Warehouse Notification"; const { code, date, company, product, plate, truck_type, driver, note } = content; const html = warehouseNotificationTemplate( code, date, company, product, plate, truck_type, driver, note ); 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 +}; diff --git a/v1/src/lib/Handlers/MailClient/index.js b/v1/src/lib/Handlers/MailClient/index.js index b9637e9..b9d5270 100644 --- a/v1/src/lib/Handlers/MailClient/index.js +++ b/v1/src/lib/Handlers/MailClient/index.js @@ -1,12 +1,37 @@ '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={ ACCOUNT_VERIFY:1, ACCOUNT_CONFIRMED:2, ACCOUNT_PWD_RESET:3, 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 ); } 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; default: