Files
gps-backend/models/ZoneModels.js
2025-05-29 08:59:40 +00:00

313 lines
13 KiB
JavaScript
Executable File

const db = require(`../config/dbMysqlConn`);
const defaultSelectGetInZone = `
z.id as zid,z.name,z.desc,z.type,zt.name as type_name,z.workflow_type,zw.name as workflow_type_name
,z.shiptocode,z.fulladdress,z.boundary_type,z.boundary_radius,z.boundary_latlngs,ST_AsText(boundary_points) as points
,z.client_group_id,c.c_name,c_mail,c.pic_name,c.pic_mail
`;
class ZoneModels {
static STTS_ACTIVE = 1;
static STTS_INACTIVE = 2;
static ZONE_BOUNDARY_CIRCLE = 'circle';
static ZONE_BOUNDARY_POLYGON = 'polygon';
static ZONE_BOUNDARY_RECTANGLE = 'rectangle';
static async getNearest(lat, lng, meters) {
return new Promise((resolve, reject) => {
let params = [];
let query = 'SELECT';
query += defaultSelectGetInZone;
query += ` ,ST_Distance_Sphere( ST_GeomFromText('POINT(${lng} ${lat})'), z.boundary_points) AS distance_meters`;
// params.push(lng, lat);
query += ' FROM t_zones AS z';
query += ' INNER JOIN t_zones_types AS zt ON z.type = zt.id';
query += ' INNER JOIN t_zones_workflows AS zw ON z.workflow_type = zw.id';
query += ' LEFT JOIN t_clients AS c ON z.client_group_id = c.id';
query += ' WHERE z.dlt is null AND z.status = ?';
params.push(ZoneModels.STTS_ACTIVE);
query += ' HAVING distance_meters <= ?';
params.push(meters);
db.query(query, params, function (err, resp) {
if (err) {
reject(err);
return false;
}
resolve(resp);
return true;
});
});
}
static async getInCircle(lat, lng, filter = {}) {
return new Promise((resolve, reject) => {
let params = [];
let query = 'SELECT';
query += defaultSelectGetInZone;
query += ` ,ST_Distance_Sphere( ST_GeomFromText('POINT(${lng} ${lat})'), z.boundary_points) AS distance_meters`;
// params.push(lng, lat);
query += ' FROM t_zones AS z';
query += ' INNER JOIN t_zones_types AS zt ON z.type = zt.id';
query += ' INNER JOIN t_zones_workflows AS zw ON z.workflow_type = zw.id';
query += ' LEFT JOIN t_clients AS c ON z.client_group_id = c.id';
query += ' WHERE z.dlt is null AND z.status = ? AND z.boundary_type = ?';
params.push(ZoneModels.STTS_ACTIVE, ZoneModels.ZONE_BOUNDARY_CIRCLE);
if (filter['zid']) {
query += ' AND z.id = ?';
params.push(filter['zid']);
}
query += ' HAVING boundary_radius >= distance_meters';
db.query(query, params, function (err, resp) {
if (err) {
reject(err);
return false;
}
resolve(resp);
return true;
});
});
}
static async getInShape(lat, lng, filter = {}) {
return new Promise((resolve, reject) => {
let params = [];
let query = 'SELECT';
query += defaultSelectGetInZone;
query += ` ,ST_Distance_Sphere( ST_GeomFromText('POINT(${lng} ${lat})'), z.boundary_points) AS distance_meters`;
query += ` ,MBRContains( boundary_points, ST_GeomFromText('POINT(${lng} ${lat})') ) as is_contain`;
query += ` ,MBRWithin( ST_GeomFromText('POINT(${lng} ${lat})'), boundary_points ) as is_within`;
// params.push(lng, lat);
query += ' FROM t_zones AS z';
query += ' INNER JOIN t_zones_types AS zt ON z.type = zt.id';
query += ' INNER JOIN t_zones_workflows AS zw ON z.workflow_type = zw.id';
query += ' LEFT JOIN t_clients AS c ON z.client_group_id = c.id';
query += ' WHERE z.dlt is null AND z.status = ? AND z.boundary_type IN (?,?)';
params.push(ZoneModels.STTS_ACTIVE, ZoneModels.ZONE_BOUNDARY_POLYGON, ZoneModels.ZONE_BOUNDARY_RECTANGLE);
if (filter['zid']) {
query += ' AND z.id = ?';
params.push(filter['zid']);
}
query += ' HAVING is_within = 1';
query += ' AND is_contain = 1';
db.query(query, params, function (err, resp) {
if (err) {
reject(err);
return false;
}
resolve(resp);
return true;
});
});
}
static async getOrdInCircle(lat, lng, filter = {}) {
return new Promise((resolve, reject) => {
let params = [];
let query = 'SELECT';
query += defaultSelectGetInZone;
query += ` ,ST_Distance_Sphere( ST_GeomFromText('POINT(${lng} ${lat})'), z.boundary_points) AS distance_meters`;
// params.push(lng, lat);
query += ' FROM t_zones AS z';
query += ' INNER JOIN t_zones_types AS zt ON z.type = zt.id';
query += ' INNER JOIN t_zones_workflows AS zw ON z.workflow_type = zw.id';
query += ' LEFT JOIN t_clients AS c ON z.client_group_id = c.id';
query += ' WHERE z.boundary_type = ?';
params.push(ZoneModels.ZONE_BOUNDARY_CIRCLE);
if (filter['zid']) {
query += ' AND z.id = ?';
params.push(filter['zid']);
}
query += ' HAVING boundary_radius >= distance_meters';
db.query(query, params, function (err, resp) {
if (err) {
reject(err);
return false;
}
resolve(resp);
return true;
});
});
}
static async getOrdInShape(lat, lng, filter = {}) {
return new Promise((resolve, reject) => {
let params = [];
let query = 'SELECT';
query += defaultSelectGetInZone;
query += ` ,ST_Distance_Sphere( ST_GeomFromText('POINT(${lng} ${lat})'), z.boundary_points) AS distance_meters`;
query += ` ,MBRContains( boundary_points, ST_GeomFromText('POINT(${lng} ${lat})') ) as is_contain`;
query += ` ,MBRWithin( ST_GeomFromText('POINT(${lng} ${lat})'), boundary_points ) as is_within`;
// params.push(lng, lat);
query += ' FROM t_zones AS z';
query += ' INNER JOIN t_zones_types AS zt ON z.type = zt.id';
query += ' INNER JOIN t_zones_workflows AS zw ON z.workflow_type = zw.id';
query += ' LEFT JOIN t_clients AS c ON z.client_group_id = c.id';
query += ' WHERe z.boundary_type IN (?,?)';
params.push(ZoneModels.ZONE_BOUNDARY_POLYGON, ZoneModels.ZONE_BOUNDARY_RECTANGLE);
if (filter['zid']) {
query += ' AND z.id = ?';
params.push(filter['zid']);
}
query += ' HAVING is_within = 1';
query += ' AND is_contain = 1';
db.query(query, params, function (err, resp) {
if (err) {
reject(err);
return false;
}
resolve(resp);
return true;
});
});
}
static async testZoning() {
return new Promise((resolve, reject) => {
`
-- in mysql using x,y => longitude,latitude
-- ST_GeomFromText(col) => convert text to blob, ST_AsText(col) convert blob to text
SELECT id,name,boundary_type,boundary_radius,ST_AsText(boundary_points) FROM db_trucking.t_zones;
-- nearest zone from this latLng for circle. if radius less than meters, it mean this loc in this zone
SELECT id,name,boundary_type,boundary_radius as radius,ST_AsText(boundary_points) AS zonasi
,ST_Distance_Sphere( ST_GeomFromText('POINT(106.834916 -6.161736)'), boundary_points) AS meters
FROM db_trucking.t_zones WHERE boundary_type='circle'
HAVING radius >= meters;
-- id:3 => -6.57538126,106.63426234
-- id:5 => -6.244811,106.865669
-- nearest zone from this latLng for polygon,rectangle
SELECT id,name,boundary_type
,MBRContains( boundary_points, ST_GeomFromText('POINT(106.865669 -6.244811)') ) as contain
,MBRWithin( ST_GeomFromText('POINT(106.865669 -6.244811)'), boundary_points ) as within
,ST_AsText(boundary_points) as zonasi
,ST_Distance_Sphere( ST_GeomFromText('POINT(106.865669 -6.244811)'), boundary_points) AS meters
FROM db_trucking.t_zones WHERE boundary_type IN ('polygon','rectangle')
HAVING within >= 1;
`
let params = [];
let query = 'SELECT * FROM t_zones';
db.query(query, params, function (err, resp) {
if (err) {
reject(err);
return false;
}
resolve(resp);
return true;
});
});
}
static async getCheckpointsInCircle(lat, lng, filter = {}) {
return new Promise((resolve, reject) => {
let params = [];
let where = '';
let query = 'SELECT';
query += defaultSelectGetInZone;
query += `
,ord.id as ord_id,ord.code as ord_code,ord_pck_drop.id as ord_pck_drop_id
,ord.status as stts_order,ord_pck_drop.stts as stts_delivery
,ord.crt as ord_crt,ord_pck_drop.crt as ord_pck_drop_crt
,checkpoint.id as checkpoint_id,checkpoint.pocket_sort,checkpoint.pocket_is_paid,checkpoint.pocket_total
,ord_drv.drv_id,ord_drv.drv_name,ord_drv.drv_bank_id,ord_drv.drv_bank_code,ord_drv.drv_bank_name,ord_drv.drv_bank_short_name,ord_drv.drv_bank_acc_number,ord_drv.drv_bank_acc_name
`;
query += ` ,ST_Distance_Sphere( ST_GeomFromText('POINT(${lng} ${lat})'), z.boundary_points) AS distance_meters`;
// params.push(lng, lat);
query += ' FROM t_zones AS z';
query += ' INNER JOIN t_zones_types AS zt ON z.type = zt.id';
query += ' INNER JOIN t_zones_workflows AS zw ON z.workflow_type = zw.id';
query += ' LEFT JOIN t_clients AS c ON z.client_group_id = c.id';
query += ' INNER JOIN t_orders_checkpoints AS checkpoint ON z.id = checkpoint.pck_id';
query += ' INNER JOIN t_orders AS ord ON checkpoint.ord_id = ord.id';
query += ' INNER JOIN t_orders_pck_drop AS ord_pck_drop ON checkpoint.ord_id = ord_pck_drop.ord_id';
query += ' INNER JOIN t_orders_drivers AS ord_drv ON checkpoint.ord_id = ord_drv.ord_id';
query += ' WHERE ord.dlt is null AND checkpoint.dlt is null AND z.boundary_type = ?';
params.push(ZoneModels.ZONE_BOUNDARY_CIRCLE);
if (typeof filter['pocket_is_paid'] !== 'undefined') query += ' AND checkpoint.pocket_is_paid = ' + filter['pocket_is_paid'];
if (typeof filter['where_not_pocket_is_paid'] !== 'undefined') query += ' AND checkpoint.pocket_is_paid != ' + filter['where_not_pocket_is_paid'];
if (typeof filter['pocket_sort'] !== 'undefined') query += ' AND checkpoint.pocket_sort != 1';
if (typeof filter['drv_id'] !== 'undefined') query += ' AND ord_drv.drv_id = ' + filter['drv_id'];
if (filter['stts_delivery'] && filter['stts_delivery'].length > 0) {
where += ' AND ord_pck_drop.stts IN (';
for (const stts_delivery of filter['stts_delivery']) {
where += '?,';
params.push(stts_delivery);
}
where = where.slice(0, -1) + ')';
}
query += where;
query += ' HAVING boundary_radius >= distance_meters';
db.query(query, params, function (err, resp) {
if (err) {
reject(err);
return false;
}
resolve(resp);
return true;
});
});
}
static async getCheckpointsInShape(lat, lng, filter = {}) {
return new Promise((resolve, reject) => {
let params = [];
let where = '';
let query = 'SELECT';
query += defaultSelectGetInZone;
query += `
,ord.id as ord_id,ord.code as ord_code,ord_pck_drop.id as ord_pck_drop_id
,ord.status as stts_order,ord_pck_drop.stts as stts_delivery
,ord.crt as ord_crt,ord_pck_drop.crt as ord_pck_drop_crt
,checkpoint.id as checkpoint_id,checkpoint.pocket_sort,checkpoint.pocket_is_paid,checkpoint.pocket_total
,ord_drv.drv_id,ord_drv.drv_name,ord_drv.drv_bank_id,ord_drv.drv_bank_code,ord_drv.drv_bank_name,ord_drv.drv_bank_short_name,ord_drv.drv_bank_branch_name,ord_drv.drv_bank_acc_number,ord_drv.drv_bank_acc_name
`;
query += ` ,ST_Distance_Sphere( ST_GeomFromText('POINT(${lng} ${lat})'), z.boundary_points) AS distance_meters`;
query += ` ,MBRContains( boundary_points, ST_GeomFromText('POINT(${lng} ${lat})') ) as is_contain`;
query += ` ,MBRWithin( ST_GeomFromText('POINT(${lng} ${lat})'), boundary_points ) as is_within`;
// params.push(lng, lat);
query += ' FROM t_zones AS z';
query += ' INNER JOIN t_zones_types AS zt ON z.type = zt.id';
query += ' INNER JOIN t_zones_workflows AS zw ON z.workflow_type = zw.id';
query += ' LEFT JOIN t_clients AS c ON z.client_group_id = c.id';
query += ' INNER JOIN t_orders_checkpoints AS checkpoint ON z.id = checkpoint.pck_id';
query += ' INNER JOIN t_orders AS ord ON checkpoint.ord_id = ord.id';
query += ' INNER JOIN t_orders_pck_drop AS ord_pck_drop ON checkpoint.ord_id = ord_pck_drop.ord_id';
query += ' INNER JOIN t_orders_drivers AS ord_drv ON checkpoint.ord_id = ord_drv.ord_id';
query += ' WHERE ord.dlt is null AND checkpoint.dlt is null AND z.boundary_type IN (?,?)';
params.push(ZoneModels.ZONE_BOUNDARY_POLYGON, ZoneModels.ZONE_BOUNDARY_RECTANGLE);
if (typeof filter['pocket_is_paid'] !== 'undefined') query += ' AND checkpoint.pocket_is_paid = ' + filter['pocket_is_paid'];
if (typeof filter['where_not_pocket_is_paid'] !== 'undefined') query += ' AND checkpoint.pocket_is_paid != ' + filter['where_not_pocket_is_paid'];
if (typeof filter['pocket_sort'] !== 'undefined') query += ' AND checkpoint.pocket_sort != 1';
if (typeof filter['drv_id'] !== 'undefined') query += ' AND ord_drv.drv_id = ' + filter['drv_id'];
if (filter['stts_delivery'] && filter['stts_delivery'].length > 0) {
where += ' AND ord_pck_drop.stts IN (';
for (const stts_delivery of filter['stts_delivery']) {
where += '?,';
params.push(stts_delivery);
}
where = where.slice(0, -1) + ')';
}
query += where;
query += ' HAVING is_within = 1';
query += ' AND is_contain = 1';
db.query(query, params, function (err, resp) {
if (err) {
reject(err);
return false;
}
resolve(resp);
return true;
});
});
}
}
module.exports = ZoneModels;