Initial commit
This commit is contained in:
137
workers/BlastOrderWorker.js
Normal file
137
workers/BlastOrderWorker.js
Normal file
@ -0,0 +1,137 @@
|
||||
const SandboxedJobMQ = require('bullmq').SandboxedJob;
|
||||
const LibWinston = require('../library/LibWinston');
|
||||
const LibMail = require('../library/LibMail');
|
||||
const moment = require('moment');
|
||||
const GpsTracksModels = require('../models/GpsTracksModels');
|
||||
const OrdersModels = require('../models/OrdersModels');
|
||||
const OrdersVendorsModels = require('../models/OrdersVendorsModels');
|
||||
const UsersModels = require('../models/UsersModels');
|
||||
|
||||
const queueName = process.env.REDIS_QUEUE_BLAST_ORDER;
|
||||
const Logger = LibWinston.initialize(queueName);
|
||||
|
||||
module.exports = async (job) => {
|
||||
try {
|
||||
Logger.log('info', `${queueName} running: ${JSON.stringify(job.opts)}`);
|
||||
const now = moment().unix();
|
||||
const { ord_id, ord_code, base_link } = job.data;
|
||||
if (!ord_id || !ord_code || !base_link) {
|
||||
Logger.log('info', `${queueName} running_fail: data not valid`);
|
||||
return {
|
||||
type: 'fail',
|
||||
message: 'data not valid',
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
const order = await OrdersModels.showOrder({
|
||||
'id': ord_id,
|
||||
});
|
||||
if (order.length < 1) {
|
||||
Logger.log('info', `${queueName} running_fail: order not found on order_id ${ord_id}`);
|
||||
return {
|
||||
type: 'fail',
|
||||
message: `order not found on order_id ${ord_id}`,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
++order[0].count_sch_blast_order;
|
||||
// check is accepted
|
||||
if (order[0].ord_vdr_id) {
|
||||
Logger.log('info', `${queueName} running_info: order have been accepted by another vendor ${order[0].ord_vdr_id} on order_id ${ord_id}`);
|
||||
return {
|
||||
type: 'success',
|
||||
message: 'order have been accepted by another vendor',
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
// Kirim ke admin bahwa tidak ada vendor yang acc 3x10 menit
|
||||
if (order[0].count_sch_blast_order >= 3) {
|
||||
Logger.log('info', `${queueName} running_info: No vendor accept this order on order_id ${ord_id} in 3x10 minutes`);
|
||||
let admins = await UsersModels.getUsersActiveByRole(UsersModels.ROLE_ADMIN);
|
||||
for (let admin of admins) {
|
||||
LibMail.sendAdminInfoNoVdrAccOrd('Order Diabaikan oleh Vendor', admin.email, {
|
||||
trx_code: order[0].ord_code,
|
||||
trx_at: moment.unix(order[0].crt).format('DD MMM YYYY'),
|
||||
admin_id: admin.id,
|
||||
admin_name: admin.first_name,
|
||||
admin_phone: '0' + admin.phone,
|
||||
admin_mail: admin.email,
|
||||
admin_addr: admin.fulladdress,
|
||||
client_id: order[0].c_id,
|
||||
client_name: order[0].c_name,
|
||||
client_phone: '0' + order[0].c_phone_val,
|
||||
client_mail: order[0].c_mail,
|
||||
client_addr: '',
|
||||
client_prefer_type_truck: '',
|
||||
pickup_zone_title: order[0].pck_name,
|
||||
pickup_zone_addr: order[0].pck_addr,
|
||||
pickup_at: order[0].set_pck_at,
|
||||
drop_zone_title: order[0].drop_name,
|
||||
drop_zone_addr: order[0].drop_addr,
|
||||
});
|
||||
}
|
||||
return {
|
||||
type: 'fail',
|
||||
message: `No vendor accept this order on order_id ${ord_id} in 3x10 minutes`,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
OrdersModels.updt(order[0].ord_id, {
|
||||
count_sch_blast_order: order[0].count_sch_blast_order,
|
||||
});
|
||||
// blast to other vendor
|
||||
const nextVendors = await OrdersVendorsModels.getNextVendorsByOrdId(ord_id);
|
||||
if (nextVendors.length > 0) {
|
||||
for (let key in nextVendors) {
|
||||
const blastToVendor = await OrdersVendorsModels.getById(nextVendors[key].id);
|
||||
if (blastToVendor.length < 1) {
|
||||
Logger.log('info', `${queueName} running_fail: vendor ${nextVendors[key].vdr_id} want to blast not found on order_id ${ord_id[key]}`);
|
||||
continue;
|
||||
}
|
||||
// kalau expirednya mau diupdate
|
||||
if (blastToVendor[0].status === OrdersVendorsModels.STTS_WAIT && blastToVendor[0].is_want === OrdersVendorsModels.IS_WANT_IGNORE) {
|
||||
await OrdersVendorsModels.updt(nextVendors[key].id, {
|
||||
is_exp: OrdersVendorsModels.LINK_WILL_EXP,
|
||||
exp_at: moment.unix(now).add(10, 'minutes').unix(),
|
||||
// exp_at: moment.unix(now).add(1, 'day').unix(),
|
||||
});
|
||||
}
|
||||
const bidOrderMailData = {
|
||||
trx_code: order[0].ord_code,
|
||||
// client_id: order[0].ord_client_id,
|
||||
client_name: order[0].c_name,
|
||||
client_phone: '0' + order[0].c_phone_val,
|
||||
client_mail: order[0].c_mail,
|
||||
// client_addr,
|
||||
client_prefer_type_truck: order[0].prefer_type_truck,
|
||||
pickup_zone_title: order[0].pck_name,
|
||||
pickup_zone_addr: order[0].pck_addr,
|
||||
pickup_at: moment.unix(order[0].set_pck_at).format('DD MMM YYYY HH:mm') + ' WIB',
|
||||
drop_zone_title: order[0].drop_name,
|
||||
drop_zone_addr: order[0].drop_addr,
|
||||
// vendor_id: blastToVendor[0].vdr_id,
|
||||
vendor_name: blastToVendor[0].vdr_name,
|
||||
vendor_phone: '0' + blastToVendor[0].vdr_phone_val,
|
||||
vendor_mail: blastToVendor[0].vdr_mail,
|
||||
vendor_addr: blastToVendor[0].vdr_addr,
|
||||
vendor_acc_link: base_link + blastToVendor[0].bid_token,
|
||||
};
|
||||
LibMail.sendBidOrderMail('Ada Order Masuk', blastToVendor[0].vdr_mail, bidOrderMailData);
|
||||
}
|
||||
} else {
|
||||
Logger.log('info', `${queueName} running_info: No next vendors, mean all vendors want but no accepted on order_id ${ord_id} in 3x10 minutes`);
|
||||
}
|
||||
// Logger.log('error', `${queueName} running_error: ${JSON.stringify(e, Object.getOwnPropertyNames(e))}`);
|
||||
return {
|
||||
type: 'success',
|
||||
message: 'success do blast order to vendor',
|
||||
data: null,
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
type: 'error',
|
||||
message: e.message,
|
||||
e: e,
|
||||
};
|
||||
}
|
||||
};
|
||||
117
workers/BlastOrderWorkerBAK.js
Normal file
117
workers/BlastOrderWorkerBAK.js
Normal file
@ -0,0 +1,117 @@
|
||||
const SandboxedJobMQ = require('bullmq').SandboxedJob;
|
||||
const LibWinston = require('../library/LibWinston');
|
||||
const LibMail = require('../library/LibMail');
|
||||
const moment = require('moment');
|
||||
const GpsTracksModels = require('../models/GpsTracksModels');
|
||||
const OrdersModels = require('../models/OrdersModels');
|
||||
const OrdersVendorsModels = require('../models/OrdersVendorsModels');
|
||||
|
||||
const queueName = process.env.REDIS_QUEUE_BLAST_ORDER;
|
||||
const Logger = LibWinston.initialize(queueName);
|
||||
|
||||
module.exports = async (job) => {
|
||||
try {
|
||||
Logger.log('info', `${queueName} running: ${JSON.stringify(job.opts)}`);
|
||||
const now = moment().unix();
|
||||
const data = job.data;
|
||||
if (!data.ord_id || !data.ord_code) {
|
||||
Logger.log('info', `${queueName} running_fail: data not valid`);
|
||||
return {
|
||||
type: 'fail',
|
||||
message: 'data not valid',
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
const order = await OrdersModels.showOrder({
|
||||
'id': data.ord_id,
|
||||
});
|
||||
if (order.length < 1) {
|
||||
Logger.log('info', `${queueName} running_fail: order not found on order_id ${data.ord_id}`);
|
||||
return {
|
||||
type: 'fail',
|
||||
message: `order not found on order_id ${data.ord_id}`,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
// check is accepted
|
||||
if (order[0].ord_vdr_id) {
|
||||
Logger.log('info', `${queueName} running_info: order have been accepted by another vendor ${order[0].ord_vdr_id} on order_id ${data.ord_id}`);
|
||||
return {
|
||||
type: 'success',
|
||||
message: 'order have been accepted by another vendor',
|
||||
data: null,
|
||||
};
|
||||
} else {
|
||||
await OrdersVendorsModels.updt(data.current_ord_vdr_id, {
|
||||
status: OrdersVendorsModels.STTS_NOT_READY,
|
||||
});
|
||||
}
|
||||
// blast to other vendor
|
||||
if (data.next_ord_vdr_id.length > 0) {
|
||||
for (let key in data.next_ord_vdr_id) {
|
||||
// get by vendor_id not bid token
|
||||
// let blastToVendor = await OrdersVendorsModels.getByBidToken(data.next_vdr_bid_token[key].tkn);
|
||||
let blastToVendor = await OrdersVendorsModels.getById(data.next_ord_vdr_id[key].id);
|
||||
if (blastToVendor.length < 1) {
|
||||
Logger.log('info', `${queueName} running_fail: vendor want to blast not found on order_id ${data.ord_id[key]} and bid_token ${data.next_vdr_bid_token[key].tkn}`);
|
||||
// return {
|
||||
// type: 'fail',
|
||||
// message: `vendor want to blast not found on order_id ${data.ord_id[key]} and bid_token ${data.next_vdr_bid_token[key].tkn}`,
|
||||
// data: null,
|
||||
// };
|
||||
continue;
|
||||
}
|
||||
// kalau expirednya mau diupdate
|
||||
// if (blastToVendor[0].status === OrdersVendorsModels.STTS_WAIT && blastToVendor[0].is_want === OrdersVendorsModels.IS_WANT_IGNORE) {
|
||||
// await OrdersVendorsModels.updt(data.next_ord_vdr_id[key].id, {
|
||||
// is_exp: OrdersVendorsModels.LINK_WILL_EXP,
|
||||
// // exp_at: moment.unix(now).add(10, 'minutes').unix(),
|
||||
// exp_at: moment.unix(now).add(1, 'day').unix(),
|
||||
// });
|
||||
// }
|
||||
let bidOrderMailData = {
|
||||
trx_code: order[0].ord_code,
|
||||
// client_id: order[0].ord_client_id,
|
||||
client_name: order[0].c_name,
|
||||
client_phone: '0' + order[0].c_phone_val,
|
||||
client_mail: order[0].c_mail,
|
||||
// client_addr,
|
||||
client_prefer_type_truck: order[0].prefer_type_truck,
|
||||
// weight: Number(order[0].weight),
|
||||
// cbm: Number(order[0].cbm),
|
||||
// koli: Number(order[0].koli),
|
||||
pickup_zone_title: order[0].pck_name,
|
||||
pickup_zone_addr: order[0].pck_addr,
|
||||
pickup_at: moment.unix(order[0].set_pck_at).format('DD MMM YYYY HH:mm') + ' WIB',
|
||||
drop_zone_title: order[0].drop_name,
|
||||
drop_zone_addr: order[0].drop_addr,
|
||||
// vendor_id: blastToVendor[0].vdr_id,
|
||||
vendor_name: blastToVendor[0].vdr_name,
|
||||
vendor_phone: '0' + blastToVendor[0].vdr_phone_val,
|
||||
vendor_mail: blastToVendor[0].vdr_mail,
|
||||
vendor_addr: blastToVendor[0].vdr_addr,
|
||||
vendor_acc_link: data.next_vdr_acc_link[key].link,
|
||||
};
|
||||
LibMail.sendBidOrderMail('Ada Order Masuk', blastToVendor[0].vdr_mail, bidOrderMailData);
|
||||
}
|
||||
} else {
|
||||
await OrdersModels.updt(data.ord_id, {
|
||||
status: OrdersModels.STTS_CANCEL,
|
||||
cancel_type: OrdersModels.CANCEL_TYPE_VDR_NOT_READY,
|
||||
cancel_at: now,
|
||||
});
|
||||
}
|
||||
// Logger.log('error', `${queueName} running_error: ${JSON.stringify(e, Object.getOwnPropertyNames(e))}`);
|
||||
return {
|
||||
type: 'success',
|
||||
message: 'success do blast order to vendor',
|
||||
data: null,
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
type: 'error',
|
||||
message: e.message,
|
||||
e: e,
|
||||
};
|
||||
}
|
||||
};
|
||||
75
workers/DrvBlastNotifWorker.js
Normal file
75
workers/DrvBlastNotifWorker.js
Normal file
@ -0,0 +1,75 @@
|
||||
const SandboxedJobMQ = require('bullmq').SandboxedJob;
|
||||
const moment = require('moment');
|
||||
const LibWinston = require('../library/LibWinston');
|
||||
const LibFirebase = require('../library/LibFirebase');
|
||||
const DriversModels = require('../models/DriversModels');
|
||||
// const GpsTracksModels = require('../models/GpsTracksModels');
|
||||
|
||||
const schedulerName = process.env.REDIS_SCHEDULER_DRV_BLAST_NOTIF;
|
||||
const Logger = LibWinston.initialize(schedulerName);
|
||||
|
||||
module.exports = async (job) => {
|
||||
try {
|
||||
Logger.log('info', `${schedulerName} running: ${JSON.stringify(job.opts)}`);
|
||||
/**
|
||||
* cek apakah ord_pck_drop.stts(status_delivery) === OrdersPckDropsModels.STTS_DELIVERY_FINISH_PICKUP
|
||||
* jika iya dan sudah upload menu_travel_document maka kendaraan sedang dalam perjalanan ke lokasi drop
|
||||
* cek apakah ord_pck_drop.stts(status_delivery) === OrdersPckDropsModels.STTS_DELIVERY_OTW_DROP
|
||||
* jika iya dan ord_pck_drop.drv_app_lock_menu_otw_drop_at === 0 maka kendaraan masih dalam perjalanan ke lokasi drop
|
||||
*/
|
||||
|
||||
const libFirebase = new LibFirebase();
|
||||
let notifTitle = 'Pengecekan Aplikasi'; // cek app
|
||||
let notifBody = 'Harap Dihiraukan'; // cek app
|
||||
|
||||
// (async function() {
|
||||
try {
|
||||
async function checkNotifNLogs(job) {
|
||||
libFirebase.sendToDevice(job.drv_fcm_token, {
|
||||
// notification: {
|
||||
// title: notifTitle,
|
||||
// body: notifBody,
|
||||
// },
|
||||
data: {
|
||||
title: notifTitle,
|
||||
body: notifBody,
|
||||
type: '' + LibFirebase.blastNotif,
|
||||
detail_id: '',
|
||||
content_available: 'true',
|
||||
}
|
||||
}, {
|
||||
priority: 'high', // to apple: normal(5), high(10)
|
||||
android: {
|
||||
priority: 'high', // to anroid: low(?). normal(5), high(10)
|
||||
},
|
||||
content_available: true,
|
||||
click_action: 'FLUTTER_NOTIFICATION_CLICK',
|
||||
});
|
||||
}
|
||||
|
||||
let loop = process.env.SCHEDULE_DRV_BLAST_NOTIF_MAX_LOOP;
|
||||
for (let x = 0; x < loop; x++) {
|
||||
// all drivers login
|
||||
const allDrvLogins = await DriversModels.getDriversLogin(DriversModels.IS_LOGIN);
|
||||
for (const drv of allDrvLogins) {
|
||||
await checkNotifNLogs({drv_fcm_token: drv.fcm_token});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
Logger.log('error', `${schedulerName} error: ${JSON.stringify(e)}`);
|
||||
}
|
||||
// })();
|
||||
return {
|
||||
type: 'success',
|
||||
message: 'success run scheduler drv up photo',
|
||||
data: null,
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
type: 'error',
|
||||
message: e.message,
|
||||
e: e,
|
||||
};
|
||||
}
|
||||
};
|
||||
116
workers/DrvUpLocIdleWorker.js
Normal file
116
workers/DrvUpLocIdleWorker.js
Normal file
@ -0,0 +1,116 @@
|
||||
const SandboxedJobMQ = require('bullmq').SandboxedJob;
|
||||
const moment = require('moment');
|
||||
const LibWinston = require('../library/LibWinston');
|
||||
const LibFirebase = require('../library/LibFirebase');
|
||||
const OrdersModels = require('../models/OrdersModels');
|
||||
const DriversModels = require('../models/DriversModels');
|
||||
const OrdersPckDropsModels = require('../models/OrdersPckDropsModels');
|
||||
// const GpsTracksModels = require('../models/GpsTracksModels');
|
||||
|
||||
const schedulerName = process.env.REDIS_SCHEDULER_DRV_UP_LOC_IDLE;
|
||||
const Logger = LibWinston.initialize(schedulerName);
|
||||
|
||||
module.exports = async (job) => {
|
||||
try {
|
||||
Logger.log('info', `${schedulerName} running: ${JSON.stringify(job.opts)}`);
|
||||
/**
|
||||
* semua non-aktif order dan driver sedang login
|
||||
* get last t_gps_tracks by drv_id
|
||||
* jika crt_d > 2 hour => send notif
|
||||
*/
|
||||
|
||||
const libFirebase = new LibFirebase();
|
||||
let notifTitle = 'Notifikasi Cek Lokasi'; // up location
|
||||
let notifBody = 'Harap Dihiraukan'; // up location
|
||||
|
||||
// (async function() {
|
||||
try {
|
||||
async function checkNotifNLogs(job) {
|
||||
libFirebase.sendToDevice(job.drv_fcm_token, {
|
||||
// notification: {
|
||||
// title: notifTitle,
|
||||
// body: notifBody,
|
||||
// },
|
||||
data: {
|
||||
title: notifTitle,
|
||||
body: notifBody,
|
||||
type: '' + LibFirebase.upLocIdle,
|
||||
detail_id: '',
|
||||
content_available: 'true',
|
||||
}
|
||||
}, {
|
||||
priority: 'high', // to apple: normal(5), high(10)
|
||||
android: {
|
||||
priority: 'high', // to anroid: low(?). normal(5), high(10)
|
||||
},
|
||||
content_available: true,
|
||||
click_action: 'FLUTTER_NOTIFICATION_CLICK',
|
||||
});
|
||||
}
|
||||
|
||||
let loop = process.env.SCHEDULE_DRV_UP_LOC_IDLE_MAX_LOOP;
|
||||
for (let x = 0; x < loop; x++) {
|
||||
// all active order
|
||||
const activeJobs = await OrdersModels.listOrders({
|
||||
is_active: OrdersModels.IS_ACTIVE,
|
||||
delivery_statuses: [
|
||||
OrdersPckDropsModels.STTS_DELIVERY_OTW_PICKUP,OrdersPckDropsModels.STTS_DELIVERY_ARRIVED_PICKUP,OrdersPckDropsModels.STTS_DELIVERY_PROCESS_PICKUP
|
||||
,OrdersPckDropsModels.STTS_DELIVERY_FINISH_PICKUP,OrdersPckDropsModels.STTS_DELIVERY_TRAVEL_DOC,OrdersPckDropsModels.STTS_DELIVERY_OTW_DROP
|
||||
,OrdersPckDropsModels.STTS_DELIVERY_ARRIVED_DROP,OrdersPckDropsModels.STTS_DELIVERY_PROCESS_DROP,OrdersPckDropsModels.STTS_DELIVERY_FINISH_DROP
|
||||
// ,OrdersPckDropsModels.STTS_DELIVERY_HANDOVER_DOC
|
||||
],
|
||||
couple_pck_drop: 1,
|
||||
inner_join_phone_devices: 1,
|
||||
phone_devices_is_login: DriversModels.IS_LOGIN,
|
||||
last_tracks_phone_drv: 1,
|
||||
group_by: 'GROUP BY ord_drv.drv_id',
|
||||
});
|
||||
const drvs = [];
|
||||
for (const job of activeJobs) {
|
||||
drvs[job.drv_id] = job;
|
||||
}
|
||||
|
||||
// all inactive order
|
||||
const inactiveJobs = await OrdersModels.listOrders({
|
||||
// is_active: OrdersModels.IS_ACTIVE,
|
||||
delivery_statuses: [OrdersPckDropsModels.STTS_DELIVERY_HANDOVER_DOC],
|
||||
couple_pck_drop: 1,
|
||||
inner_join_phone_devices: 1,
|
||||
phone_devices_is_login: DriversModels.IS_LOGIN,
|
||||
last_tracks_phone_drv: 1,
|
||||
group_by: 'GROUP BY ord_drv.drv_id',
|
||||
});
|
||||
|
||||
for (const job of inactiveJobs) {
|
||||
// baru ketembak notif, minimal ada 1x update lokasi
|
||||
if (job.drv_fcm_token && job.tr_crt_d && job.tr_crt_d != 0) {
|
||||
// if the driver id not in active order
|
||||
if (typeof drvs[job.drv_id] === 'undefined') {
|
||||
await checkNotifNLogs(job);
|
||||
}
|
||||
}
|
||||
// ketembak notif jika belum pernah ada update lokasi samsek
|
||||
else {
|
||||
await checkNotifNLogs(job);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
Logger.log('error', `${schedulerName} error: ${JSON.stringify(e)}`);
|
||||
}
|
||||
// })();
|
||||
|
||||
return {
|
||||
type: 'success',
|
||||
message: 'success run scheduler drv up idle location',
|
||||
data: null,
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
type: 'error',
|
||||
message: e.message,
|
||||
e: e,
|
||||
};
|
||||
}
|
||||
};
|
||||
137
workers/DrvUpLocWorker.js
Normal file
137
workers/DrvUpLocWorker.js
Normal file
@ -0,0 +1,137 @@
|
||||
const SandboxedJobMQ = require('bullmq').SandboxedJob;
|
||||
const moment = require('moment');
|
||||
const LibWinston = require('../library/LibWinston');
|
||||
const LibFirebase = require('../library/LibFirebase');
|
||||
const OrdersModels = require('../models/OrdersModels');
|
||||
const DriversModels = require('../models/DriversModels');
|
||||
const OrdersPckDropsModels = require('../models/OrdersPckDropsModels');
|
||||
const LogsSchNotifModels = require('../models/LogsSchNotifModels');
|
||||
// const GpsTracksModels = require('../models/GpsTracksModels');
|
||||
|
||||
const schedulerName = process.env.REDIS_SCHEDULER_DRV_UP_LOC;
|
||||
const Logger = LibWinston.initialize(schedulerName);
|
||||
|
||||
module.exports = async (job) => {
|
||||
try {
|
||||
// const now = moment().unix();
|
||||
Logger.log('info', `${schedulerName} running: ${JSON.stringify(job.opts)}`);
|
||||
/**
|
||||
* semua aktif order dan driver sedang login
|
||||
* get last t_gps_tracks by drv_id
|
||||
* jika crt_d > 5 minute => send notif
|
||||
*/
|
||||
|
||||
const libFirebase = new LibFirebase();
|
||||
let notifTitle = 'Notifikasi Cek Lokasi'; // up location
|
||||
let notifBody = 'Harap Dihiraukan'; // up location
|
||||
|
||||
// (async function() {
|
||||
try {
|
||||
async function checkNotifNLogs(job) {
|
||||
// hapus logs notif jika lebih dari 3x dan lebih dari 1jam
|
||||
const logs = await LogsSchNotifModels.list({ drv_id: job.drv_id, notif_type: LibFirebase.upLocActiveOrder, order_by: 'lognot.drv_id DESC', limit: 3 });
|
||||
if (logs.length >= 3) {
|
||||
let start = moment();
|
||||
end = moment.unix(logs[0].crt);
|
||||
duration = moment.duration(start.diff(end));
|
||||
if (duration.asHours() >= 1) {
|
||||
LogsSchNotifModels.delLogs({ drv_id: job.drv_id, notif_type: LibFirebase.upLocActiveOrder });
|
||||
} else {
|
||||
// continue;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// kirim notif
|
||||
console.log('drvUpLocWorker driver id => ', job.drv_id, ' at ', moment().unix());
|
||||
libFirebase.sendToDevice(job.drv_fcm_token, {
|
||||
notification: {
|
||||
title: notifTitle,
|
||||
body: notifBody,
|
||||
},
|
||||
data: {
|
||||
title: notifTitle,
|
||||
body: notifBody,
|
||||
type: '' + LibFirebase.upLocActiveOrder,
|
||||
detail_id: '',
|
||||
content_available: 'true',
|
||||
}
|
||||
}, {
|
||||
priority: 'high', // to apple: normal(5), high(10)
|
||||
android: {
|
||||
priority: 'high', // to anroid: low(?). normal(5), high(10)
|
||||
},
|
||||
content_available: true,
|
||||
click_action: 'FLUTTER_NOTIFICATION_CLICK',
|
||||
});
|
||||
LogsSchNotifModels.insLog({
|
||||
fcm_token: job.drv_fcm_token,
|
||||
device_id: job.drv_device_id,
|
||||
drv_id: job.drv_id,
|
||||
notif_type: LibFirebase.upLocActiveOrder,
|
||||
crt: moment().unix(),
|
||||
});
|
||||
}
|
||||
|
||||
let loop = process.env.SCHEDULE_DRV_UP_LOC_MAX_LOOP;
|
||||
for (let x = 0; x < loop; x++) {
|
||||
// all active order
|
||||
const activeJobs = await OrdersModels.listOrders({
|
||||
is_active: OrdersModels.IS_ACTIVE,
|
||||
delivery_statuses: [
|
||||
OrdersPckDropsModels.STTS_DELIVERY_OTW_PICKUP,OrdersPckDropsModels.STTS_DELIVERY_ARRIVED_PICKUP,OrdersPckDropsModels.STTS_DELIVERY_PROCESS_PICKUP
|
||||
,OrdersPckDropsModels.STTS_DELIVERY_FINISH_PICKUP,OrdersPckDropsModels.STTS_DELIVERY_TRAVEL_DOC,OrdersPckDropsModels.STTS_DELIVERY_OTW_DROP
|
||||
,OrdersPckDropsModels.STTS_DELIVERY_ARRIVED_DROP,OrdersPckDropsModels.STTS_DELIVERY_PROCESS_DROP,OrdersPckDropsModels.STTS_DELIVERY_FINISH_DROP
|
||||
// ,OrdersPckDropsModels.STTS_DELIVERY_HANDOVER_DOC
|
||||
],
|
||||
couple_pck_drop: 1,
|
||||
inner_join_phone_devices: 1,
|
||||
phone_devices_is_login: DriversModels.IS_LOGIN,
|
||||
last_tracks_phone_drv: 1,
|
||||
group_by: 'GROUP BY ord_drv.drv_id',
|
||||
});
|
||||
|
||||
/**
|
||||
* jika telah mengirim notif lebih dari 3x, maka stop
|
||||
* ngapusnya gimana ? permasalahnnya order yang didapet adalah ketika driver login
|
||||
* ngapusnya pas driver sudah update data terbaru
|
||||
* kalo misalkan pas ngirim notif masih ada log notif belum terhapus sebanyak 3x, maka check apakah sudah 1hari ? baru dihapus dan create log baru
|
||||
*/
|
||||
|
||||
for (const job of activeJobs) {
|
||||
// baru ketembak notif, minimal ada 1x update lokasi
|
||||
if (job.drv_fcm_token && job.tr_crt_d && job.tr_crt_d != 0) {
|
||||
// more than 5 minute
|
||||
let start = moment();
|
||||
let end = moment.unix(job.tr_crt_d);
|
||||
let duration = moment.duration(start.diff(end));
|
||||
if (duration.asMinutes() >= 4) {
|
||||
await checkNotifNLogs(job);
|
||||
} else {
|
||||
LogsSchNotifModels.delLogs({ drv_id: job.drv_id, notif_type: LibFirebase.upLocActiveOrder });
|
||||
}
|
||||
}
|
||||
// ketembak notif jika belum pernah ada update lokasi samsek
|
||||
else {
|
||||
await checkNotifNLogs(job);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
Logger.log('error', `${schedulerName} error: ${JSON.stringify(e)}`);
|
||||
}
|
||||
// })();
|
||||
|
||||
return {
|
||||
type: 'success',
|
||||
message: 'success run scheduler drv up location',
|
||||
data: null,
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
type: 'error',
|
||||
message: e.message,
|
||||
e: e,
|
||||
};
|
||||
}
|
||||
};
|
||||
107
workers/DrvUpPhotoWorker.js
Normal file
107
workers/DrvUpPhotoWorker.js
Normal file
@ -0,0 +1,107 @@
|
||||
const SandboxedJobMQ = require('bullmq').SandboxedJob;
|
||||
const moment = require('moment');
|
||||
const LibWinston = require('../library/LibWinston');
|
||||
const LibFirebase = require('../library/LibFirebase');
|
||||
const OrdersModels = require('../models/OrdersModels');
|
||||
const DriversModels = require('../models/DriversModels');
|
||||
const OrdersPckDropsModels = require('../models/OrdersPckDropsModels');
|
||||
// const GpsTracksModels = require('../models/GpsTracksModels');
|
||||
|
||||
const schedulerName = process.env.REDIS_SCHEDULER_DRV_UP_PHOTO;
|
||||
const Logger = LibWinston.initialize(schedulerName);
|
||||
|
||||
module.exports = async (job) => {
|
||||
try {
|
||||
Logger.log('info', `${schedulerName} running: ${JSON.stringify(job.opts)}`);
|
||||
/**
|
||||
* cek apakah ord_pck_drop.stts(status_delivery) === OrdersPckDropsModels.STTS_DELIVERY_FINISH_PICKUP
|
||||
* jika iya dan sudah upload menu_travel_document maka kendaraan sedang dalam perjalanan ke lokasi drop
|
||||
* cek apakah ord_pck_drop.stts(status_delivery) === OrdersPckDropsModels.STTS_DELIVERY_OTW_DROP
|
||||
* jika iya dan ord_pck_drop.drv_app_lock_menu_otw_drop_at === 0 maka kendaraan masih dalam perjalanan ke lokasi drop
|
||||
*/
|
||||
|
||||
const libFirebase = new LibFirebase();
|
||||
let notifTitle = 'Notifikasi Cek Photo Saat diperjalanan'; // up location
|
||||
let notifBody = 'Harap Dihiraukan'; // up location
|
||||
|
||||
// (async function() {
|
||||
try {
|
||||
async function checkNotifNLogs(job) {
|
||||
libFirebase.sendToDevice(job.drv_fcm_token, {
|
||||
// notification: {
|
||||
// title: notifTitle,
|
||||
// body: notifBody,
|
||||
// },
|
||||
data: {
|
||||
title: notifTitle,
|
||||
body: notifBody,
|
||||
type: '' + LibFirebase.upPhotoOtwDrop,
|
||||
detail_id: '' + job.detail_id,
|
||||
content_available: 'true',
|
||||
}
|
||||
}, {
|
||||
priority: 'high', // to apple: normal(5), high(10)
|
||||
android: {
|
||||
priority: 'high', // to anroid: low(?). normal(5), high(10)
|
||||
},
|
||||
content_available: true,
|
||||
click_action: 'FLUTTER_NOTIFICATION_CLICK',
|
||||
});
|
||||
}
|
||||
|
||||
let loop = process.env.SCHEDULE_DRV_UP_PHOTO_MAX_LOOP;
|
||||
for (let x = 0; x < loop; x++) {
|
||||
// all active order
|
||||
const activeJobs = await OrdersModels.listOrders({
|
||||
is_active: OrdersModels.IS_ACTIVE,
|
||||
delivery_statuses: [
|
||||
OrdersPckDropsModels.STTS_DELIVERY_OTW_DROP
|
||||
],
|
||||
couple_pck_drop: 1,
|
||||
inner_join_phone_devices: 1,
|
||||
phone_devices_is_login: DriversModels.IS_LOGIN,
|
||||
last_tracks_phone_drv: 1,
|
||||
// group_by: 'GROUP BY ord_drv.drv_id',
|
||||
});
|
||||
|
||||
let hadSends = [];
|
||||
for (const job of activeJobs) {
|
||||
// baru ketembak notif, minimal ada 1x update lokasi
|
||||
if (job.drv_fcm_token && job.tr_crt_d && job.tr_crt_d != 0) {
|
||||
if (job.drv_app_lock_menu_otw_drop_at !== 0) continue;
|
||||
if (hadSends.includes(job.drv_id)) continue;
|
||||
// more than 2 hour
|
||||
let start = moment();
|
||||
let end = moment.unix(job.tr_crt_d);
|
||||
let duration = moment.duration(start.diff(end));
|
||||
if (duration.asHours() >= 2) {
|
||||
hadSends.push(job.drv_id);
|
||||
job.detail_id = Buffer.from(`${job.ord_id}_${job.ord_pck_id}_${job.ord_drop_id}_${job.ord_pck_drop_id}`, 'ascii').toString('hex');
|
||||
await checkNotifNLogs(job);
|
||||
}
|
||||
}
|
||||
// ketembak notif jika belum pernah ada update lokasi samsek
|
||||
else {
|
||||
job.detail_id = Buffer.from(`${job.ord_id}_${job.ord_pck_id}_${job.ord_drop_id}_${job.ord_pck_drop_id}`, 'ascii').toString('hex');
|
||||
await checkNotifNLogs(job);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
Logger.log('error', `${schedulerName} error: ${JSON.stringify(e)}`);
|
||||
}
|
||||
// })();
|
||||
return {
|
||||
type: 'success',
|
||||
message: 'success run scheduler drv up photo',
|
||||
data: null,
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
type: 'error',
|
||||
message: e.message,
|
||||
e: e,
|
||||
};
|
||||
}
|
||||
};
|
||||
258
workers/ReverseGeocodeWorker.js
Normal file
258
workers/ReverseGeocodeWorker.js
Normal file
@ -0,0 +1,258 @@
|
||||
const SandboxedJobMQ = require('bullmq').SandboxedJob;
|
||||
const LibWinston = require('../library/LibWinston');
|
||||
const moment = require('moment');
|
||||
const axios = require('axios').default;
|
||||
const url = require('url');
|
||||
const request = require('../config/request');
|
||||
const GpsTracksModels = require('../models/GpsTracksModels');
|
||||
const RegionModels = require('../models/RegionModels');
|
||||
|
||||
const schedulerName = process.env.REDIS_SCHEDULER_REVERSE_GEO;
|
||||
const Logger = LibWinston.initialize(schedulerName);
|
||||
|
||||
module.exports = async (job) => {
|
||||
try {
|
||||
Logger.log('info', `${schedulerName} running: ${JSON.stringify(job.opts)}`);
|
||||
|
||||
// (async function() {
|
||||
try {
|
||||
let loop = process.env.SCHEDULE_REVERSE_GEO_MAX_LOOP;
|
||||
for (let x = 0; x < loop; x++) {
|
||||
// let tracks = [];
|
||||
let tracks = await GpsTracksModels.get2ForReverseGeo(1);
|
||||
for (let i = 0; i < tracks.length; i++) {
|
||||
let now = moment().unix();
|
||||
let updtData = {};
|
||||
let respReverseGeo = null;
|
||||
try {
|
||||
const sameAddr = await GpsTracksModels.select2Address(tracks[i].latitude, tracks[i].longitude);
|
||||
if (sameAddr.length > 0) {
|
||||
let addrData = {
|
||||
device_id: tracks[i].device_id,
|
||||
master_id: tracks[i].id,
|
||||
type: sameAddr[0].type,
|
||||
lat: tracks[i].latitude,
|
||||
lng: tracks[i].longitude,
|
||||
country_id: sameAddr[0].country_id,
|
||||
country_code: sameAddr[0].country_code,
|
||||
country_text: sameAddr[0].country_text,
|
||||
state_id: sameAddr[0].state_id,
|
||||
state_text: sameAddr[0].state_text,
|
||||
city_id: sameAddr[0].city_id,
|
||||
city_text: sameAddr[0].city_text,
|
||||
district_id: sameAddr[0].district_id,
|
||||
district_text: sameAddr[0].district_text,
|
||||
village_id: sameAddr[0].village_id,
|
||||
village_text: sameAddr[0].village_text,
|
||||
postcode: sameAddr[0].postcode,
|
||||
streets: sameAddr[0].streets,
|
||||
fulladdress: encodeURIComponent(decodeURIComponent(sameAddr[0].fulladdress)),
|
||||
type_reverse_geo: sameAddr[0].type_reverse_geo,
|
||||
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_SC,
|
||||
log_reverse_geo: sameAddr[0].log_reverse_geo,
|
||||
crt: now,
|
||||
crt_format: moment.unix(now).format('YYYY-MM-DD HH:mm:ss'),
|
||||
};
|
||||
GpsTracksModels.create2Address(addrData);
|
||||
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_SC;
|
||||
await GpsTracksModels.update2(tracks[i].id, updtData);
|
||||
continue;
|
||||
}
|
||||
|
||||
let params = new url.URLSearchParams({
|
||||
lat: tracks[i].latitude,
|
||||
lon: tracks[i].longitude,
|
||||
format: 'geojson',
|
||||
});
|
||||
const axInstance = axios.create();
|
||||
axios.defaults.timeout = 3000;
|
||||
axios.defaults.crossDomain = true;
|
||||
// respReverseGeo = await axios({
|
||||
// url: request.osm_reverse_geo.urlFull,
|
||||
// method: request.osm_reverse_geo.method,
|
||||
// params: params,
|
||||
// responseType: 'json',
|
||||
// });
|
||||
respReverseGeo = await axInstance.get(request.osm_reverse_geo.urlFull + '?' + params.toString(), {
|
||||
timeout: 3000,
|
||||
});
|
||||
let respData = respReverseGeo.data || {};
|
||||
if (respReverseGeo.status == 200) {
|
||||
if (respData.features.length < 1) {
|
||||
GpsTracksModels.create2Address({
|
||||
device_id: tracks[i].device_id,
|
||||
master_id: tracks[i].id,
|
||||
lat: tracks[i].latitude,
|
||||
lng: tracks[i].longitude,
|
||||
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_LOST,
|
||||
log_reverse_geo: JSON.stringify(respData),
|
||||
crt: now,
|
||||
crt_format: moment.unix(now).format('YYYY-MM-DD HH:mm:ss'),
|
||||
});
|
||||
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_LOST;
|
||||
await GpsTracksModels.update2(tracks[i].id, updtData);
|
||||
} else {
|
||||
let respAddr = respData.features[0].properties.address;
|
||||
let addrData = {
|
||||
device_id: tracks[i].device_id,
|
||||
master_id: tracks[i].id,
|
||||
lat: tracks[i].latitude,
|
||||
lng: tracks[i].longitude,
|
||||
country_id: GpsTracksModels.DEFAULT_COUNTRY_ID,
|
||||
country_code: respAddr.country_code,
|
||||
country_text: (respAddr.country) ? respAddr.country.toUpperCase() : respAddr.country || null,
|
||||
state_id: null,
|
||||
city_id: null,
|
||||
district_id: null,
|
||||
village_id: null,
|
||||
postcode: respAddr.postcode,
|
||||
fulladdress: encodeURIComponent(respData.features[0].properties.display_name),
|
||||
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_SC,
|
||||
log_reverse_geo: (respData.features[0].properties) ? JSON.stringify(respData.features[0].properties) : null,
|
||||
crt: now,
|
||||
crt_format: moment.unix(now).format('YYYY-MM-DD HH:mm:ss'),
|
||||
};
|
||||
if (respAddr.state || respAddr.city) {
|
||||
addrData.state_text = respAddr.region || respAddr.state || respAddr.state_district || respAddr.county || respAddr.city || '';
|
||||
addrData.state_text = (addrData.state_text) ? addrData.state_text.toUpperCase() : addrData.state_text || null;
|
||||
addrData.state_text = addrData.state_text || null;
|
||||
}
|
||||
if (respAddr.city_district || respAddr.city) {
|
||||
addrData.city_text = respAddr.city_district || respAddr.city || '';
|
||||
addrData.city_text = (addrData.city_text) ? addrData.city_text.toUpperCase() : addrData.city_text || null;
|
||||
addrData.city_text = addrData.city_text || null;
|
||||
}
|
||||
if (respAddr.suburb || respAddr.subdistrict) {
|
||||
addrData.district_text = respAddr.suburb || respAddr.subdistrict || respAddr.subdivision || '';
|
||||
addrData.district_text = (addrData.district_text) ? addrData.district_text.toUpperCase() : addrData.district_text || null;
|
||||
addrData.district_text = addrData.district_text || null;
|
||||
}
|
||||
if (respAddr.village) {
|
||||
addrData.village_text = respAddr.village || respAddr.neighbourhood || '';
|
||||
addrData.village_text = (addrData.village_text) ? addrData.village_text.toUpperCase() : addrData.village_text || null;
|
||||
addrData.village_text = addrData.village_text || null;
|
||||
}
|
||||
if (respAddr.amenity || respAddr.road || respAddr.city_block) {
|
||||
addrData.streets = '';
|
||||
addrData.streets += (respAddr.amenity) ? respAddr.amenity + ', ' : '';
|
||||
addrData.streets += (respAddr.road) ? respAddr.road + ', ' : '';
|
||||
addrData.streets += (respAddr.house_number) ? respAddr.house_number + ', ' : '';
|
||||
addrData.streets += (respAddr.house_name) ? respAddr.house_name + ', ' : '';
|
||||
addrData.streets += (respAddr.city_block) ? respAddr.city_block + ', ' : '';
|
||||
addrData.streets += addrData.streets || null;
|
||||
if (addrData.streets) {
|
||||
addrData.streets = encodeURIComponent(addrData.streets.slice(0, -2));
|
||||
}
|
||||
}
|
||||
|
||||
let byAll = await RegionModels.whereLike({
|
||||
nmProvinsiKel: addrData.state_text,
|
||||
nmKotamadyaKel: addrData.city_text,
|
||||
nmKecamatanKel: addrData.district_text,
|
||||
nmKelurahan: addrData.village_text,
|
||||
});
|
||||
if (byAll.length > 1) {
|
||||
addrData.state_id = byAll[0].kodeProv;
|
||||
addrData.city_id = byAll[0].kodeKab;
|
||||
addrData.district_id = byAll[0].kodeKec;
|
||||
addrData.village_id = byAll[0].kodeKel;
|
||||
}
|
||||
|
||||
let byKel = await RegionModels.whereLike({
|
||||
nmKelurahan: addrData.village_text,
|
||||
});
|
||||
if (byAll.length < 1 && byKel.length > 0) {
|
||||
addrData.state_id = byKel[0].kodeProv;
|
||||
addrData.city_id = byKel[0].kodeKab;
|
||||
addrData.district_id = byKel[0].kodeKec;
|
||||
addrData.village_id = byKel[0].kodeKel;
|
||||
}
|
||||
|
||||
if (addrData.state_id === null) {
|
||||
let byPr = await RegionModels.whereLike({ nmProvinsiKel: addrData.state_text });
|
||||
if (byPr.length > 0) { addrData.state_id = byPr[0].kodeProv; }
|
||||
}
|
||||
|
||||
if (addrData.state_id !== null && addrData.city_id === null) {
|
||||
let byKt = await RegionModels.whereLike({ nmKotamadyaKel: addrData.city_text });
|
||||
if (byKt.length > 0) { addrData.city_id = byKt[0].kodeKab; }
|
||||
}
|
||||
|
||||
if (addrData.state_id !== null && addrData.city_id !== null && addrData.district_id === null) {
|
||||
let byKc = await RegionModels.whereLike({ nmKecamatanKel: addrData.district_text });
|
||||
if (byKc.length > 0) { addrData.district_id = byKc[0].kodeKec; }
|
||||
}
|
||||
|
||||
if (addrData.state_id !== null && addrData.city_id !== null && addrData.district_id !== null && addrData.village_id === null) {
|
||||
let byKl = await RegionModels.whereLike({ nmKelurahan: addrData.village_text });
|
||||
if (byKl.length > 0) { addrData.village_id = byKl[0].kodeKel; }
|
||||
}
|
||||
|
||||
GpsTracksModels.create2Address(addrData).catch((e) => {
|
||||
Logger.log('error', `${schedulerName} running_error: ${JSON.stringify(e, Object.getOwnPropertyNames(e))}`);
|
||||
});
|
||||
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_SC;
|
||||
await GpsTracksModels.update2(tracks[i].id, updtData);
|
||||
}
|
||||
} else {
|
||||
GpsTracksModels.create2Address({
|
||||
device_id: tracks[i].device_id,
|
||||
master_id: tracks[i].id,
|
||||
lat: tracks[i].latitude,
|
||||
lng: tracks[i].longitude,
|
||||
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_ER,
|
||||
log_reverse_geo: JSON.stringify(respData),
|
||||
crt: now,
|
||||
crt_format: moment.unix(now).format('YYYY-MM-DD HH:mm:ss'),
|
||||
});
|
||||
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_ER;
|
||||
await GpsTracksModels.update2(tracks[i].id, updtData);
|
||||
}
|
||||
} catch (e) {
|
||||
let respData = {}
|
||||
if (respReverseGeo) {
|
||||
if (respReverseGeo.status != 200) {
|
||||
respData.data = respReverseGeo.data;
|
||||
} else {
|
||||
respData.msg = e.message;
|
||||
}
|
||||
} else if (typeof e.response != 'undefined') {
|
||||
respData.data = e.response;
|
||||
} else {
|
||||
respData.msg = e.message;
|
||||
}
|
||||
GpsTracksModels.create2Address({
|
||||
device_id: tracks[i].device_id,
|
||||
master_id: tracks[i].id,
|
||||
lat: tracks[i].latitude,
|
||||
lng: tracks[i].longitude,
|
||||
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_ER,
|
||||
log_reverse_geo: JSON.stringify(respData),
|
||||
crt: now,
|
||||
crt_format: moment.unix(now).format('YYYY-MM-DD HH:mm:ss'),
|
||||
});
|
||||
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_ER;
|
||||
await GpsTracksModels.update2(tracks[i].id, updtData);
|
||||
}
|
||||
job.updateProgress(1);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
Logger.log('error', `${schedulerName} error: ${JSON.stringify(e)}`);
|
||||
}
|
||||
// })();
|
||||
|
||||
return {
|
||||
type: 'success',
|
||||
message: 'success do reverse geocoding',
|
||||
data: null,
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
type: 'error',
|
||||
message: e.message,
|
||||
e: e,
|
||||
};
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user