Added notification generation for next 24hrs shipcalls
This commit is contained in:
parent
50cecc6a9d
commit
e5d9d051ea
@ -8,7 +8,7 @@ def create_sql_query_shipcall_get(options:dict)->str:
|
|||||||
|
|
||||||
args:
|
args:
|
||||||
options : dict. A dictionary, which must contains the 'past_days' key (int). Determines the range
|
options : dict. A dictionary, which must contains the 'past_days' key (int). Determines the range
|
||||||
by which shipcalls are filtered.
|
by which shipcalls are filtered.
|
||||||
"""
|
"""
|
||||||
if "participant_id" not in options: # if no participant_id is given, all shipcalls are selected
|
if "participant_id" not in options: # if no participant_id is given, all shipcalls are selected
|
||||||
query = ("SELECT s.id as id, ship_id, port_id, type, eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, " +
|
query = ("SELECT s.id as id, ship_id, port_id, type, eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, " +
|
||||||
@ -17,7 +17,7 @@ def create_sql_query_shipcall_get(options:dict)->str:
|
|||||||
"evaluation_message, evaluation_time, evaluation_notifications_sent, s.created as created, s.modified as modified, time_ref_point " +
|
"evaluation_message, evaluation_time, evaluation_notifications_sent, s.created as created, s.modified as modified, time_ref_point " +
|
||||||
"FROM shipcall s " +
|
"FROM shipcall s " +
|
||||||
"LEFT JOIN times t ON t.shipcall_id = s.id AND t.participant_type = 8 " +
|
"LEFT JOIN times t ON t.shipcall_id = s.id AND t.participant_type = 8 " +
|
||||||
"WHERE " +
|
"WHERE " +
|
||||||
"(type = 1 AND " +
|
"(type = 1 AND " +
|
||||||
"((t.id IS NOT NULL AND t.eta_berth >= DATE(NOW() - INTERVAL %d DAY)) OR " +
|
"((t.id IS NOT NULL AND t.eta_berth >= DATE(NOW() - INTERVAL %d DAY)) OR " +
|
||||||
"(eta >= DATE(NOW() - INTERVAL %d DAY)))) OR " +
|
"(eta >= DATE(NOW() - INTERVAL %d DAY)))) OR " +
|
||||||
@ -61,9 +61,9 @@ def create_sql_query_shipcall_post(schemaModel:dict)->str:
|
|||||||
if key == "evaluation":
|
if key == "evaluation":
|
||||||
continue
|
continue
|
||||||
if key == "evaluation_message":
|
if key == "evaluation_message":
|
||||||
continue
|
continue
|
||||||
if key == "type_value":
|
if key == "type_value":
|
||||||
continue
|
continue
|
||||||
if key == "evaluation_value":
|
if key == "evaluation_value":
|
||||||
continue
|
continue
|
||||||
if isNotFirst:
|
if isNotFirst:
|
||||||
@ -214,12 +214,12 @@ def create_sql_query_ship_put(schemaModel:dict):
|
|||||||
class SQLQuery():
|
class SQLQuery():
|
||||||
"""
|
"""
|
||||||
This class provides quick access to different SQL query functions, which creates default queries for the BreCal package.
|
This class provides quick access to different SQL query functions, which creates default queries for the BreCal package.
|
||||||
Each method is callable without initializing the SQLQuery object.
|
Each method is callable without initializing the SQLQuery object.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
SQLQuery.get_berths()
|
SQLQuery.get_berths()
|
||||||
|
|
||||||
When the data violates one of the rules, a marshmallow.ValidationError is raised, which details the issues.
|
When the data violates one of the rules, a marshmallow.ValidationError is raised, which details the issues.
|
||||||
"""
|
"""
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
pass
|
pass
|
||||||
@ -233,30 +233,30 @@ class SQLQuery():
|
|||||||
def get_history()->str:
|
def get_history()->str:
|
||||||
query = "SELECT id, participant_id, shipcall_id, timestamp, eta, type, operation FROM history WHERE shipcall_id = ?shipcallid?"
|
query = "SELECT id, participant_id, shipcall_id, timestamp, eta, type, operation FROM history WHERE shipcall_id = ?shipcallid?"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_user()->str:
|
def get_user()->str:
|
||||||
query = "SELECT id, participant_id, first_name, last_name, user_name, user_email, user_phone, password_hash, " +\
|
query = "SELECT id, participant_id, first_name, last_name, user_name, user_email, user_phone, password_hash, " +\
|
||||||
"api_key, notify_email, notify_whatsapp, notify_signal, notify_popup, created, modified FROM user " +\
|
"api_key, notify_email, notify_whatsapp, notify_signal, notify_popup, created, modified FROM user " +\
|
||||||
"WHERE user_name = ?username? OR user_email = ?username?"
|
"WHERE user_name = ?username? OR user_email = ?username?"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_notifications()->str:
|
def get_notifications()->str:
|
||||||
query = "SELECT id, shipcall_id, level, type, message, created, modified FROM notification " + \
|
query = "SELECT id, shipcall_id, level, type, message, created, modified FROM notification " + \
|
||||||
"WHERE shipcall_id = ?scid?"
|
"WHERE shipcall_id = ?scid?"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_participant_by_user_id()->str:
|
def get_participant_by_user_id()->str:
|
||||||
query = "SELECT p.id as id, p.name as name, p.street as street, p.postal_code as postal_code, p.city as city, p.type as type, p.flags as flags, p.created as created, p.modified as modified, p.deleted as deleted FROM participant p INNER JOIN user u WHERE u.participant_id = p.id and u.id = ?userid?"
|
query = "SELECT p.id as id, p.name as name, p.street as street, p.postal_code as postal_code, p.city as city, p.type as type, p.flags as flags, p.created as created, p.modified as modified, p.deleted as deleted FROM participant p INNER JOIN user u WHERE u.participant_id = p.id and u.id = ?userid?"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_participants()->str:
|
def get_participants()->str:
|
||||||
query = "SELECT id, name, street, postal_code, city, type, flags, created, modified, deleted FROM participant p ORDER BY p.name"
|
query = "SELECT id, name, street, postal_code, city, type, flags, created, modified, deleted FROM participant p ORDER BY p.name"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_shipcalls(options:dict={'past_days':3})->str:
|
def get_shipcalls(options:dict={'past_days':3})->str:
|
||||||
# a pytest proves this method to be identical to create_sql_query_shipcall_get(options)
|
# a pytest proves this method to be identical to create_sql_query_shipcall_get(options)
|
||||||
@ -278,17 +278,26 @@ class SQLQuery():
|
|||||||
f"(etd >= DATE(NOW() - INTERVAL {past_days} DAY)))) " + \
|
f"(etd >= DATE(NOW() - INTERVAL {past_days} DAY)))) " + \
|
||||||
"ORDER BY eta")
|
"ORDER BY eta")
|
||||||
return query
|
return query
|
||||||
|
|
||||||
|
def get_next24hrs_shipcalls()->str:
|
||||||
|
query = ("SELECT s.id as id, ship.name as name FROM shipcall s INNER JOIN ship ON s.ship_id = ship.id LEFT JOIN times t on t.shipcall_id = s.id AND t.participant_type = 8 " + \
|
||||||
|
"WHERE (type = 1 AND ((t.id IS NOT NULL AND t.eta_berth >= NOW() AND t.eta_berth < (NOW() + INTERVAL 1 DAY))" + \
|
||||||
|
"OR (eta >= NOW() AND eta < (NOW() + INTERVAL 1 DAY)))) OR " + \
|
||||||
|
"((type = 2 OR type = 3) AND ((t.id IS NOT NULL AND t.etd_berth >= NOW() AND " + \
|
||||||
|
"t.etd_berth < (NOW() + INTERVAL 1 DAY)) OR (etd >= NOW() AND etd < (NOW() + INTERVAL 1 DAY))))" + \
|
||||||
|
"AND s.canceled = 0")
|
||||||
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_ships()->str:
|
def get_ships()->str:
|
||||||
query = "SELECT id, name, imo, callsign, participant_id, length, width, is_tug, bollard_pull, eni, created, modified, deleted FROM ship ORDER BY name"
|
query = "SELECT id, name, imo, callsign, participant_id, length, width, is_tug, bollard_pull, eni, created, modified, deleted FROM ship ORDER BY name"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_ship_by_id()->str:
|
def get_ship_by_id()->str:
|
||||||
query = "SELECT * FROM ship where id = ?id?"
|
query = "SELECT * FROM ship where id = ?id?"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_times()->str:
|
def get_times()->str:
|
||||||
query = "SELECT id, eta_berth, eta_berth_fixed, etd_berth, etd_berth_fixed, lock_time, lock_time_fixed, " + \
|
query = "SELECT id, eta_berth, eta_berth_fixed, etd_berth, etd_berth_fixed, lock_time, lock_time_fixed, " + \
|
||||||
@ -296,12 +305,12 @@ class SQLQuery():
|
|||||||
"berth_id, berth_info, pier_side, participant_type, created, modified, ata, atd, eta_interval_end, etd_interval_end FROM times " + \
|
"berth_id, berth_info, pier_side, participant_type, created, modified, ata, atd, eta_interval_end, etd_interval_end FROM times " + \
|
||||||
"WHERE times.shipcall_id = ?scid?"
|
"WHERE times.shipcall_id = ?scid?"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_user_by_id():
|
def get_user_by_id():
|
||||||
query = "SELECT * FROM user where id = ?id?"
|
query = "SELECT * FROM user where id = ?id?"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_user_put(schemaModel:dict):
|
def get_user_put(schemaModel:dict):
|
||||||
# a pytest proves this method to be identical to create_sql_query_user_put(schemaModel)
|
# a pytest proves this method to be identical to create_sql_query_user_put(schemaModel)
|
||||||
@ -326,7 +335,7 @@ class SQLQuery():
|
|||||||
def get_participant_from_id()->str:
|
def get_participant_from_id()->str:
|
||||||
query = "SELECT id, type, flags FROM participant WHERE id=?participant_id?"
|
query = "SELECT id, type, flags FROM participant WHERE id=?participant_id?"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_shipcall_post(schemaModel:dict)->str:
|
def get_shipcall_post(schemaModel:dict)->str:
|
||||||
# a pytest proves this method to be identical to create_sql_query_shipcall_post(schemaModel)
|
# a pytest proves this method to be identical to create_sql_query_shipcall_post(schemaModel)
|
||||||
@ -349,28 +358,28 @@ class SQLQuery():
|
|||||||
def get_last_insert_id()->str:
|
def get_last_insert_id()->str:
|
||||||
query = "select last_insert_id()"
|
query = "select last_insert_id()"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_shipcall_post_last_insert_id()->str:
|
def get_shipcall_post_last_insert_id()->str:
|
||||||
"""alias function. May be deleted soon"""
|
"""alias function. May be deleted soon"""
|
||||||
query = SQLQuery.get_last_insert_id()
|
query = SQLQuery.get_last_insert_id()
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_shipcall_post_update_shipcall_participant_map()->str:
|
def get_shipcall_post_update_shipcall_participant_map()->str:
|
||||||
query = "INSERT INTO shipcall_participant_map (shipcall_id, participant_id, type) VALUES (?shipcall_id?, ?participant_id?, ?type?)"
|
query = "INSERT INTO shipcall_participant_map (shipcall_id, participant_id, type) VALUES (?shipcall_id?, ?participant_id?, ?type?)"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_sql_query_history_post()->str:
|
def create_sql_query_history_post()->str:
|
||||||
query = create_sql_query_history_post()
|
query = create_sql_query_history_post()
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_shipcall_by_id()->str:
|
def get_shipcall_by_id()->str:
|
||||||
query = "SELECT * FROM shipcall where id = ?id?"
|
query = "SELECT * FROM shipcall where id = ?id?"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_shipcall_put(schemaModel:dict)->str:
|
def get_shipcall_put(schemaModel:dict)->str:
|
||||||
# a pytest proves this method to be identical to create_sql_query_shipcall_put(schemaModel)
|
# a pytest proves this method to be identical to create_sql_query_shipcall_put(schemaModel)
|
||||||
@ -384,12 +393,12 @@ class SQLQuery():
|
|||||||
|
|
||||||
query = prefix + body + suffix
|
query = prefix + body + suffix
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_shipcall_participant_map_by_shipcall_id()->str:
|
def get_shipcall_participant_map_by_shipcall_id()->str:
|
||||||
query = "SELECT id, participant_id, type FROM shipcall_participant_map where shipcall_id = ?id?"
|
query = "SELECT id, participant_id, type FROM shipcall_participant_map where shipcall_id = ?id?"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_shipcall_participant_map_by_shipcall_id_and_type()->str:
|
def get_shipcall_participant_map_by_shipcall_id_and_type()->str:
|
||||||
query = "SELECT id, participant_id FROM shipcall_participant_map where (shipcall_id = ?id? AND type=?type?)"
|
query = "SELECT id, participant_id FROM shipcall_participant_map where (shipcall_id = ?id? AND type=?type?)"
|
||||||
@ -432,14 +441,14 @@ class SQLQuery():
|
|||||||
def get_ship_delete_by_id()->str:
|
def get_ship_delete_by_id()->str:
|
||||||
query = "UPDATE ship SET deleted = 1 WHERE id = ?id?"
|
query = "UPDATE ship SET deleted = 1 WHERE id = ?id?"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_notification_post()->str:
|
def get_notification_post()->str:
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
# #TODO: this query is wrong and just a proxy for a POST request
|
# #TODO: this query is wrong and just a proxy for a POST request
|
||||||
query = "INSERT INTO shipcall_participant_map (shipcall_id, participant_id, type) VALUES (?shipcall_id?, ?participant_id?, ?type?)"
|
query = "INSERT INTO shipcall_participant_map (shipcall_id, participant_id, type) VALUES (?shipcall_id?, ?participant_id?, ?type?)"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_shipcall_put_notification_state()->str:
|
def get_shipcall_put_notification_state()->str:
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|||||||
@ -4,6 +4,8 @@ from BreCal.schemas import model
|
|||||||
from BreCal.local_db import getPoolConnection
|
from BreCal.local_db import getPoolConnection
|
||||||
from BreCal.database.update_database import evaluate_shipcall_state
|
from BreCal.database.update_database import evaluate_shipcall_state
|
||||||
from BreCal.database.sql_queries import create_sql_query_shipcall_get
|
from BreCal.database.sql_queries import create_sql_query_shipcall_get
|
||||||
|
from BreCal.database.sql_queries import SQLQuery
|
||||||
|
from BreCal.database.sql_utils import get_notification_for_shipcall_and_type
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
import schedule
|
import schedule
|
||||||
@ -58,12 +60,7 @@ def UpdateNotifications():
|
|||||||
query = "SELECT * FROM notification WHERE level = 0 AND created < DATE(NOW() - INTERVAL 10 MINUTE)"
|
query = "SELECT * FROM notification WHERE level = 0 AND created < DATE(NOW() - INTERVAL 10 MINUTE)"
|
||||||
data = commands.query(query, model=model.Notification)
|
data = commands.query(query, model=model.Notification)
|
||||||
for notification in data:
|
for notification in data:
|
||||||
notification.level = 1
|
commands.execute("UPDATE notification SET level = 1 WHERE id = ?id?", param={"id":notification.id})
|
||||||
commands.update(notification)
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
# send "real" notifications to user
|
|
||||||
# ... E-Mail, messenger
|
|
||||||
|
|
||||||
pooledConnection.close()
|
pooledConnection.close()
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
@ -82,6 +79,35 @@ def add_function_to_schedule__send_notifications(vr, interval_in_minutes:int=10)
|
|||||||
schedule.every(interval_in_minutes).minutes.do(vr.notifier.send_notifications)
|
schedule.every(interval_in_minutes).minutes.do(vr.notifier.send_notifications)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def eval_next_24_hrs():
|
||||||
|
try:
|
||||||
|
pooledConnection = getPoolConnection()
|
||||||
|
commands = pydapper.using(pooledConnection)
|
||||||
|
query = SQLQuery.get_next24hrs_shipcalls()
|
||||||
|
data = commands.query(query)
|
||||||
|
nquery = "INSERT INTO notification (shipcall_id, participant_id, level, type, message) VALUES (?shipcall_id?, ?participant_id?, 0, 2, ?message?)"
|
||||||
|
for shipcall in data:
|
||||||
|
existing_notifications = get_notification_for_shipcall_and_type(shipcall["id"], 2)
|
||||||
|
query = SQLQuery.get_shipcall_participant_map_by_shipcall_id()
|
||||||
|
participants = commands.query(query, model=dict, param={"id":shipcall["id"]})
|
||||||
|
for participant in participants:
|
||||||
|
if participant["type"] == 1: # BSMD
|
||||||
|
continue
|
||||||
|
if participant["type"] == 32: # PORT AUTHORITY
|
||||||
|
continue
|
||||||
|
# check if "open" notification already exists
|
||||||
|
found_notification = False
|
||||||
|
for existing_notification in existing_notifications:
|
||||||
|
if existing_notification["participant_id"] == participant["id"] and existing_notification["level"] == 0:
|
||||||
|
found_notification = True
|
||||||
|
break
|
||||||
|
if not found_notification:
|
||||||
|
commands.execute(nquery, param={"shipcall_id":shipcall["id"], "participant_id": participant["participant_id"], "message":shipcall["name"]})
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
logging.error(ex)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
def setup_schedule(update_shipcalls_interval_in_minutes:int=60):
|
def setup_schedule(update_shipcalls_interval_in_minutes:int=60):
|
||||||
|
|
||||||
@ -94,9 +120,13 @@ def setup_schedule(update_shipcalls_interval_in_minutes:int=60):
|
|||||||
|
|
||||||
add_function_to_evaluate_notifications()
|
add_function_to_evaluate_notifications()
|
||||||
|
|
||||||
|
schedule.every().day.at("09:00").do(eval_next_24_hrs)
|
||||||
|
|
||||||
# placeholder: create/send notifications
|
# placeholder: create/send notifications
|
||||||
# add_function_to_schedule__send_notifications(...)
|
# add_function_to_schedule__send_notifications(...)
|
||||||
|
|
||||||
|
# TODO: Add schedule function to evaluate all notifications in level 1 and create actions
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user