bugfix of 0004A and B, where the tide window may have deviated by few seconds, so the wrong state would be concluded.
This commit is contained in:
parent
c0a9557584
commit
82309a53d6
@ -2,6 +2,15 @@ import datetime
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
|
def validate_time_exceeds_threshold(value:datetime.datetime, seconds:int=60, minutes:int=60, hours:int=24, days:int=30, months:int=12)->bool:
|
||||||
|
"""returns a boolean when the input value is very distant in the future. The parameters provide the threshold"""
|
||||||
|
# time difference in seconds. Positive: in the future, Negative: in the past
|
||||||
|
current_time = datetime.datetime.now()
|
||||||
|
time_ = (value-current_time).total_seconds()
|
||||||
|
threshold = seconds*minutes*hours*days*months
|
||||||
|
print(time_, threshold)
|
||||||
|
return time_>=threshold
|
||||||
|
|
||||||
class TimeLogic():
|
class TimeLogic():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
return
|
return
|
||||||
@ -41,10 +50,11 @@ class TimeLogic():
|
|||||||
def time_inbetween(self, query_time:datetime.datetime, start_time:datetime.datetime, end_time:datetime.datetime) -> bool:
|
def time_inbetween(self, query_time:datetime.datetime, start_time:datetime.datetime, end_time:datetime.datetime) -> bool:
|
||||||
"""
|
"""
|
||||||
checks, whether the query time is inbetween the start & end time. Returns a bool to indicate that.
|
checks, whether the query time is inbetween the start & end time. Returns a bool to indicate that.
|
||||||
|
The function internally rounds seconds and microseconds to zero, so they are ignored in the evaluation.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
a = datetime.datetime(2017, 5, 16, 8, 21, 10)
|
a = datetime.datetime(2017, 5, 16, 8, 21, 10)
|
||||||
b = datetime.datetime(2017, 5, 17, 8, 21, 10)
|
b = datetime.datetime(2017, 5, 17, 8, 21, 09)
|
||||||
c = datetime.datetime(2017, 5, 18, 8, 21, 10)
|
c = datetime.datetime(2017, 5, 18, 8, 21, 10)
|
||||||
|
|
||||||
is b between a and c? -> yes. Returns True
|
is b between a and c? -> yes. Returns True
|
||||||
@ -55,7 +65,12 @@ class TimeLogic():
|
|||||||
assert isinstance(query_time, datetime.datetime)
|
assert isinstance(query_time, datetime.datetime)
|
||||||
assert isinstance(start_time, datetime.datetime)
|
assert isinstance(start_time, datetime.datetime)
|
||||||
assert isinstance(end_time, datetime.datetime)
|
assert isinstance(end_time, datetime.datetime)
|
||||||
|
"""
|
||||||
|
query_time = query_time.replace(second=0, microsecond=0)
|
||||||
|
start_time = start_time.replace(second=0, microsecond=0)
|
||||||
|
end_time = end_time.replace(second=0, microsecond=0)"""
|
||||||
|
|
||||||
|
print("time_inbetween function! UNVIOLATED?", start_time <= query_time <= end_time, start_time, query_time, end_time)
|
||||||
return start_time <= query_time <= end_time
|
return start_time <= query_time <= end_time
|
||||||
|
|
||||||
def time_inbetween_absolute_delta(self, query_time:datetime.datetime, start_time:datetime.datetime, end_time:datetime.datetime) -> tuple:
|
def time_inbetween_absolute_delta(self, query_time:datetime.datetime, start_time:datetime.datetime, end_time:datetime.datetime) -> tuple:
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import types
|
|||||||
from BreCal.database.enums import ParticipantType, ShipcallType, ParticipantwiseTimeDelta
|
from BreCal.database.enums import ParticipantType, ShipcallType, ParticipantwiseTimeDelta
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
import datetime
|
||||||
from BreCal.validators.time_logic import TimeLogic
|
from BreCal.validators.time_logic import TimeLogic
|
||||||
from BreCal.database.enums import StatusFlags
|
from BreCal.database.enums import StatusFlags
|
||||||
#from BreCal.validators.schema_validation import validation_state_and_validation_name
|
#from BreCal.validators.schema_validation import validation_state_and_validation_name
|
||||||
@ -713,7 +714,12 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
|
|||||||
if self.check_is_not_a_time_or_is_none(times_terminal.operations_start) or self.check_is_not_a_time_or_is_none(times_agency.eta_berth):
|
if self.check_is_not_a_time_or_is_none(times_terminal.operations_start) or self.check_is_not_a_time_or_is_none(times_agency.eta_berth):
|
||||||
return self.get_no_violation_default_output()
|
return self.get_no_violation_default_output()
|
||||||
|
|
||||||
# check, whether the start of operations is AFTER the estimated arrival time
|
# check, whether the end of operations is BEFORE the estimated arrival time
|
||||||
|
if isinstance(times_terminal.operations_start, (pd.Timestamp, datetime.datetime)):
|
||||||
|
times_terminal.operations_start = times_terminal.operations_start.replace(second=0, microsecond=0)
|
||||||
|
if isinstance(times_agency.eta_berth, (pd.Timestamp, datetime.datetime)):
|
||||||
|
times_agency.eta_berth = times_agency.eta_berth.replace(second=0, microsecond=0)
|
||||||
|
|
||||||
violation_state = times_terminal.operations_start < times_agency.eta_berth
|
violation_state = times_terminal.operations_start < times_agency.eta_berth
|
||||||
|
|
||||||
if violation_state:
|
if violation_state:
|
||||||
@ -749,6 +755,11 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
|
|||||||
return self.get_no_violation_default_output()
|
return self.get_no_violation_default_output()
|
||||||
|
|
||||||
# check, whether the end of operations is AFTER the estimated departure time
|
# check, whether the end of operations is AFTER the estimated departure time
|
||||||
|
if isinstance(times_terminal.operations_end, (pd.Timestamp, datetime.datetime)):
|
||||||
|
times_terminal.operations_end = times_terminal.operations_end.replace(second=0, microsecond=0)
|
||||||
|
if isinstance(times_agency.etd_berth, (pd.Timestamp, datetime.datetime)):
|
||||||
|
times_agency.etd_berth = times_agency.etd_berth.replace(second=0, microsecond=0)
|
||||||
|
|
||||||
violation_state = times_terminal.operations_end > times_agency.etd_berth
|
violation_state = times_terminal.operations_end > times_agency.etd_berth
|
||||||
|
|
||||||
if violation_state:
|
if violation_state:
|
||||||
|
|||||||
@ -1062,6 +1062,38 @@ def test_validation_rule_fct_etd_time_not_in_tidal_window__etd_outside_tidal_win
|
|||||||
assert code==StatusFlags.RED, f"state should be 'red', etd_berth takes place after the tidal window"
|
assert code==StatusFlags.RED, f"state should be 'red', etd_berth takes place after the tidal window"
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def test_validation_rule_fct_tidal_window_is_precisely_eta_or_etd__is_okay(build_sql_proxy_connection):
|
||||||
|
"""0004-A & 0004-B eta/etd is exactly tidal window: no violation"""
|
||||||
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
shipcall = get_shipcall_simple()
|
||||||
|
df_times = get_df_times(shipcall)
|
||||||
|
times_agency = vr.sql_handler.get_times_for_participant_type(df_times, participant_type=ParticipantType.AGENCY.value)
|
||||||
|
|
||||||
|
|
||||||
|
# tidal window: [t0 +1min, t0 +1hr)
|
||||||
|
# etd berth:
|
||||||
|
t0_time = datetime.datetime.now()
|
||||||
|
times_agency.eta_berth = t0_time
|
||||||
|
shipcall.tidal_window_from = t0_time
|
||||||
|
shipcall.tidal_window_to = t0_time+datetime.timedelta(minutes=3)
|
||||||
|
|
||||||
|
violation_state = not vr.time_logic.time_inbetween(
|
||||||
|
query_time=times_agency.eta_berth, start_time=shipcall.tidal_window_from, end_time=shipcall.tidal_window_to
|
||||||
|
)
|
||||||
|
assert violation_state==False
|
||||||
|
|
||||||
|
t0_time = datetime.datetime.now()
|
||||||
|
times_agency.etd_berth = t0_time
|
||||||
|
shipcall.tidal_window_from = t0_time+datetime.timedelta(minutes=-3)
|
||||||
|
shipcall.tidal_window_to = t0_time
|
||||||
|
|
||||||
|
violation_state = not vr.time_logic.time_inbetween(
|
||||||
|
query_time=times_agency.etd_berth, start_time=shipcall.tidal_window_from, end_time=shipcall.tidal_window_to
|
||||||
|
)
|
||||||
|
assert violation_state==False
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
def test_validation_rule_fct_too_many_identical_eta_times__is_violated_by_too_many_identical_times(build_sql_proxy_connection):
|
def test_validation_rule_fct_too_many_identical_eta_times__is_violated_by_too_many_identical_times(build_sql_proxy_connection):
|
||||||
"""0005-A validation_rule_fct_too_many_identical_eta_times"""
|
"""0005-A validation_rule_fct_too_many_identical_eta_times"""
|
||||||
vr = build_sql_proxy_connection['vr']
|
vr = build_sql_proxy_connection['vr']
|
||||||
|
|||||||
Reference in New Issue
Block a user