diff --git a/business_objects/dog/button_shape.py b/business_objects/dog/button_shape.py index 275669b..61b7092 100644 --- a/business_objects/dog/button_shape.py +++ b/business_objects/dog/button_shape.py @@ -142,19 +142,29 @@ class Parameters_Button_Shape(Get_Many_Parameters_Base): ids_button_shape: str names_button_shape: str notes_button_shape: str + get_all_user: bool + get_inactive_user: bool + ids_user: str + names_user: str + emails_user: str require_all_id_search_filters_met: bool require_any_id_search_filters_met: bool require_all_non_id_search_filters_met: bool require_any_non_id_search_filters_met: bool @classmethod - def get_default(cls): + def get_default(cls, id_user_session): return cls( get_all_button_shape = True , get_inactive_button_shape = False , ids_button_shape = '' , names_button_shape = '' , notes_button_shape = '' + , get_all_user = False + , get_inactive_user = False + , ids_user = str(id_user_session) + , names_user = '' + , emails_user = '' , require_all_id_search_filters_met = True , require_any_id_search_filters_met = True , require_all_non_id_search_filters_met = False @@ -169,6 +179,11 @@ class Parameters_Button_Shape(Get_Many_Parameters_Base): , ids_button_shape = json.get('a_ids_button_shape', '') , names_button_shape = json.get('a_names_button_shape', '') , notes_button_shape = json.get('a_notes_button_shape', '') + , get_all_user = json.get('a_get_all_user', False) + , get_inactive_user = json.get('a_get_inactive_user', False) + , ids_user = json.get('a_ids_user', '') + , names_user = json.get('a_names_user', '') + , emails_user = json.get('a_emails_user', '') , require_all_id_search_filters_met = json.get('a_require_all_id_search_filters_met', True) , require_any_id_search_filters_met = json.get('a_require_any_id_search_filters_met', True) , require_all_non_id_search_filters_met = json.get('a_require_all_non_id_search_filters_met', False) @@ -197,6 +212,11 @@ class Parameters_Button_Shape(Get_Many_Parameters_Base): , 'a_ids_button_shape': self.ids_button_shape , 'a_names_button_shape': self.names_button_shape , 'a_notes_button_shape': self.notes_button_shape + , 'a_get_all_user': self.get_all_user + , 'a_get_inactive_user': self.get_inactive_user + , 'a_ids_user': self.ids_user + , 'a_names_user': self.names_user + , 'a_emails_user': self.emails_user , 'a_require_all_id_search_filters_met': self.require_all_id_search_filters_met , 'a_require_any_id_search_filters_met': self.require_any_id_search_filters_met , 'a_require_all_non_id_search_filters_met': self.require_all_non_id_search_filters_met diff --git a/business_objects/dog/command.py b/business_objects/dog/command.py index e0208f6..2b1355c 100644 --- a/business_objects/dog/command.py +++ b/business_objects/dog/command.py @@ -189,6 +189,11 @@ class Parameters_Command(Get_Many_Parameters_Base): names_command: str hand_signal_default_descriptions_command: str notes_command: str + get_all_user: bool + get_inactive_user: bool + ids_user: str + names_user: str + emails_user: str require_all_id_search_filters_met: bool require_any_id_search_filters_met: bool require_all_non_id_search_filters_met: bool @@ -197,7 +202,7 @@ class Parameters_Command(Get_Many_Parameters_Base): output_commands: bool @classmethod - def get_default(cls): + def get_default(cls, id_user_session): return cls( get_all_command_category = True , get_inactive_command_category = False @@ -209,6 +214,11 @@ class Parameters_Command(Get_Many_Parameters_Base): , names_command = '' , hand_signal_default_descriptions_command = '' , notes_command = '' + , get_all_user = False + , get_inactive_user = False + , ids_user = str(id_user_session) + , names_user = '' + , emails_user = '' , require_all_id_search_filters_met = True , require_any_id_search_filters_met = True , require_all_non_id_search_filters_met = False @@ -230,6 +240,11 @@ class Parameters_Command(Get_Many_Parameters_Base): , names_command = json.get('a_names_command', '') , hand_signal_default_descriptions_command = json.get('a_hand_signal_default_descriptions_command', '') , notes_command = json.get('a_notes_command', '') + , get_all_user = json.get('a_get_all_user', False) + , get_inactive_user = json.get('a_get_inactive_user', False) + , ids_user = json.get('a_ids_user', '') + , names_user = json.get('a_names_user', '') + , emails_user = json.get('a_emails_user', '') , require_all_id_search_filters_met = json.get('a_require_all_id_search_filters_met', True) , require_any_id_search_filters_met = json.get('a_require_any_id_search_filters_met', True) , require_all_non_id_search_filters_met = json.get('a_require_all_non_id_search_filters_met', False) @@ -239,12 +254,12 @@ class Parameters_Command(Get_Many_Parameters_Base): ) @classmethod - def from_form_filters_command(cls, form): + def from_form_filters_command(cls, form, id_user_session): av.val_instance(form, 'form', 'Parameters_Command.from_form_filters_command', Filters_Command) has_filter_search_text = not (form.search.data == '' or form.search.data is None) has_filter_command_category = not (has_filter_search_text or form.id_command_category.data == '0' or form.id_command_category.data == '' or form.id_command_category.data is None) active_only = av.input_bool(form.active_only.data, "active", "Parameters_Command.from_form_filters_command") - filters = cls.get_default() + filters = cls.get_default(id_user_session) filters.get_all_command_category = not has_filter_command_category filters.get_inactive_command_category = not active_only filters.ids_command_category = form.id_command_category.data if has_filter_command_category else '' @@ -256,11 +271,11 @@ class Parameters_Command(Get_Many_Parameters_Base): return filters @classmethod - def from_form_filters_command_category(cls, form): + def from_form_filters_command_category(cls, form, id_user_session): av.val_instance(form, 'form', 'Parameters_Command.from_form_filters_command_category', Filters_Command_Category) has_filter_search_text = not (form.search.data == '' or form.search.data is None) active_only = av.input_bool(form.active_only.data, "active", "Parameters_Command.from_form_filters_command") - filters = cls.get_default() + filters = cls.get_default(id_user_session) filters.get_all_command_category = True filters.get_inactive_command_category = not active_only filters.ids_command_category = '' @@ -285,6 +300,11 @@ class Parameters_Command(Get_Many_Parameters_Base): , 'a_names_command': self.names_command , 'a_hand_signal_default_descriptions_command': self.hand_signal_default_descriptions_command , 'a_notes_command': self.notes_command + , 'a_get_all_user': self.get_all_user + , 'a_get_inactive_user': self.get_inactive_user + , 'a_ids_user': self.ids_user + , 'a_names_user': self.names_user + , 'a_emails_user': self.emails_user , 'a_require_all_id_search_filters_met': self.require_all_id_search_filters_met , 'a_require_any_id_search_filters_met': self.require_any_id_search_filters_met , 'a_require_all_non_id_search_filters_met': self.require_all_non_id_search_filters_met diff --git a/business_objects/dog/distraction_intensity_level.py b/business_objects/dog/distraction_intensity_level.py index c619094..c282c74 100644 --- a/business_objects/dog/distraction_intensity_level.py +++ b/business_objects/dog/distraction_intensity_level.py @@ -158,18 +158,28 @@ class Parameters_Distraction_Intensity_Level(Get_Many_Parameters_Base): get_inactive_distraction_intensity_level: bool ids_distraction_intensity_level: str names_distraction_intensity_level: str + get_all_user: bool + get_inactive_user: bool + ids_user: str + names_user: str + emails_user: str require_all_id_search_filters_met: bool require_any_id_search_filters_met: bool require_all_non_id_search_filters_met: bool require_any_non_id_search_filters_met: bool @classmethod - def get_default(cls): + def get_default(cls, id_user_session): return cls( get_all_distraction_intensity_level = True , get_inactive_distraction_intensity_level = False , ids_distraction_intensity_level = '' , names_distraction_intensity_level = '' + , get_all_user = False + , get_inactive_user = False + , ids_user = str(id_user_session) + , names_user = '' + , emails_user = '' , require_all_id_search_filters_met = True , require_any_id_search_filters_met = True , require_all_non_id_search_filters_met = False @@ -183,6 +193,11 @@ class Parameters_Distraction_Intensity_Level(Get_Many_Parameters_Base): , get_inactive_distraction_intensity_level = json.get('a_get_inactive_distraction_intensity_level', False) , ids_distraction_intensity_level = json.get('a_ids_distraction_intensity_level', '') , names_distraction_intensity_level = json.get('a_names_distraction_intensity_level', '') + , get_all_user = json.get('a_get_all_user', False) + , get_inactive_user = json.get('a_get_inactive_user', False) + , ids_user = json.get('a_ids_user', '') + , names_user = json.get('a_names_user', '') + , emails_user = json.get('a_emails_user', '') , require_all_id_search_filters_met = json.get('a_require_all_id_search_filters_met', True) , require_any_id_search_filters_met = json.get('a_require_any_id_search_filters_met', True) , require_all_non_id_search_filters_met = json.get('a_require_all_non_id_search_filters_met', False) @@ -210,6 +225,11 @@ class Parameters_Distraction_Intensity_Level(Get_Many_Parameters_Base): , 'a_get_inactive_distraction_intensity_level': self.get_inactive_distraction_intensity_level , 'a_ids_distraction_intensity_level': self.ids_distraction_intensity_level , 'a_names_distraction_intensity_level': self.names_distraction_intensity_level + , 'a_get_all_user': self.get_all_user + , 'a_get_inactive_user': self.get_inactive_user + , 'a_ids_user': self.ids_user + , 'a_names_user': self.names_user + , 'a_emails_user': self.emails_user , 'a_require_all_id_search_filters_met': self.require_all_id_search_filters_met , 'a_require_any_id_search_filters_met': self.require_any_id_search_filters_met , 'a_require_all_non_id_search_filters_met': self.require_all_non_id_search_filters_met diff --git a/business_objects/dog/distraction_type.py b/business_objects/dog/distraction_type.py index 6176a85..1736cdd 100644 --- a/business_objects/dog/distraction_type.py +++ b/business_objects/dog/distraction_type.py @@ -122,18 +122,28 @@ class Parameters_Distraction_Type(Get_Many_Parameters_Base): get_inactive_distraction_type: bool ids_distraction_type: str names_distraction_type: str + get_all_user: bool + get_inactive_user: bool + ids_user: str + names_user: str + emails_user: str require_all_id_search_filters_met: bool require_any_id_search_filters_met: bool require_all_non_id_search_filters_met: bool require_any_non_id_search_filters_met: bool @classmethod - def get_default(cls): + def get_default(cls, id_user_session): return cls( get_all_distraction_type = True , get_inactive_distraction_type = False , ids_distraction_type = '' , names_distraction_type = '' + , get_all_user = False + , get_inactive_user = False + , ids_user = str(id_user_session) + , names_user = '' + , emails_user = '' , require_all_id_search_filters_met = True , require_any_id_search_filters_met = True , require_all_non_id_search_filters_met = False @@ -147,6 +157,11 @@ class Parameters_Distraction_Type(Get_Many_Parameters_Base): , get_inactive_distraction_type = json.get('a_get_inactive_distraction_type', False) , ids_distraction_type = json.get('a_ids_distraction_type', '') , names_distraction_type = json.get('a_names_distraction_type', '') + , get_all_user = json.get('a_get_all_user', False) + , get_inactive_user = json.get('a_get_inactive_user', False) + , ids_user = json.get('a_ids_user', '') + , names_user = json.get('a_names_user', '') + , emails_user = json.get('a_emails_user', '') , require_all_id_search_filters_met = json.get('a_require_all_id_search_filters_met', True) , require_any_id_search_filters_met = json.get('a_require_any_id_search_filters_met', True) , require_all_non_id_search_filters_met = json.get('a_require_all_non_id_search_filters_met', False) @@ -174,6 +189,11 @@ class Parameters_Distraction_Type(Get_Many_Parameters_Base): , 'a_get_inactive_distraction_type': self.get_inactive_distraction_type , 'a_ids_distraction_type': self.ids_distraction_type , 'a_names_distraction_type': self.names_distraction_type + , 'a_get_all_user': self.get_all_user + , 'a_get_inactive_user': self.get_inactive_user + , 'a_ids_user': self.ids_user + , 'a_names_user': self.names_user + , 'a_emails_user': self.emails_user , 'a_require_all_id_search_filters_met': self.require_all_id_search_filters_met , 'a_require_any_id_search_filters_met': self.require_any_id_search_filters_met , 'a_require_all_non_id_search_filters_met': self.require_all_non_id_search_filters_met diff --git a/business_objects/dog/dog.py b/business_objects/dog/dog.py index b9e29c5..cf11355 100644 --- a/business_objects/dog/dog.py +++ b/business_objects/dog/dog.py @@ -145,18 +145,28 @@ class Parameters_Dog(Get_Many_Parameters_Base): get_inactive_dog: bool ids_dog: str names_dog: str + get_all_user: bool + get_inactive_user: bool + ids_user: str + names_user: str + emails_user: str require_all_id_search_filters_met: bool require_any_id_search_filters_met: bool require_all_non_id_search_filters_met: bool require_any_non_id_search_filters_met: bool @classmethod - def get_default(cls): + def get_default(cls, id_user_session): return cls( get_all_dog = True , get_inactive_dog = False , ids_dog = '' , names_dog = '' + , get_all_user = False + , get_inactive_user = False + , ids_user = str(id_user_session) + , names_user = '' + , emails_user = '' , require_all_id_search_filters_met = True , require_any_id_search_filters_met = True , require_all_non_id_search_filters_met = False @@ -170,6 +180,11 @@ class Parameters_Dog(Get_Many_Parameters_Base): , get_inactive_dog = json.get('a_get_inactive_dog', False) , ids_dog = json.get('a_ids_dog', '') , names_dog = json.get('names_dog', '') + , get_all_user = json.get('a_get_all_user', False) + , get_inactive_user = json.get('a_get_inactive_user', False) + , ids_user = json.get('a_ids_user', '') + , names_user = json.get('a_names_user', '') + , emails_user = json.get('a_emails_user', '') , require_all_id_search_filters_met = json.get('a_require_all_id_search_filters_met', True) , require_any_id_search_filters_met = json.get('a_require_any_id_search_filters_met', True) , require_all_non_id_search_filters_met = json.get('a_require_all_non_id_search_filters_met', False) @@ -177,12 +192,12 @@ class Parameters_Dog(Get_Many_Parameters_Base): ) @classmethod - def from_form_filters_dog(cls, form): + def from_form_filters_dog(cls, form, id_user_session): av.val_instance(form, 'form', 'Parameters_Dog.from_form_filters_dog', Filters_Dog) has_filter_search_text = not (form.search.data == '' or form.search.data is None) has_filter_dog = has_filter_search_text # has_filter_id or has_filter_name active_only = av.input_bool(form.active_only.data, "active_only", "Parameters_Dog.from_form_filters_dog") - filter_parameters = cls.get_default() + filter_parameters = cls.get_default(id_user_session) filter_parameters.get_all_dog = not has_filter_dog filter_parameters.get_inactive_dog = not active_only filter_parameters.ids_dog = '' # form.id_dog.data if has_filter_id else '' @@ -195,6 +210,11 @@ class Parameters_Dog(Get_Many_Parameters_Base): , 'a_get_inactive_dog': self.get_inactive_dog , 'a_ids_dog': self.ids_dog , 'a_names_dog': self.names_dog + , 'a_get_all_user': self.get_all_user + , 'a_get_inactive_user': self.get_inactive_user + , 'a_ids_user': self.ids_user + , 'a_names_user': self.names_user + , 'a_emails_user': self.emails_user , 'a_require_all_id_search_filters_met': self.require_all_id_search_filters_met , 'a_require_any_id_search_filters_met': self.require_any_id_search_filters_met , 'a_require_all_non_id_search_filters_met': self.require_all_non_id_search_filters_met diff --git a/business_objects/dog/image.py b/business_objects/dog/image.py index 9ef9bd6..1f78201 100644 --- a/business_objects/dog/image.py +++ b/business_objects/dog/image.py @@ -163,13 +163,18 @@ class Parameters_Image(Get_Many_Parameters_Base): get_inactive_image: bool ids_image: str names_image: str + get_all_user: bool + get_inactive_user: bool + ids_user: str + names_user: str + emails_user: str require_all_id_search_filters_met: bool require_any_id_search_filters_met: bool require_all_non_id_search_filters_met: bool require_any_non_id_search_filters_met: bool @classmethod - def get_default(cls): + def get_default(cls, id_user_session): return cls( get_all_file_type = True , get_inactive_file_type = False @@ -183,6 +188,11 @@ class Parameters_Image(Get_Many_Parameters_Base): , get_inactive_image = False , ids_image = '' , names_image = '' + , get_all_user = False + , get_inactive_user = False + , ids_user = str(id_user_session) + , names_user = '' + , emails_user = '' , require_all_id_search_filters_met = True , require_any_id_search_filters_met = True , require_all_non_id_search_filters_met = False @@ -204,6 +214,11 @@ class Parameters_Image(Get_Many_Parameters_Base): , get_inactive_image = json.get('a_get_inactive_image', False) , ids_image = json.get('a_ids_image', '') , names_image = json.get('a_names_image', '') + , get_all_user = json.get('a_get_all_user', False) + , get_inactive_user = json.get('a_get_inactive_user', False) + , ids_user = json.get('a_ids_user', '') + , names_user = json.get('a_names_user', '') + , emails_user = json.get('a_emails_user', '') , require_all_id_search_filters_met = json.get('a_require_all_id_search_filters_met', True) , require_any_id_search_filters_met = json.get('a_require_any_id_search_filters_met', True) , require_all_non_id_search_filters_met = json.get('a_require_all_non_id_search_filters_met', False) @@ -230,6 +245,11 @@ class Parameters_Image(Get_Many_Parameters_Base): , 'a_get_inactive_image': self.get_inactive_image , 'a_ids_image': self.ids_image , 'a_names_image': self.names_image + , 'a_get_all_user': self.get_all_user + , 'a_get_inactive_user': self.get_inactive_user + , 'a_ids_user': self.ids_user + , 'a_names_user': self.names_user + , 'a_emails_user': self.emails_user , 'a_require_all_id_search_filters_met': self.require_all_id_search_filters_met , 'a_require_any_id_search_filters_met': self.require_any_id_search_filters_met , 'a_require_all_non_id_search_filters_met': self.require_all_non_id_search_filters_met diff --git a/business_objects/dog/location.py b/business_objects/dog/location.py index db1951b..7919322 100644 --- a/business_objects/dog/location.py +++ b/business_objects/dog/location.py @@ -158,6 +158,11 @@ class Parameters_Location(Get_Many_Parameters_Base): get_inactive_location: bool ids_location: str names_location: str + get_all_user: bool + get_inactive_user: bool + ids_user: str + names_user: str + emails_user: str require_all_id_search_filters_met: bool require_any_id_search_filters_met: bool require_all_non_id_search_filters_met: bool @@ -165,12 +170,17 @@ class Parameters_Location(Get_Many_Parameters_Base): output_locations: bool @classmethod - def get_default(cls): + def get_default(cls, id_user_session): return cls( get_all_location = True , get_inactive_location = False , ids_location = '' , names_location = '' + , get_all_user = False + , get_inactive_user = False + , ids_user = str(id_user_session) + , names_user = '' + , emails_user = '' , require_all_id_search_filters_met = True , require_any_id_search_filters_met = True , require_all_non_id_search_filters_met = False @@ -185,6 +195,11 @@ class Parameters_Location(Get_Many_Parameters_Base): , get_inactive_location = json.get('a_get_inactive_location', False) , ids_location = json.get('a_ids_location', '') , names_location = json.get('a_names_location', '') + , get_all_user = json.get('a_get_all_user', False) + , get_inactive_user = json.get('a_get_inactive_user', False) + , ids_user = json.get('a_ids_user', '') + , names_user = json.get('a_names_user', '') + , emails_user = json.get('a_emails_user', '') , require_all_id_search_filters_met = json.get('a_require_all_id_search_filters_met', True) , require_any_id_search_filters_met = json.get('a_require_any_id_search_filters_met', True) , require_all_non_id_search_filters_met = json.get('a_require_all_non_id_search_filters_met', False) @@ -211,6 +226,11 @@ class Parameters_Location(Get_Many_Parameters_Base): , 'a_get_inactive_location': self.get_inactive_location , 'a_ids_location': self.ids_location , 'a_names_location': self.names_location + , 'a_get_all_user': self.get_all_user + , 'a_get_inactive_user': self.get_inactive_user + , 'a_ids_user': self.ids_user + , 'a_names_user': self.names_user + , 'a_emails_user': self.emails_user , 'a_require_all_id_search_filters_met': self.require_all_id_search_filters_met , 'a_require_any_id_search_filters_met': self.require_any_id_search_filters_met , 'a_require_all_non_id_search_filters_met': self.require_all_non_id_search_filters_met diff --git a/business_objects/dog/obedience_level.py b/business_objects/dog/obedience_level.py index 7bf216f..8c412b9 100644 --- a/business_objects/dog/obedience_level.py +++ b/business_objects/dog/obedience_level.py @@ -118,18 +118,28 @@ class Parameters_Obedience_Level(Get_Many_Parameters_Base): get_inactive_obedience_level: bool ids_obedience_level: str names_obedience_level: str + get_all_user: bool + get_inactive_user: bool + ids_user: str + names_user: str + emails_user: str require_all_id_search_filters_met: bool require_any_id_search_filters_met: bool require_all_non_id_search_filters_met: bool require_any_non_id_search_filters_met: bool @classmethod - def get_default(cls): + def get_default(cls, id_user_session): return cls( get_all_obedience_level = True , get_inactive_obedience_level = False , ids_obedience_level = '' , names_obedience_level = '' + , get_all_user = False + , get_inactive_user = False + , ids_user = str(id_user_session) + , names_user = '' + , emails_user = '' , require_all_id_search_filters_met = True , require_any_id_search_filters_met = True , require_all_non_id_search_filters_met = False @@ -143,6 +153,11 @@ class Parameters_Obedience_Level(Get_Many_Parameters_Base): , get_inactive_obedience_level = json.get('a_get_inactive_obedience_level', False) , ids_obedience_level = json.get('a_ids_obedience_level', '') , names_obedience_level = json.get('a_names_obedience_level', '') + , get_all_user = json.get('a_get_all_user', False) + , get_inactive_user = json.get('a_get_inactive_user', False) + , ids_user = json.get('a_ids_user', '') + , names_user = json.get('a_names_user', '') + , emails_user = json.get('a_emails_user', '') , require_all_id_search_filters_met = json.get('a_require_all_id_search_filters_met', True) , require_any_id_search_filters_met = json.get('a_require_any_id_search_filters_met', True) , require_all_non_id_search_filters_met = json.get('a_require_all_non_id_search_filters_met', False) @@ -170,6 +185,11 @@ class Parameters_Obedience_Level(Get_Many_Parameters_Base): , 'a_get_inactive_obedience_level': self.get_inactive_obedience_level , 'a_ids_obedience_level': self.ids_obedience_level , 'a_names_obedience_level': self.names_obedience_level + , 'a_get_all_user': self.get_all_user + , 'a_get_inactive_user': self.get_inactive_user + , 'a_ids_user': self.ids_user + , 'a_names_user': self.names_user + , 'a_emails_user': self.emails_user , 'a_require_all_id_search_filters_met': self.require_all_id_search_filters_met , 'a_require_any_id_search_filters_met': self.require_any_id_search_filters_met , 'a_require_all_non_id_search_filters_met': self.require_all_non_id_search_filters_met diff --git a/business_objects/dog/response_quality_metric.py b/business_objects/dog/response_quality_metric.py index 95412bc..b478148 100644 --- a/business_objects/dog/response_quality_metric.py +++ b/business_objects/dog/response_quality_metric.py @@ -144,18 +144,28 @@ class Parameters_Response_Quality_Metric(Get_Many_Parameters_Base): get_inactive_response_quality_metric: bool ids_response_quality_metric: str names_response_quality_metric: str + get_all_user: bool + get_inactive_user: bool + ids_user: str + names_user: str + emails_user: str require_all_id_search_filters_met: bool require_any_id_search_filters_met: bool require_all_non_id_search_filters_met: bool require_any_non_id_search_filters_met: bool @classmethod - def get_default(cls): + def get_default(cls, id_user_session): return cls( get_all_response_quality_metric = True , get_inactive_response_quality_metric = False , ids_response_quality_metric = '' , names_response_quality_metric = '' + , get_all_user = False + , get_inactive_user = False + , ids_user = str(id_user_session) + , names_user = '' + , emails_user = '' , require_all_id_search_filters_met = True , require_any_id_search_filters_met = True , require_all_non_id_search_filters_met = False @@ -169,6 +179,11 @@ class Parameters_Response_Quality_Metric(Get_Many_Parameters_Base): , get_inactive_response_quality_metric = json.get('a_get_inactive_response_quality_metric', False) , ids_response_quality_metric = json.get('a_ids_response_quality_metric', '') , names_response_quality_metric = json.get('a_names_response_quality_metric', '') + , get_all_user = json.get('a_get_all_user', False) + , get_inactive_user = json.get('a_get_inactive_user', False) + , ids_user = json.get('a_ids_user', '') + , names_user = json.get('a_names_user', '') + , emails_user = json.get('a_emails_user', '') , require_all_id_search_filters_met = json.get('a_require_all_id_search_filters_met', True) , require_any_id_search_filters_met = json.get('a_require_any_id_search_filters_met', True) , require_all_non_id_search_filters_met = json.get('a_require_all_non_id_search_filters_met', False) @@ -196,6 +211,11 @@ class Parameters_Response_Quality_Metric(Get_Many_Parameters_Base): , 'a_get_inactive_response_quality_metric': self.get_inactive_response_quality_metric , 'a_ids_response_quality_metric': self.ids_response_quality_metric , 'a_names_response_quality_metric': self.names_response_quality_metric + , 'a_get_all_user': self.get_all_user + , 'a_get_inactive_user': self.get_inactive_user + , 'a_ids_user': self.ids_user + , 'a_names_user': self.names_user + , 'a_emails_user': self.emails_user , 'a_require_all_id_search_filters_met': self.require_all_id_search_filters_met , 'a_require_any_id_search_filters_met': self.require_any_id_search_filters_met , 'a_require_all_non_id_search_filters_met': self.require_all_non_id_search_filters_met diff --git a/controllers/blog/blog.py b/controllers/blog/blog.py index ee13746..7a14818 100644 --- a/controllers/blog/blog.py +++ b/controllers/blog/blog.py @@ -59,6 +59,17 @@ def blog_article_how_to_scale_your_dog_training_business_from_solo_to_multi_trai return jsonify(error=str(e)), 403 return html_body +@routes_blog.route(Model_View_Blog_Home.HASH_PAGE_BLOG_ARTICLE_THE_HIDDEN_COSTS_OF_SPREADSHEET_DOG_TRAINING_WHY_UK_TRAINERS_ARE_LOSING_2000_PLUS_POUNDS_PER_YEAR, methods=['GET']) +def blog_article_the_hidden_costs_of_spreadsheet_dog_training_why_uk_trainers_are_losing_2000_plus_pounds_per_year(): + try: + form = Form_Newsletter() + model = Model_View_Blog_Home(form_newsletter = form, hash_page_current = Model_View_Blog_Home.HASH_PAGE_BLOG_ARTICLE_THE_SCIENCE_BEHIND_DOG_TRAINING_ASSESSMENTS_HOW_TRACK_REAL_PROGRESS) + model._title = 'Blog Article' + html_body = render_template('pages/blog/_article_the_hidden_costs_of_spreadsheet_dog_training_why_uk_trainers_are_losing_2000_plus_pounds_per_year.html', model = model) + except Exception as e: + return jsonify(error=str(e)), 403 + return html_body + @routes_blog.route(Model_View_Blog_Home.HASH_PAGE_BLOG_ARTICLE_THE_SCIENCE_BEHIND_DOG_TRAINING_ASSESSMENTS_HOW_TRACK_REAL_PROGRESS, methods=['GET']) def blog_article_the_science_behind_dog_training_assessments_how_to_track_real_progress(): try: diff --git a/models/model_view_base.py b/models/model_view_base.py index 99ed4c6..4102b63 100644 --- a/models/model_view_base.py +++ b/models/model_view_base.py @@ -277,6 +277,7 @@ class Model_View_Base(BaseModel, ABC): HASH_PAGE_APPLY_FOUNDING_PARTNER_SUCCESS: ClassVar[str] = '/apply-founding-partner-success'# HASH_PAGE_BLOG_ARTICLE_HOW_TO_SCALE_YOUR_DOG_TRAINING_BUSINESS_FROM_25_TO_100_PLUS_CLIENTS: ClassVar[str] = '/blog/article/how-to-scale-your-dog-training-business-from-25-to-100-plus-clients' HASH_PAGE_BLOG_ARTICLE_HOW_TO_SCALE_YOUR_DOG_TRAINING_BUSINESS_FROM_SOLO_TO_MULTI_TRAINER_SUCCESS: ClassVar[str] = '/blog/article/how-to-scale-your-dog-training-business-from-solo-to-multi-trainer-success' + HASH_PAGE_BLOG_ARTICLE_THE_HIDDEN_COSTS_OF_SPREADSHEET_DOG_TRAINING_WHY_UK_TRAINERS_ARE_LOSING_2000_PLUS_POUNDS_PER_YEAR: ClassVar[str] = '/blog/article/the-hidden-costs-of-spreadsheet-dog-training-why-uk-trainers-are-losing-2000-plus-pounds-per-year' HASH_PAGE_BLOG_ARTICLE_THE_SCIENCE_BEHIND_DOG_TRAINING_ASSESSMENTS_HOW_TRACK_REAL_PROGRESS: ClassVar[str] = '/blog/article/the-science-behind-dog-training-assessments-how-to-track-real-progress' HASH_PAGE_BLOG_ARTICLE_WHY_EVERY_PROFESSIONAL_TRAINER_NEEDS_A_COMMAND_DICTIONARY_IN_2025: ClassVar[str] = '/blog/article/why-every-professional-trainer-needs-a-command-dictionary-in-2025' HASH_PAGE_BLOG_CATEGORY_MARKETING_AND_GROWTH: ClassVar[str] = '/blog/category/marketing-and-growth' diff --git a/models/model_view_dog_assessment.py b/models/model_view_dog_assessment.py index d050fba..4dd5583 100644 --- a/models/model_view_dog_assessment.py +++ b/models/model_view_dog_assessment.py @@ -88,6 +88,8 @@ class Model_View_Dog_Assessment(Model_View_Dog_Base): self.form_filters = form_filters_old datastore_dog = DataStore_Dog() datastore_user = DataStore_User() + + user_session = datastore_dog.get_user_session() # Assessments + filters parameters_filter_lighting_level = Parameters_Lighting_Level.get_default() @@ -95,7 +97,7 @@ class Model_View_Dog_Assessment(Model_View_Dog_Base): if len(self.filter_lighting_levels) > 0: self.form_filters.id_lighting_level.choices += [(str(lighting_level.id_lighting_level), lighting_level.name) for lighting_level in self.filter_lighting_levels] - parameters_filter_location = Parameters_Location.get_default() + parameters_filter_location = Parameters_Location.get_default(user_session.id_user) self.filter_locations, errors = datastore_dog.get_many_location(parameters_filter_location) if len(self.filter_locations) > 0: self.form_filters.id_location.choices += [(str(location.id_location), location.name) for location in self.filter_locations] @@ -120,14 +122,14 @@ class Model_View_Dog_Assessment(Model_View_Dog_Base): self.assessments, errors = datastore_dog.get_many_assessment(parameters_filter_assessment) # Distractions + filters - parameters_filter_distraction_type = Parameters_Distraction_Type.get_default() + parameters_filter_distraction_type = Parameters_Distraction_Type.get_default(user_session.id_user) self.filter_distraction_types, errors = datastore_dog.get_many_distraction_type(parameters_filter_distraction_type) """ if len(self.filter_distraction_types) > 0: self.form_filters.id_distraction_type.choices += [(str(distraction_type.id_type), distraction_type.name) for distraction_type in self.filter_distraction_types] """ - parameters_filter_distraction_intensity_level = Parameters_Distraction_Intensity_Level.get_default() + parameters_filter_distraction_intensity_level = Parameters_Distraction_Intensity_Level.get_default(user_session.id_user) self.filter_distraction_intensity_levels, errors = datastore_dog.get_many_distraction_intensity_level(parameters_filter_distraction_intensity_level) """ if len(self.filter_distraction_intensity_levels) > 0: @@ -138,7 +140,7 @@ class Model_View_Dog_Assessment(Model_View_Dog_Base): distractions, errors = datastore_dog.get_many_distraction(parameters_filter_distraction) # Assessment Command Modality Links + filters - parameters_filter_command = Parameters_Command.get_default() + parameters_filter_command = Parameters_Command.get_default(user_session.id_user) self.filter_command_categories, self.filter_commands, errors = datastore_dog.get_many_command(parameters_filter_command) """ if len(self.filter_command_categories) > 0: @@ -169,14 +171,14 @@ class Model_View_Dog_Assessment(Model_View_Dog_Base): assessment_command_modality_links, errors = datastore_dog.get_many_assessment_command_modality_link(parameters_filter_assessment_command_modality_link) # Assessment Responses and filters - parameters_filter_response_quality_metric = Parameters_Response_Quality_Metric.get_default() + parameters_filter_response_quality_metric = Parameters_Response_Quality_Metric.get_default(user_session.id_user) self.filter_response_quality_metrics, errors = datastore_dog.get_many_response_quality_metric(parameters_filter_response_quality_metric) """ if len(self.filter_response_quality_metrics) > 0: self.form_filters.id_response_quality_metric.choices += [(str(response_quality_metric.id_response_quality_metric), response_quality_metric.name) for response_quality_metric in self.filter_response_quality_metrics] """ - parameters_filter_obedience_level = Parameters_Obedience_Level.get_default() + parameters_filter_obedience_level = Parameters_Obedience_Level.get_default(user_session.id_user) self.filter_obedience_levels, errors = datastore_dog.get_many_obedience_level(parameters_filter_obedience_level) """ if len(self.filter_obedience_levels) > 0: diff --git a/models/model_view_dog_command.py b/models/model_view_dog_command.py index a263b26..6b3d232 100644 --- a/models/model_view_dog_command.py +++ b/models/model_view_dog_command.py @@ -38,8 +38,10 @@ class Model_View_Dog_Command(Model_View_Dog_Base): self._title = 'Command' self.form_filters = form_filters_old datastore = DataStore_Dog() + + user_session = datastore.get_user_session() - parameters_filter_command = Parameters_Command.get_default() + parameters_filter_command = Parameters_Command.get_default(user_session.id_user) self.filter_command_categories, filter_commands, errors = datastore.get_many_command(parameters_filter_command) self.form_filters.id_command_category.choices += [(str(command_category.id_command_category), command_category.name) for command_category in self.filter_command_categories] diff --git a/models/model_view_dog_command_button_link.py b/models/model_view_dog_command_button_link.py index e00444b..9d04a80 100644 --- a/models/model_view_dog_command_button_link.py +++ b/models/model_view_dog_command_button_link.py @@ -49,8 +49,10 @@ class Model_View_Dog_Command_Button_Link(Model_View_Dog_Base): self._title = 'Command Button Link' self.form_filters = form_filters_old datastore = DataStore_Dog() + + user_session = datastore.get_user_session() - parameters_filter_command = Parameters_Command.get_default() + parameters_filter_command = Parameters_Command.get_default(user_session.id_user) self.filter_command_categories, self.filter_commands, errors = datastore.get_many_command(parameters_filter_command) if len(self.filter_command_categories) > 0: self.form_filters.id_command_category.choices += [(str(command_category.id_command_category), command_category.name) for command_category in self.filter_command_categories] @@ -61,7 +63,7 @@ class Model_View_Dog_Command_Button_Link(Model_View_Dog_Base): Helper_App.console_log(f'sorted filter commands: {sorted_filter_commands}') self.form_filters.id_command.choices += [(str(command.id_command), command.name) for command in sorted_filter_commands] # .sort(key = lambda command: command[1]) - parameters_filter_button_shape = Parameters_Button_Shape.get_default() + parameters_filter_button_shape = Parameters_Button_Shape.get_default(user_session.id_user) self.filter_button_shapes, errors = datastore.get_many_button_shape(parameters_filter_button_shape) if len(self.filter_button_shapes) > 0: self.form_filters.id_button_shape.choices += [(str(button_shape.id_button_shape), button_shape.name) for button_shape in self.filter_button_shapes] @@ -76,7 +78,7 @@ class Model_View_Dog_Command_Button_Link(Model_View_Dog_Base): if len(self.filter_button_icons) > 0: self.form_filters.id_button_icon.choices += [(str(button_icon.id_button_icon), button_icon.name) for button_icon in self.filter_button_icons] - parameters_filter_location = Parameters_Location.get_default() + parameters_filter_location = Parameters_Location.get_default(user_session.id_user) self.filter_locations, errors = datastore.get_many_location(parameters_filter_location) if len(self.filter_locations) > 0: self.form_filters.id_location.choices += [(str(location.id_location), location.name) for location in self.filter_locations] diff --git a/models/model_view_dog_dog_command_link.py b/models/model_view_dog_dog_command_link.py index 4251807..6371266 100644 --- a/models/model_view_dog_dog_command_link.py +++ b/models/model_view_dog_dog_command_link.py @@ -43,12 +43,13 @@ class Model_View_Dog_Dog_Command_Link(Model_View_Dog_Base): self._title = 'Dog Command Link' self.form_filters = form_filters_old datastore = DataStore_Dog() - parameters_filter_dog = Parameters_Dog.get_default() + user_session = datastore.get_user_session() + parameters_filter_dog = Parameters_Dog.get_default(user_session.id_user) self.filter_dogs, errors = datastore.get_many_dog(parameters_filter_dog) if len(self.filter_dogs) > 0: self.form_filters.id_dog.choices += [(str(dog.id_dog), dog.name) for dog in self.filter_dogs] - parameters_filter_command = Parameters_Command.get_default() + parameters_filter_command = Parameters_Command.get_default(user_session.id_user) self.filter_command_categories, self.filter_commands, errors = datastore.get_many_command(parameters_filter_command) if len(self.filter_command_categories) > 0: self.form_filters.id_command_category.choices += [(str(command_category.id_command_category), command_category.name) for command_category in self.filter_command_categories] diff --git a/static/MySQL/00000_combined.sql b/static/MySQL/00000_combined.sql index bc6fb18..85588fe 100644 --- a/static/MySQL/00000_combined.sql +++ b/static/MySQL/00000_combined.sql @@ -1,16 +1,15 @@ USE demo; -DROP PROCEDURE IF EXISTS demo.p_dog_calc_dog; +DROP PROCEDURE IF EXISTS demo.p_dog_get_many_obedience_level; DELIMITER // -CREATE PROCEDURE demo.p_dog_calc_dog ( - IN a_guid BINARY(36) - , IN a_id_user INT - , IN a_get_all_dog BIT - , IN a_get_inactive_dog BIT - , IN a_ids_dog TEXT - , IN a_names_dog TEXT +CREATE PROCEDURE demo.p_dog_get_many_obedience_level ( + IN a_id_user INT + , IN a_get_all_obedience_level BIT + , IN a_get_inactive_obedience_level BIT + , IN a_ids_obedience_level TEXT + , IN a_names_obedience_level TEXT , IN a_get_all_user BIT , IN a_get_inactive_user BIT , IN a_ids_user TEXT @@ -20,23 +19,16 @@ CREATE PROCEDURE demo.p_dog_calc_dog ( , IN a_require_any_id_search_filters_met BIT , IN a_require_all_non_id_search_filters_met BIT , IN a_require_any_non_id_search_filters_met BIT - , IN a_show_errors BIT , IN a_debug BIT ) BEGIN DECLARE v_can_view BIT; DECLARE v_code_type_error_bad_data VARCHAR(100); DECLARE v_code_type_error_no_permission VARCHAR(100); - DECLARE v_has_filter_dog_id BIT; - DECLARE v_has_filter_dog_name BIT; + DECLARE v_guid BINARY(36); DECLARE v_id_access_level_view INT; - DECLARE v_id_minimum INT; - DECLARE v_id_permission_dog_view INT; DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; - DECLARE v_is_super_user BIT; - DECLARE v_priority_access_level_none INT; - DECLARE v_priority_access_level_view INT; DECLARE v_time_start TIMESTAMP(6); DECLARE exit handler for SQLEXCEPTION @@ -49,14 +41,14 @@ BEGIN ROLLBACK; - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error_Calc_Dog ( + CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error ( id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT , id_type INT , code VARCHAR(250) NOT NULL , msg TEXT NOT NULL ); - INSERT INTO tmp_Msg_Error_Calc_Dog ( + INSERT INTO tmp_Msg_Error ( id_type , code , msg @@ -79,706 +71,204 @@ BEGIN , ERROR_TYPE.background_colour , ERROR_TYPE.text_colour , t_ERROR.msg - FROM tmp_Msg_Error_Calc_Dog t_ERROR + FROM tmp_Msg_Error t_ERROR INNER JOIN demo.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type ; - DROP TABLE IF EXISTS tmp_Msg_Error_Calc_Dog; + DROP TABLE IF EXISTS tmp_Msg_Error; END; SET v_time_start := CURRENT_TIMESTAMP(6); + SET v_guid := UUID(); SET v_code_type_error_bad_data := 'BAD_DATA'; SET v_code_type_error_no_permission := 'NO_PERMISSION'; SET v_id_type_error_bad_data := (SELECT ERROR_TYPE.id_type FROM demo.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_bad_data LIMIT 1); SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM demo.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); - SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM demo.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM demo.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1); - SET v_priority_access_level_none := (SELECT ACCESS_LEVEL.priority FROM demo.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'NONE' LIMIT 1); - SET v_priority_access_level_view := (SELECT ACCESS_LEVEL.priority FROM demo.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.id_access_level = v_id_access_level_view); - - CALL demo.p_core_validate_guid ( a_guid ); - + SET a_id_user := IFNULL(a_id_user, 0); - SET a_get_all_dog := IFNULL(a_get_all_dog, 0); - SET a_get_inactive_dog := IFNULL(a_get_inactive_dog, 0); - SET a_ids_dog := TRIM(IFNULL(a_ids_dog, '')); - SET a_names_dog := TRIM(IFNULL(a_names_dog, '')); - -- USER filters handled by p_dog_calc_user_access + /* + SET a_get_all_obedience_level := IFNULL(a_get_all_obedience_level, 0); + SET a_get_inactive_obedience_level := IFNULL(a_get_inactive_obedience_level, 0); + SET a_ids_obedience_level := TRIM(IFNULL(a_ids_obedience_level, '')); + SET a_names_obedience_level := TRIM(IFNULL(a_names_obedience_level, '')); SET a_require_all_id_search_filters_met := IFNULL(a_require_all_id_search_filters_met, 1); SET a_require_any_id_search_filters_met := IFNULL(a_require_any_id_search_filters_met, 1); SET a_require_all_non_id_search_filters_met := IFNULL(a_require_all_non_id_search_filters_met, 0); SET a_require_any_non_id_search_filters_met := IFNULL(a_require_any_non_id_search_filters_met, 1); - SET a_show_errors := IFNULL(a_show_errors, 0); + */ SET a_debug := IFNULL(a_debug, 0); IF a_debug = 1 THEN SELECT - a_guid - , a_id_user - , a_get_all_dog - , a_get_inactive_dog - , a_ids_dog - , a_names_dog - , a_get_all_user - , a_get_inactive_user - , a_ids_user - , a_names_user - , a_emails_user + a_id_user + , a_get_all_obedience_level + , a_get_inactive_obedience_level + , a_ids_obedience_level + , a_names_obedience_level , a_require_all_id_search_filters_met , a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met , a_require_any_non_id_search_filters_met - , a_show_errors , a_debug ; SELECT v_id_type_error_bad_data , v_id_type_error_no_permission - , v_id_permission_dog_view + , v_guid , v_time_start ; END IF; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name_Calc_Dog; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_Dog; - DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_Dog; - DROP TEMPORARY TABLE IF EXISTS tmp_Dog_Calc_Dog; - DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_Dog; + DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; + DROP TEMPORARY TABLE IF EXISTS tmp_Obedience_Level; - CREATE TEMPORARY TABLE tmp_Calc_User_Access_Calc_Dog ( - id_temp INT PRIMARY KEY AUTO_INCREMENT NOT NULL - , id_user INT - , id_role INT - , id_permission_required INT NOT NULL - , priority_access_level_required INT NOT NULL - , is_super_user BIT - , priority_access_level_user INT - , has_access BIT - , can_view BIT - , can_edit BIT - , can_admin BIT + CREATE TEMPORARY TABLE tmp_Obedience_Level ( + id_obedience_level INT NOT NULL + , code VARCHAR(250) + , name VARCHAR(250) , active BIT , does_meet_id_filters BIT , does_meet_non_id_filters BIT - ); - - CREATE TEMPORARY TABLE tmp_Dog_Calc_Dog ( - id_dog INT NOT NULL - , exists_valid_link BIT NOT NULL - , id_user INT - , does_meet_id_filters BIT NOT NULL - , does_meet_non_id_filters BIT NOT NULL ); - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error_Calc_Dog ( + CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error ( id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT , id_type INT , code VARCHAR(250) NOT NULL , msg TEXT NOT NULL - ); - - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Id_Calc_Dog ( - substring VARCHAR(4000) NOT NULL - , as_int INT - ); - DELETE FROM tmp_Split_Id_Calc_Dog; - - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Name_Calc_Dog ( - substring VARCHAR(4000) NOT NULL - , as_int INT - ); - DELETE FROM tmp_Split_Name_Calc_Dog; - - SET v_has_filter_dog_id = CASE WHEN a_ids_dog <> '' THEN 1 ELSE 0 END; - SET v_has_filter_dog_name = CASE WHEN a_names_dog <> '' THEN 1 ELSE 0 END; - - - - -- Permissions - IF a_debug = 1 THEN - SELECT - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ; - END IF; - - CALL demo.p_dog_calc_user_access( - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug ); - - SELECT - IFNULL(CALC_USER_T.has_access, 0) - , IFNULL(CALC_USER_T.is_super_user, 0) - INTO - v_can_view - , v_is_super_user - FROM demo.DOG_Calc_User_Access_Temp CALC_USER_T - WHERE CALC_USER_T.guid = a_guid - LIMIT 1 - ; - IF a_debug = 1 THEN - SELECT - v_can_view - , v_is_super_user - ; - END IF; - IF (v_can_view = 0) THEN - DELETE t_ME - FROM tmp_Msg_Error_Calc_Dog t_ME - WHERE t_ME.id_type <> v_id_type_error_no_permission - ; - INSERT INTO tmp_Msg_Error_Calc_Dog ( - id_type - , code - , msg - ) - VALUES ( - v_id_type_error_no_permission - , v_code_type_error_no_permission - , 'You do not have permission to view Dog.' - ) - ; - END IF; - - CALL demo.p_dog_clear_calc_user_access( - a_guid - , 0 -- a_debug - ); - - -- Users - IF a_debug = 1 THEN - SELECT - a_guid -- guid - , a_get_all_user -- get_all_user - , a_get_inactive_user -- get_inactive_user - , a_ids_user -- ids_user - , '' -- a_auth0_ids_user - , a_names_user -- a_names_user - , a_emails_user -- a_emails_user + -- Call Obedience_Level Calc + IF NOT EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN demo.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN + IF a_debug = 1 THEN + SELECT + v_guid -- a_guid + , a_id_user -- a_id_user + , a_get_all_obedience_level -- a_get_all_obedience_level + , a_get_inactive_obedience_level -- a_get_inactive_obedience_level + , a_ids_obedience_level -- a_ids_obedience_level + , a_names_obedience_level -- a_names_obedience_level + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user + , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met + , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met + , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met + , a_require_any_non_id_search_filters_met -- a_require_any_non_id_search_filters_met + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL demo.p_dog_calc_obedience_level ( + v_guid -- a_guid + , a_id_user -- a_id_user + , a_get_all_obedience_level -- a_get_all_obedience_level + , a_get_inactive_obedience_level -- a_get_inactive_obedience_level + , a_ids_obedience_level -- a_ids_obedience_level + , a_names_obedience_level -- a_names_obedience_level + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met - , 0 -- a_require_any_id_search_filters_met + , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level + , a_require_any_non_id_search_filters_met -- a_require_any_non_id_search_filters_met , 0 -- a_show_errors - , 0 -- a_debug - ; - END IF; - - CALL demo.p_dog_calc_user_access( - a_guid-- guid - , a_get_all_user -- get_all_user - , a_get_inactive_user -- get_inactive_user - , a_ids_user -- ids_user - , '' -- a_auth0_ids_user - , a_names_user -- a_names_user - , a_emails_user -- a_emails_user - , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met - , 0 -- a_require_any_id_search_filters_met - , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ); - - INSERT INTO tmp_Calc_User_Access_Calc_Dog ( - id_user - , id_role - , id_permission_required - , priority_access_level_required - , is_super_user - , priority_access_level_user - , has_access - , can_view - , can_edit - , can_admin - , active - , does_meet_id_filters - , does_meet_non_id_filters - ) - SELECT - CALC_USER_T.id_user - , CALC_USER_T.id_role - , CALC_USER_T.id_permission_required - , CALC_USER_T.priority_access_level_required - , CALC_USER_T.is_super_user - , CALC_USER_T.priority_access_level_user - , CALC_USER_T.has_access - , CALC_USER_T.can_view - , CALC_USER_T.can_edit - , CALC_USER_T.can_admin - , CALC_USER_T.active - , CALC_USER_T.does_meet_id_filters - , CALC_USER_T.does_meet_non_id_filters - FROM demo.DOG_Calc_User_Access_Temp CALC_USER_T - WHERE CALC_USER_T.GUID = a_guid - ; - - IF a_debug = 1 THEN - SELECT 'After get many user'; - SELECT * FROM tmp_Calc_User_Access_Calc_Dog; - SELECT COUNT(*) AS Count_Errors FROM tmp_Msg_Error_Calc_Dog t_ERROR; - SELECT * FROM tmp_Msg_Error_Calc_Dog t_ERROR; - END IF; - - CALL demo.p_dog_clear_calc_user_access( - a_guid - , 0 -- a_debug - ); - - - -- Dogs - IF v_has_filter_dog_id = 1 THEN - CALL demo.p_core_split(a_guid, a_ids_dog, ',', a_debug); - - SET sql_mode = ''; - + , 0 -- a_debug + ); + IF a_debug = 1 THEN - SELECT * - FROM demo.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = a_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; - SELECT COUNT(*) AS count_split_ids - FROM demo.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = a_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; + SELECT COUNT(*) FROM demo.DOG_Obedience_Level_Temp; + SELECT * FROM demo.DOG_Obedience_Level_Temp; END IF; - - INSERT INTO tmp_Split_Id_Calc_Dog ( - substring - , as_int - ) - SELECT - SPLIT_T.substring - , CAST(SPLIT_T.substring AS DECIMAL(10,0)) AS as_int - FROM demo.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = a_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; - - CALL demo.p_core_clear_split( a_guid ); - END IF; + + INSERT INTO tmp_Obedience_Level ( + id_obedience_level + , code + , name + , active - IF v_has_filter_dog_name = 1 THEN - CALL demo.p_core_split(a_guid, a_names_dog, ',', a_debug); - - SET sql_mode = ''; + , does_meet_id_filters + , does_meet_non_id_filters + ) + SELECT + OBEDIENCE_LEVEL_T.id_obedience_level + , OBEDIENCE_LEVEL_T.code + , OBEDIENCE_LEVEL_T.name + , OBEDIENCE_LEVEL_T.active + , OBEDIENCE_LEVEL_T.does_meet_id_filters + , OBEDIENCE_LEVEL_T.does_meet_non_id_filters + FROM demo.DOG_Obedience_Level_Temp OBEDIENCE_LEVEL_T + WHERE OBEDIENCE_LEVEL_T.GUID = v_guid + ; + IF a_debug = 1 THEN - SELECT * - FROM demo.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = a_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; - SELECT COUNT(*) AS count_split_names - FROM demo.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = a_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; + SELECT COUNT(*) FROM tmp_Obedience_Level; + SELECT * FROM tmp_Obedience_Level; END IF; - - INSERT INTO tmp_Split_Name_Calc_Dog ( - substring - , as_int - ) - SELECT - SPLIT_T.substring - , CAST(SPLIT_T.substring AS DECIMAL(10,0)) AS as_int - FROM demo.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = a_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; - - CALL demo.p_core_clear_split( a_guid ); - END IF; - - IF a_debug = 1 THEN - SELECT * - FROM tmp_Split_Id_Calc_Dog - ; - SELECT * - FROM tmp_Split_Name_Calc_Dog - ; END IF; - IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Dog t_ERROR INNER JOIN demo.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN - IF EXISTS ( - SELECT * - FROM tmp_Split_Id_Calc_Dog t_SPLIT_ID - LEFT JOIN demo.DOG_Dog DOG ON t_SPLIT_ID.as_int = DOG.id_dog - WHERE - ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(DOG.id_dog) - OR ( - DOG.active = 0 - AND a_get_inactive_dog = 0 - ) - ) THEN - INSERT INTO tmp_Msg_Error_Calc_Dog ( - id_type - , code - , msg - ) - SELECT - v_id_type_error_bad_data - , v_code_type_error_bad_data - , CONCAT('Invalid or inactive Dog IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT_ID.substring SEPARATOR ', '), 'NULL')) - FROM tmp_Split_Id_Calc_Dog t_SPLIT_ID - LEFT JOIN demo.DOG_Dog DOG ON t_SPLIT_ID.as_int = DOG.id_dog - WHERE - ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(DOG.id_dog) - OR ( - DOG.active = 0 - AND a_get_inactive_dog = 0 - ) - ; - /* Don't error on names not found - ELSEIF EXISTS () - */ - ELSE - INSERT INTO tmp_Dog_Calc_Dog ( - id_dog - , exists_valid_link - , id_user - , does_meet_id_filters - , does_meet_non_id_filters - ) - WITH - Dog_Id_Filter AS ( - SELECT DOG.id_dog - FROM tmp_Split_Id_Calc_Dog t_SPLIT_ID - INNER JOIN demo.DOG_Dog DOG ON t_SPLIT_ID.as_int = DOG.id_dog - ) - , Dog_Name_Filter AS ( - SELECT DOG.id_dog - FROM tmp_Split_Name_Calc_Dog t_SPLIT_NAME - INNER JOIN demo.DOG_Dog DOG ON DOG.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') - WHERE IFNULL(t_SPLIT_NAME.substring, '') <> '' - ) - , Dog_Filters AS ( - SELECT - DOG_COMBINED.id_dog - , MAX(DOG_COMBINED.does_meet_id_filter) AS does_meet_id_filter - , MAX(DOG_COMBINED.does_meet_name_filter) AS does_meet_name_filter - FROM ( - SELECT - DOG_ID_FILTER.id_dog - , 1 AS does_meet_id_filter - , 0 AS does_meet_name_filter - FROM Dog_Id_Filter DOG_ID_FILTER - UNION - SELECT - DOG_NAME_FILTER.id_dog - , 0 AS does_meet_id_filter - , 1 AS does_meet_name_filter - FROM Dog_Name_Filter DOG_NAME_FILTER - ) DOG_COMBINED - GROUP BY DOG_COMBINED.id_dog - ) - , Dog_Access AS ( - SELECT - DOG.id_dog - , CASE WHEN - v_is_super_user = 1 - OR ( - t_USER.id_user IS NOT NULL - AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view - ) - THEN 1 ELSE 0 END AS exists_valid_link - , ROW_NUMBER() OVER ( - PARTITION BY DOG.id_dog - ORDER BY - CASE WHEN - v_is_super_user = 1 - OR ( - t_USER.id_user IS NOT NULL - AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view - ) - THEN 1 ELSE 0 END DESC - , t_USER.does_meet_id_filters DESC - , t_USER.does_meet_non_id_filters DESC - ) AS index_link_in_dog - , t_USER.id_user - FROM demo.DOG_Dog DOG - LEFT JOIN demo.DOG_Dog_User_Link DOG_USER_LINK - ON DOG.id_dog = DOG_USER_LINK.id_dog - AND ( - ( - a_get_inactive_dog = 1 - AND a_get_inactive_user = 1 - ) - OR DOG_USER_LINK.active = 1 - ) - LEFT JOIN tmp_Calc_User_Access_Calc_Dog t_USER - ON DOG_USER_LINK.id_user = t_USER.id_user - AND ( - a_get_inactive_user = 1 - OR t_USER.active = 1 - ) - LEFT JOIN demo.DOG_Access_Level ACCESS_LEVEL - ON DOG_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level - AND ACCESS_LEVEL.active = 1 - ) - SELECT - DOG.id_dog - , IFNULL(DOG_ACCESS.exists_valid_link, 0) AS exists_valid_link - , DOG_ACCESS.id_user - , CASE WHEN - v_has_filter_dog_id = 0 - OR IFNULL(DOG_FILTERS.does_meet_id_filter, 0) = 1 - THEN 1 ELSE 0 END AS does_meet_id_filters - , CASE WHEN - ( - v_has_filter_dog_name = 0 - ) - OR IFNULL(DOG_FILTERS.does_meet_name_filter, 0) = 1 - THEN 1 ELSE 0 END AS does_meet_non_id_filters - FROM demo.DOG_Dog DOG - LEFT JOIN Dog_Filters DOG_FILTERS ON DOG.id_dog = DOG_FILTERS.id_dog - LEFT JOIN Dog_Access DOG_ACCESS - ON DOG.id_dog = DOG_ACCESS.id_dog - AND DOG_ACCESS.index_link_in_dog = 1 - WHERE - ( - a_get_all_dog = 1 - OR ( - v_has_filter_dog_id = 1 - AND DOG_FILTERS.does_meet_id_filter = 1 - ) - OR ( - v_has_filter_dog_name = 1 - AND DOG_FILTERS.does_meet_name_filter = 1 - ) - ) - AND IFNULL(DOG_ACCESS.exists_valid_link, 0) = 1 - AND ( - a_get_inactive_dog = 1 - OR DOG.active = 1 - ) - ; - END IF; - END IF; - - DELETE FROM tmp_Split_Id_Calc_Dog; - DELETE FROM tmp_Split_Name_Calc_Dog; - - IF a_debug = 1 THEN - SELECT 'After get all dogs'; - SELECT * FROM tmp_Dog_Calc_Dog; - END IF; - - -- Filter records - IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Dog t_ERROR INNER JOIN demo.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN - /* - WITH - Dog_Access AS ( - SELECT - DOG.id_dog - , CASE WHEN - v_is_super_user = 1 - OR ( - t_USER.id_user IS NOT NULL - AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view - ) - THEN 1 ELSE 0 END AS can_user_access_dog - , ROW_NUMBER() OVER ( - PARTITION BY DOG.id_dog - ORDER BY CASE WHEN - v_is_super_user = 1 - OR ( - t_USER.id_user IS NOT NULL - AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view - ) - THEN 1 ELSE 0 END DESC - ) AS index_link_in_dog - , t_USER.does_meet_id_filters AS does_user_meet_id_filters - , t_USER.does_meet_non_id_filters AS does_user_meet_non_id_filters - FROM demo.DOG_Dog DOG - LEFT JOIN demo.DOG_Dog_User_Link DOG_USER_LINK - ON DOG.id_dog = DOG_USER_LINK.id_dog - AND ( - ( - a_get_inactive_dog = 1 - AND a_get_inactive_user = 1 - ) - OR DOG_USER_LINK.active = 1 - ) - LEFT JOIN tmp_Calc_User_Access_Calc_Dog t_USER - ON DOG_USER_LINK.id_user = t_USER.id_user - AND ( - a_get_inactive_user = 1 - OR t_USER.active = 1 - ) - LEFT JOIN demo.DOG_Access_Level ACCESS_LEVEL - ON DOG_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level - AND ACCESS_LEVEL.active = 1 - ) - */ - DELETE t_DOG - FROM tmp_Dog_Calc_Dog t_DOG - /* - LEFT JOIN Dog_Access DOG_ACCESS - ON t_DOG.id_dog = DOG_ACCESS.id_dog - AND DOG_ACCESS.index_link_in_dog = 1 - */ - -- LEFT JOIN demo.DOG_Dog_User_Link DOG_USER_LINK ON t_DOG.id_dog = DOG_USER_LINK.id_dog - LEFT JOIN tmp_Calc_User_Access_Calc_Dog t_USER ON t_DOG.id_user = t_USER.id_user - WHERE - ( - a_require_all_id_search_filters_met = 1 - AND ( - t_DOG.does_meet_id_filters = 0 - OR ( - t_DOG.exists_valid_link = 0 - -- AND IFNULL(DOG_ACCESS.does_user_meet_id_filters, 0) = 0 - AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 - ) - ) - ) - OR ( - a_require_all_non_id_search_filters_met = 1 - AND ( - t_DOG.does_meet_non_id_filters = 0 - OR ( - t_DOG.exists_valid_link = 0 - -- AND IFNULL(DOG_ACCESS.does_user_meet_non_id_filters, 0) = 0 - AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 - ) - ) - ) - OR ( - a_require_any_id_search_filters_met = 1 - AND t_DOG.does_meet_id_filters = 0 - AND ( - t_DOG.exists_valid_link = 0 - -- AND IFNULL(DOG_ACCESS.does_user_meet_id_filters, 0) = 0 - AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 - ) - ) - OR ( - a_require_any_non_id_search_filters_met = 1 - AND t_DOG.does_meet_non_id_filters = 0 - AND ( - t_DOG.exists_valid_link = 0 - -- AND IFNULL(DOG_ACCESS.does_user_meet_non_id_filters, 0) = 0 - AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 - ) - ) - ; - END IF; - - IF a_debug = 1 THEN - SELECT 'After filter dogs'; - SELECT * FROM tmp_Dog_Calc_Dog; - END IF; - - - IF EXISTS(SELECT * FROM tmp_Msg_Error_Calc_Dog t_ERROR INNER JOIN demo.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN + -- Filter outputs + IF EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN demo.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN IF a_debug = 1 THEN - SELECT * FROM tmp_Dog_Calc_Dog; + SELECT * FROM tmp_Obedience_Level; END IF; - DELETE FROM tmp_Dog_Calc_Dog; + DELETE FROM tmp_Obedience_Level; END IF; + -- Outputs - -- Dogs - INSERT INTO demo.DOG_Dog_Temp ( - guid - , id_dog - , name - , appearance - , mass_kg - , notes - , active - - , does_meet_id_filters - , does_meet_non_id_filters - ) + -- Obedience_Levels SELECT - a_guid - , t_DOG.id_dog - , DOG.name - , DOG.appearance - , DOG.mass_kg - , DOG.notes - , DOG.active + t_OBEDIENCE_LEVELS.id_obedience_level + , t_OBEDIENCE_LEVELS.code + , t_OBEDIENCE_LEVELS.name + , t_OBEDIENCE_LEVELS.active - , t_DOG.does_meet_id_filters - , t_DOG.does_meet_non_id_filters - FROM demo.DOG_Dog DOG - INNER JOIN tmp_Dog_Calc_Dog t_DOG ON DOG.id_dog = t_DOG.id_dog + , t_OBEDIENCE_LEVELS.does_meet_id_filters + , t_OBEDIENCE_LEVELS.does_meet_non_id_filters + FROM tmp_Obedience_Level t_OBEDIENCE_LEVELS + LEFT JOIN demo.DOG_Obedience_Level OBEDIENCE_LEVELS ON t_OBEDIENCE_LEVELS.id_obedience_level = OBEDIENCE_LEVELS.id_obedience_level + ORDER BY t_OBEDIENCE_LEVELS.name + ; + + -- Errors + SELECT + t_ERROR.id_error + , t_ERROR.id_type + , t_ERROR.code + , ERROR_TYPE.name + , ERROR_TYPE.description + , ERROR_TYPE.is_breaking_error + , ERROR_TYPE.background_colour + , ERROR_TYPE.text_colour + , t_ERROR.msg + FROM tmp_Msg_Error t_ERROR + INNER JOIN demo.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type ; - -- Errors - IF a_show_errors = 1 THEN - SELECT - t_ERROR.id_error - , t_ERROR.id_type - , t_ERROR.code - , ERROR_TYPE.name - , ERROR_TYPE.description - , ERROR_TYPE.is_breaking_error - , ERROR_TYPE.background_colour - , ERROR_TYPE.text_colour - , t_ERROR.msg - FROM tmp_Msg_Error_Calc_Dog t_ERROR - INNER JOIN demo.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type - ; - END IF; - IF a_debug = 1 AND v_can_view = 1 THEN - SELECT * FROM tmp_Dog_Calc_Dog; + SELECT * FROM tmp_Obedience_Level; END IF; + + CALL demo.p_dog_clear_calc_obedience_level( + v_guid -- a_guid + , 0 -- a_debug + ); - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name_Calc_Dog; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_Dog; - DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_Dog; - DROP TEMPORARY TABLE IF EXISTS tmp_Dog_Calc_Dog; - DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_Dog; + DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; + DROP TEMPORARY TABLE IF EXISTS tmp_Obedience_Level; IF a_debug = 1 THEN CALL demo.p_core_debug_timing_reporting ( v_time_start ); @@ -789,14 +279,12 @@ DELIMITER ; /* - -CALL demo.p_dog_calc_dog ( - 'slips ' -- a_guid - , 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user - , 1 -- a_get_all_dog - , 0 -- a_get_inactive_dog - , '' -- a_ids_dog - , '' -- a_names_dog +CALL demo.p_dog_get_many_obedience_level ( + 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user + , 1 -- a_get_all_obedience_level + , 0 -- a_get_inactive_obedience_level + , '' -- a_ids_obedience_level + , '' -- a_names_obedience_level , 1 -- a_get_all_user , 0 -- a_get_inactive_user , '' -- a_ids_user @@ -806,38 +294,26 @@ CALL demo.p_dog_calc_dog ( , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met , 1 -- a_require_any_non_id_search_filters_met - , 1 -- a_show_errors , 1 -- a_debug ); -CALL demo.p_dog_calc_dog ( - 'slips ' -- a_guid - , 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user - , 1 -- a_get_all_dog - , 0 -- a_get_inactive_dog - , '' -- a_ids_dog - , 'pat' -- a_names_dog +CALL demo.p_dog_get_many_obedience_level ( + 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user + , 1 -- a_get_all_obedience_level + , 0 -- a_get_inactive_obedience_level + , '' -- a_ids_obedience_level + , 'pat,point' -- a_names_obedience_level , 1 -- a_get_all_user , 0 -- a_get_inactive_user , '' -- a_ids_user - , 'pat' -- a_names_user - , 'pat' -- a_emails_user + , 'pat,point' -- a_names_user + , 'pat,point' -- a_emails_user , 1 -- a_require_all_id_search_filters_met , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met , 1 -- a_require_any_non_id_search_filters_met - , 0 -- a_show_errors - , 0 -- a_debug -); - -SELECT * -FROM demo.DOG_Dog_Temp -; - -CALL demo.p_dog_clear_calc_dog ( - 'slips ' -- a_guid - , 1 -- debug + , 1 -- a_debug ); */ \ No newline at end of file diff --git a/static/MySQL/11319a_tbl_DOG_Distraction_Intensity_Level_User_Link.sql b/static/MySQL/11319a_tbl_DOG_Distraction_Intensity_Level_User_Link.sql index 0f3f271..5bcd44a 100644 --- a/static/MySQL/11319a_tbl_DOG_Distraction_Intensity_Level_User_Link.sql +++ b/static/MySQL/11319a_tbl_DOG_Distraction_Intensity_Level_User_Link.sql @@ -13,7 +13,7 @@ CREATE TABLE IF NOT EXISTS fetchmetrics.DOG_Distraction_Intensity_Level_User_Lin , id_intensity_level INT NOT NULL , CONSTRAINT FK_DOG_Distraction_Intensity_Level_User_Link_id_intensity_level FOREIGN KEY (id_intensity_level) - REFERENCES fetchmetrics.DOG_Distraction_Intensity_Level(id_type) + REFERENCES fetchmetrics.DOG_Distraction_Intensity_Level(id_intensity_level) , id_user INT NOT NULL , CONSTRAINT FK_DOG_Distraction_Intensity_Level_User_Link_id_user FOREIGN KEY (id_user) diff --git a/static/MySQL/11335a_tbl_DOG_Response_Quality_Metric_User_Link.sql b/static/MySQL/11335a_tbl_DOG_Response_Quality_Metric_User_Link.sql index a892089..7d867e1 100644 --- a/static/MySQL/11335a_tbl_DOG_Response_Quality_Metric_User_Link.sql +++ b/static/MySQL/11335a_tbl_DOG_Response_Quality_Metric_User_Link.sql @@ -11,7 +11,7 @@ WHERE CREATE TABLE IF NOT EXISTS fetchmetrics.DOG_Response_Quality_Metric_User_Link ( id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY , id_response_quality_metric INT NOT NULL - , CONSTRAINT FK_DOG_Response_Quality_Metric_User_Link_id_response_quality_metric + , CONSTRAINT FK_DOG_Response_Quality_Metric_User_Link_id_metric FOREIGN KEY (id_response_quality_metric) REFERENCES fetchmetrics.DOG_Response_Quality_Metric(id_metric) , id_user INT NOT NULL diff --git a/static/MySQL/11339a_tbl_DOG_Obedience_Level_User_Link.sql b/static/MySQL/11339a_tbl_DOG_Obedience_Level_User_Link.sql index 7fb7177..6aa203b 100644 --- a/static/MySQL/11339a_tbl_DOG_Obedience_Level_User_Link.sql +++ b/static/MySQL/11339a_tbl_DOG_Obedience_Level_User_Link.sql @@ -25,11 +25,11 @@ CREATE TABLE IF NOT EXISTS fetchmetrics.DOG_Obedience_Level_User_Link ( , active BIT NOT NULL DEFAULT 1 , created_on DATETIME , id_user_created_by INT - , CONSTRAINT FK_DOG_Dog_id_user_created_by + , CONSTRAINT FK_DOG_Obedience_Level_User_Link_id_user_created_by FOREIGN KEY (id_user_created_by) REFERENCES fetchmetrics.DOG_User(id_user) , id_change_set INT - , CONSTRAINT FK_DOG_Dog_id_change_set + , CONSTRAINT FK_DOG_Obedience_Level_User_Link_id_change_set FOREIGN KEY (id_change_set) REFERENCES fetchmetrics.DOG_Dog_Change_Set(id_change_set) ); diff --git a/static/MySQL/31223_tri_DOG_Button_Shape_User_Link.sql b/static/MySQL/31223_tri_DOG_Button_Shape_User_Link.sql index 1ec4e82..3e0ef05 100644 --- a/static/MySQL/31223_tri_DOG_Button_Shape_User_Link.sql +++ b/static/MySQL/31223_tri_DOG_Button_Shape_User_Link.sql @@ -30,7 +30,7 @@ BEGIN , value_new , id_change_set ) - -- Changed dog + -- Changed button shape SELECT NEW.id_link, 'id_button_shape', CONVERT(OLD.id_button_shape, CHAR), CONVERT(NEW.id_button_shape, CHAR), NEW.id_change_set WHERE NOT OLD.id_button_shape <=> NEW.id_button_shape UNION diff --git a/static/MySQL/31231_tri_DOG_Image_User_Link.sql b/static/MySQL/31231_tri_DOG_Image_User_Link.sql index 2b7d5c1..78c3a47 100644 --- a/static/MySQL/31231_tri_DOG_Image_User_Link.sql +++ b/static/MySQL/31231_tri_DOG_Image_User_Link.sql @@ -30,7 +30,7 @@ BEGIN , value_new , id_change_set ) - -- Changed dog + -- Changed image SELECT NEW.id_link, 'id_image', CONVERT(OLD.id_image, CHAR), CONVERT(NEW.id_image, CHAR), NEW.id_change_set WHERE NOT OLD.id_image <=> NEW.id_image UNION diff --git a/static/MySQL/31319_tri_DOG_Distraction_Intensity_Level_User_Link.sql b/static/MySQL/31319_tri_DOG_Distraction_Intensity_Level_User_Link.sql index 5a1e001..1521a51 100644 --- a/static/MySQL/31319_tri_DOG_Distraction_Intensity_Level_User_Link.sql +++ b/static/MySQL/31319_tri_DOG_Distraction_Intensity_Level_User_Link.sql @@ -30,7 +30,7 @@ BEGIN , value_new , id_change_set ) - -- Changed dog + -- Changed distraction intensity level SELECT NEW.id_link, 'id_intensity_level', CONVERT(OLD.id_intensity_level, CHAR), CONVERT(NEW.id_intensity_level, CHAR), NEW.id_change_set WHERE NOT OLD.id_intensity_level <=> NEW.id_intensity_level UNION diff --git a/static/MySQL/31339_tri_DOG_Obedience_Level_User_Link.sql b/static/MySQL/31339_tri_DOG_Obedience_Level_User_Link.sql index 3f65dad..66f2188 100644 --- a/static/MySQL/31339_tri_DOG_Obedience_Level_User_Link.sql +++ b/static/MySQL/31339_tri_DOG_Obedience_Level_User_Link.sql @@ -30,7 +30,7 @@ BEGIN , value_new , id_change_set ) - -- Changed dog + -- Changed obedience level SELECT NEW.id_link, 'id_obedience_level', CONVERT(OLD.id_obedience_level, CHAR), CONVERT(NEW.id_obedience_level, CHAR), NEW.id_change_set WHERE NOT OLD.id_obedience_level <=> NEW.id_obedience_level UNION diff --git a/static/MySQL/71001_p_dog_calc_dog.sql b/static/MySQL/71001_p_dog_calc_dog.sql index 73889a1..fbd88a9 100644 --- a/static/MySQL/71001_p_dog_calc_dog.sql +++ b/static/MySQL/71001_p_dog_calc_dog.sql @@ -673,7 +673,6 @@ BEGIN t_DOG.does_meet_id_filters = 0 OR ( t_DOG.exists_valid_link = 0 - -- AND IFNULL(DOG_ACCESS.does_user_meet_id_filters, 0) = 0 AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 ) ) @@ -684,7 +683,6 @@ BEGIN t_DOG.does_meet_non_id_filters = 0 OR ( t_DOG.exists_valid_link = 0 - -- AND IFNULL(DOG_ACCESS.does_user_meet_non_id_filters, 0) = 0 AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 ) ) @@ -694,7 +692,6 @@ BEGIN AND t_DOG.does_meet_id_filters = 0 AND ( t_DOG.exists_valid_link = 0 - -- AND IFNULL(DOG_ACCESS.does_user_meet_id_filters, 0) = 0 AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 ) ) @@ -703,7 +700,6 @@ BEGIN AND t_DOG.does_meet_non_id_filters = 0 AND ( t_DOG.exists_valid_link = 0 - -- AND IFNULL(DOG_ACCESS.does_user_meet_non_id_filters, 0) = 0 AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 ) ) diff --git a/static/MySQL/71104_p_dog_calc_command.sql b/static/MySQL/71104_p_dog_calc_command.sql index 1970e26..a514339 100644 --- a/static/MySQL/71104_p_dog_calc_command.sql +++ b/static/MySQL/71104_p_dog_calc_command.sql @@ -45,6 +45,7 @@ BEGIN DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; DECLARE v_is_super_user BIT; + DECLARE v_priority_access_level_none INT; DECLARE v_priority_access_level_view INT; DECLARE v_time_start TIMESTAMP(6); @@ -102,6 +103,7 @@ BEGIN SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); SET v_id_permission_command_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'COMMAND_VIEW' LIMIT 1); SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1); + SET v_priority_access_level_none := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'NONE' LIMIT 1); SET v_priority_access_level_view := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.id_access_level = v_id_access_level_view); @@ -191,6 +193,7 @@ BEGIN id_command_category INT NOT NULL , exists_valid_link BIT NOT NULL , id_user INT + -- , active BIT , does_meet_id_filters BIT NOT NULL , does_meet_non_id_filters BIT NOT NULL ); @@ -485,6 +488,8 @@ BEGIN ELSE INSERT INTO tmp_Command_Category_Calc_Command ( id_command_category + , exists_valid_link + , id_user , does_meet_id_filters , does_meet_non_id_filters ) @@ -569,6 +574,8 @@ BEGIN ) SELECT COMMAND_CATEGORY.id_command_category + , IFNULL(COMMAND_CATEGORY_ACCESS.exists_valid_link, 0) AS exists_valid_link + , COMMAND_CATEGORY_ACCESS.id_user , CASE WHEN v_has_filter_command_category_id = 0 OR COMMAND_CATEGORY_FILTERS.does_meet_id_filter = 1 @@ -729,152 +736,6 @@ BEGIN ELSEIF EXISTS () */ ELSE - IF a_debug = 1 THEN - SELECT 'Command Filters'; - WITH - Command_Id_Filter AS ( - SELECT COMMAND.id_command - FROM tmp_Split_Id_Calc_Command t_SPLIT_ID - INNER JOIN fetchmetrics.DOG_Command COMMAND ON t_SPLIT_ID.as_int = COMMAND.id_command - ) - , Command_Name_Filter AS ( - SELECT COMMAND.id_command - FROM tmp_Split_Name_Calc_Command t_SPLIT_NAME - INNER JOIN fetchmetrics.DOG_Command COMMAND ON COMMAND.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') - WHERE - t_SPLIT_NAME.substring IS NOT NULL - AND t_SPLIT_NAME.substring <> '' - ) - , Command_Hand_Signal_Default_Description_Filter AS ( - SELECT COMMAND.id_command - FROM tmp_Split_Hand_Signal_Default_Description_Calc_Command t_SPLIT_HSDD - INNER JOIN fetchmetrics.DOG_Command COMMAND ON COMMAND.hand_signal_default_description LIKE CONCAT('%', t_SPLIT_HSDD.substring, '%') - WHERE - t_SPLIT_HSDD.substring IS NOT NULL - AND t_SPLIT_HSDD.substring <> '' - ) - , Command_Notes_Filter AS ( - SELECT COMMAND.id_command - FROM tmp_Split_Notes_Calc_Command t_SPLIT_NOTES - INNER JOIN fetchmetrics.DOG_Command COMMAND ON COMMAND.notes LIKE CONCAT('%', t_SPLIT_NOTES.substring, '%') - WHERE - t_SPLIT_NOTES.substring IS NOT NULL - AND t_SPLIT_NOTES.substring <> '' - ) - , Command_Filters AS ( - SELECT - COMMAND_COMBINED.id_command - , MAX(COMMAND_COMBINED.does_meet_id_filter) AS does_meet_id_filter - , MAX(COMMAND_COMBINED.does_meet_name_filter) AS does_meet_name_filter - , MAX(COMMAND_COMBINED.does_meet_hand_signal_default_description_filter) AS does_meet_hand_signal_default_description_filter - , MAX(COMMAND_COMBINED.does_meet_notes_filter) AS does_meet_notes_filter - FROM ( - SELECT - COMMAND_ID_FILTER.id_command - , 1 AS does_meet_id_filter - , 0 AS does_meet_name_filter - , 0 AS does_meet_hand_signal_default_description_filter - , 0 AS does_meet_notes_filter - FROM Command_Id_Filter COMMAND_ID_FILTER - UNION - SELECT - COMMAND_NAME_FILTER.id_command - , 0 AS does_meet_id_filter - , 1 AS does_meet_name_filter - , 0 AS does_meet_hand_signal_default_description_filter - , 0 AS does_meet_notes_filter - FROM Command_Name_Filter COMMAND_NAME_FILTER - UNION - SELECT - COMMAND_HSDD_FILTER.id_command - , 0 AS does_meet_id_filter - , 0 AS does_meet_name_filter - , 1 AS does_meet_hand_signal_default_description_filter - , 0 AS does_meet_notes_filter - FROM Command_Hand_Signal_Default_Description_Filter COMMAND_HSDD_FILTER - UNION - SELECT - COMMAND_NOTES_FILTER.id_command - , 0 AS does_meet_id_filter - , 0 AS does_meet_name_filter - , 0 AS does_meet_hand_signal_default_description_filter - , 1 AS does_meet_notes_filter - FROM Command_Notes_Filter COMMAND_NOTES_FILTER - ) COMMAND_COMBINED - GROUP BY COMMAND_COMBINED.id_command - ) - SELECT - COMMAND.id_command - , COMMAND.id_command_category - , CASE WHEN - v_has_filter_command_id = 0 - OR COMMAND_FILTERS.does_meet_id_filter = 1 - THEN 1 ELSE 0 END AS does_meet_id_filters - , CASE WHEN - ( - v_has_filter_command_name = 0 - AND v_has_filter_command_hand_signal_default_description = 0 - AND v_has_filter_command_notes = 0 - ) - OR COMMAND_FILTERS.does_meet_name_filter = 1 - OR COMMAND_FILTERS.does_meet_hand_signal_default_description_filter = 1 - OR COMMAND_FILTERS.does_meet_notes_filter = 1 - THEN 1 ELSE 0 END AS does_meet_non_id_filters - , CASE WHEN t_COMMAND_CATEGORY.id_command_category IS NOT NULL THEN 1 ELSE 0 END AS does_command_category_already_exist_in_temp_table - FROM fetchmetrics.DOG_Command COMMAND - INNER JOIN tmp_Command_Category_Calc_Command t_COMMAND_CATEGORY ON COMMAND.id_command_category = t_COMMAND_CATEGORY.id_command_category - LEFT JOIN Command_Filters COMMAND_FILTERS ON COMMAND.id_command = COMMAND_FILTERS.id_command - LEFT JOIN fetchmetrics.DOG_Command_Category_User_Link COMMAND_CATEGORY_USER_LINK - ON t_COMMAND_CATEGORY.id_command_category = COMMAND_CATEGORY_USER_LINK.id_command_category - AND ( - ( - a_get_inactive_command_category = 1 - AND a_get_inactive_user = 1 - ) - OR COMMAND_CATEGORY_USER_LINK.active = 1 - ) - LEFT JOIN tmp_Calc_User_Access_Calc_Command t_USER - ON COMMAND_CATEGORY_USER_LINK.id_user = t_USER.id_user - AND ( - a_get_inactive_user = 1 - OR t_USER.active = 1 - ) - LEFT JOIN fetchmetrics.DOG_Access_Level ACCESS_LEVEL - ON COMMAND_CATEGORY_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level - AND ACCESS_LEVEL.active = 1 - WHERE - ( - a_get_all_command = 1 - OR ( - v_has_filter_command_id = 1 - AND COMMAND_FILTERS.does_meet_id_filter = 1 - ) - OR ( - v_has_filter_command_name = 1 - AND COMMAND_FILTERS.does_meet_name_filter = 1 - ) - OR ( - v_has_filter_command_hand_signal_default_description = 1 - AND COMMAND_FILTERS.does_meet_hand_signal_default_description_filter = 1 - ) - OR ( - v_has_filter_command_notes = 1 - AND COMMAND_FILTERS.does_meet_notes_filter = 1 - ) - ) - AND ( - v_is_super_user = 1 - OR ( - t_USER.id_user IS NOT NULL - AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view - ) - ) - AND ( - a_get_inactive_command = 1 - OR COMMAND.active = 1 - ) - ; - END IF; INSERT INTO tmp_Command_Calc_Command ( id_command , id_command_category @@ -954,6 +815,51 @@ BEGIN ) COMMAND_COMBINED GROUP BY COMMAND_COMBINED.id_command ) + , Command_Category_Access AS ( + SELECT + COMMAND_CATEGORY.id_command_category + , CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END AS exists_valid_link + , ROW_NUMBER() OVER ( + PARTITION BY COMMAND_CATEGORY.id_command_category + ORDER BY + CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END DESC + , t_USER.does_meet_id_filters DESC + , t_USER.does_meet_non_id_filters DESC + ) AS index_link_in_command_category + , t_USER.id_user + , COMMAND_CATEGORY.active + FROM fetchmetrics.DOG_Command_Category COMMAND_CATEGORY + LEFT JOIN fetchmetrics.DOG_Command_Category_User_Link COMMAND_CATEGORY_USER_LINK + ON COMMAND_CATEGORY.id_command_category = COMMAND_CATEGORY_USER_LINK.id_command_category + AND ( + ( + a_get_inactive_command_category = 1 + AND a_get_inactive_user = 1 + ) + OR COMMAND_CATEGORY_USER_LINK.active = 1 + ) + LEFT JOIN tmp_Calc_User_Access_Calc_Command t_USER + ON COMMAND_CATEGORY_USER_LINK.id_user = t_USER.id_user + AND ( + a_get_inactive_user = 1 + OR t_USER.active = 1 + ) + LEFT JOIN fetchmetrics.DOG_Access_Level ACCESS_LEVEL + ON COMMAND_CATEGORY_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level + AND ACCESS_LEVEL.active = 1 + ) SELECT COMMAND.id_command , COMMAND.id_command_category @@ -973,28 +879,13 @@ BEGIN THEN 1 ELSE 0 END AS does_meet_non_id_filters , CASE WHEN t_COMMAND_CATEGORY.id_command_category IS NOT NULL THEN 1 ELSE 0 END AS does_command_category_already_exist_in_temp_table FROM fetchmetrics.DOG_Command COMMAND - INNER JOIN tmp_Command_Category_Calc_Command t_COMMAND_CATEGORY ON COMMAND.id_command_category = t_COMMAND_CATEGORY.id_command_category + LEFT JOIN tmp_Command_Category_Calc_Command t_COMMAND_CATEGORY ON COMMAND.id_command_category = t_COMMAND_CATEGORY.id_command_category LEFT JOIN Command_Filters COMMAND_FILTERS ON COMMAND.id_command = COMMAND_FILTERS.id_command - LEFT JOIN fetchmetrics.DOG_Command_Category_User_Link COMMAND_CATEGORY_USER_LINK - ON t_COMMAND_CATEGORY.id_command_category = COMMAND_CATEGORY_USER_LINK.id_command_category - AND ( - ( - a_get_inactive_command_category = 1 - AND a_get_inactive_user = 1 - ) - OR COMMAND_CATEGORY_USER_LINK.active = 1 - ) - LEFT JOIN tmp_Calc_User_Access_Calc_Command t_USER - ON COMMAND_CATEGORY_USER_LINK.id_user = t_USER.id_user - AND ( - a_get_inactive_user = 1 - OR t_USER.active = 1 - ) - LEFT JOIN fetchmetrics.DOG_Access_Level ACCESS_LEVEL - ON COMMAND_CATEGORY_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level - AND ACCESS_LEVEL.active = 1 + LEFT JOIN Command_Category_Access COMMAND_CATEGORY_ACCESS + ON COMMAND.id_command_category = COMMAND_CATEGORY_ACCESS.id_command_category + AND COMMAND_CATEGORY_ACCESS.index_link_in_command_category = 1 WHERE - ( + ( a_get_all_command = 1 OR ( v_has_filter_command_id = 1 @@ -1013,17 +904,15 @@ BEGIN AND COMMAND_FILTERS.does_meet_notes_filter = 1 ) ) - AND ( - v_is_super_user = 1 - OR ( - t_USER.id_user IS NOT NULL - AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view - ) - ) AND ( a_get_inactive_command = 1 OR COMMAND.active = 1 ) + AND IFNULL(COMMAND_CATEGORY_ACCESS.exists_valid_link, 0) = 1 + AND ( + a_get_inactive_command_category = 1 + OR COMMAND_CATEGORY_ACCESS.active = 1 + ) ; END IF; END IF; @@ -1040,28 +929,29 @@ BEGIN END IF; -- Missing Categories - IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Command t_ERROR INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN + /* + IF + NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Command t_ERROR INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) + AND a_require_all_id_search_filters_met = 0 + AND a_require_all_non_id_search_filters_met = 0 + THEN - IF - a_require_all_id_search_filters_met = 0 - AND a_require_all_non_id_search_filters_met = 0 - THEN - INSERT INTO tmp_Command_Category_Calc_Command ( - id_command_category - , does_meet_id_filters - , does_meet_non_id_filters - ) - SELECT DISTINCT - COMMAND_CATEGORY.id_command_category - , 0 AS does_meet_id_filters - , 0 AS does_meet_non_id_filters - FROM fetchmetrics.DOG_Command_Category COMMAND_CATEGORY - INNER JOIN tmp_Command_Calc_Command t_COMMAND - ON COMMAND_CATEGORY.id_command_category = t_COMMAND.id_command_category - AND t_COMMAND.does_command_category_already_exist_in_temp_table = 0 - ; - END IF; + INSERT INTO tmp_Command_Category_Calc_Command ( + id_command_category + , does_meet_id_filters + , does_meet_non_id_filters + ) + SELECT DISTINCT + COMMAND_CATEGORY.id_command_category + , 0 AS does_meet_id_filters + , 0 AS does_meet_non_id_filters + FROM fetchmetrics.DOG_Command_Category COMMAND_CATEGORY + INNER JOIN tmp_Command_Calc_Command t_COMMAND + ON COMMAND_CATEGORY.id_command_category = t_COMMAND.id_command_category + AND t_COMMAND.does_command_category_already_exist_in_temp_table = 0 + ; END IF; + */ -- Filter records IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Command t_ERROR INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN @@ -1088,109 +978,19 @@ BEGIN ) ) OR ( - a_require_any_id_search_filters_met = 1 + a_require_any_id_search_filters_met = 1 AND t_COMMAND.does_meet_id_filters = 0 AND t_COMMAND_CATEGORY.does_meet_id_filters = 0 AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 ) OR ( - a_require_any_non_id_search_filters_met = 1 + a_require_any_non_id_search_filters_met = 1 AND t_COMMAND.does_meet_non_id_filters = 0 AND t_COMMAND_CATEGORY.does_meet_non_id_filters = 0 AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 ) ; - IF a_debug = 1 THEN - WITH - Category_And_Best_Command AS ( - SELECT - t_COMMAND.id_command_category - , MAX(IFNULL(t_COMMAND.does_meet_id_filters, 0)) AS does_meet_id_filters - , MAX(IFNULL(t_COMMAND.does_meet_non_id_filters, 0)) AS does_meet_non_id_filters - FROM tmp_Command_Calc_Command t_COMMAND - GROUP BY t_COMMAND.id_command_category - ) - , Command_Category_Access AS ( - SELECT - COMMAND_CATEGORY.id_command_category - , CASE WHEN - v_is_super_user = 1 - OR ( - t_USER.id_user IS NOT NULL - AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view - ) - THEN 1 ELSE 0 END AS can_user_access_command_category - , ROW_NUMBER() OVER ( - PARTITION BY COMMAND_CATEGORY.id_command_category - ORDER BY CASE WHEN - v_is_super_user = 1 - OR ( - t_USER.id_user IS NOT NULL - AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view - ) - THEN 1 ELSE 0 END DESC - ) AS index_link_in_command_category - , t_USER.does_meet_id_filters AS does_user_meet_id_filters - , t_USER.does_meet_non_id_filters AS does_user_meet_non_id_filters - FROM fetchmetrics.DOG_Command_Category COMMAND_CATEGORY - LEFT JOIN fetchmetrics.DOG_Command_Category_User_Link COMMAND_CATEGORY_USER_LINK - ON COMMAND_CATEGORY.id_command_category = COMMAND_CATEGORY_USER_LINK.id_command_category - AND ( - ( - a_get_inactive_command_category = 1 - AND a_get_inactive_user = 1 - ) - OR COMMAND_CATEGORY_USER_LINK.active = 1 - ) - LEFT JOIN tmp_Calc_User_Access_Calc_Command t_USER - ON COMMAND_CATEGORY_USER_LINK.id_user = t_USER.id_user - AND ( - a_get_inactive_user = 1 - OR t_USER.active = 1 - ) - LEFT JOIN fetchmetrics.DOG_Access_Level ACCESS_LEVEL - ON COMMAND_CATEGORY_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level - AND ACCESS_LEVEL.active = 1 - ) - SELECT * - FROM tmp_Command_Category_Calc_Command t_COMMAND_CATEGORY - LEFT JOIN Category_And_Best_Command CATEGORY_BEST ON t_COMMAND_CATEGORY.id_command_category = CATEGORY_BEST.id_command_category - LEFT JOIN Command_Category_Access COMMAND_CATEGORY_ACCESS - ON t_COMMAND_CATEGORY.id_command_category = COMMAND_CATEGORY_ACCESS.id_command_category - AND COMMAND_CATEGORY_ACCESS.index_link_in_command_category = 1 - WHERE - ( - a_require_all_id_search_filters_met = 1 - AND ( - IFNULL(CATEGORY_BEST.does_meet_id_filters, 0) = 0 - OR t_COMMAND_CATEGORY.does_meet_id_filters = 0 - OR IFNULL(COMMAND_CATEGORY_ACCESS.does_user_meet_id_filters, 0) = 0 - ) - ) - OR ( - a_require_all_non_id_search_filters_met = 1 - AND ( - IFNULL(CATEGORY_BEST.does_meet_non_id_filters, 0) = 0 - OR t_COMMAND_CATEGORY.does_meet_non_id_filters = 0 - OR IFNULL(COMMAND_CATEGORY_ACCESS.does_user_meet_non_id_filters, 0) = 0 - ) - ) - OR ( - a_require_any_id_search_filters_met = 1 - AND IFNULL(CATEGORY_BEST.does_meet_id_filters, 0) = 0 - AND t_COMMAND_CATEGORY.does_meet_id_filters = 0 - AND IFNULL(COMMAND_CATEGORY_ACCESS.does_user_meet_id_filters, 0) = 0 - ) - OR ( - a_require_any_non_id_search_filters_met = 1 - AND IFNULL(CATEGORY_BEST.does_meet_non_id_filters, 0) = 0 - AND t_COMMAND_CATEGORY.does_meet_non_id_filters = 0 - AND IFNULL(COMMAND_CATEGORY_ACCESS.does_user_meet_non_id_filters, 0) = 0 - ) - ; - END IF; - WITH Category_And_Best_Command AS ( SELECT @@ -1200,6 +1000,7 @@ BEGIN FROM tmp_Command_Calc_Command t_COMMAND GROUP BY t_COMMAND.id_command_category ) + /* , Command_Category_Access AS ( SELECT COMMAND_CATEGORY.id_command_category @@ -1242,19 +1043,23 @@ BEGIN ON COMMAND_CATEGORY_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level AND ACCESS_LEVEL.active = 1 ) + */ SELECT * FROM tmp_Command_Category_Calc_Command t_COMMAND_CATEGORY LEFT JOIN Category_And_Best_Command CATEGORY_BEST ON t_COMMAND_CATEGORY.id_command_category = CATEGORY_BEST.id_command_category + /* LEFT JOIN Command_Category_Access COMMAND_CATEGORY_ACCESS ON t_COMMAND_CATEGORY.id_command_category = COMMAND_CATEGORY_ACCESS.id_command_category AND COMMAND_CATEGORY_ACCESS.index_link_in_command_category = 1 + */ + LEFT JOIN tmp_Calc_User_Access_Calc_Command t_USER ON t_COMMAND_CATEGORY.id_user = t_USER.id_user WHERE ( a_require_all_id_search_filters_met = 1 AND ( IFNULL(CATEGORY_BEST.does_meet_id_filters, 0) = 0 OR t_COMMAND_CATEGORY.does_meet_id_filters = 0 - OR IFNULL(COMMAND_CATEGORY_ACCESS.does_user_meet_id_filters, 0) = 0 + OR IFNULL(t_USER.does_meet_id_filters, 0) = 0 ) ) OR ( @@ -1262,20 +1067,20 @@ BEGIN AND ( IFNULL(CATEGORY_BEST.does_meet_non_id_filters, 0) = 0 OR t_COMMAND_CATEGORY.does_meet_non_id_filters = 0 - OR IFNULL(COMMAND_CATEGORY_ACCESS.does_user_meet_non_id_filters, 0) = 0 + OR IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 ) ) OR ( - a_require_any_id_search_filters_met = 1 + a_require_any_id_search_filters_met = 1 AND IFNULL(CATEGORY_BEST.does_meet_id_filters, 0) = 0 AND t_COMMAND_CATEGORY.does_meet_id_filters = 0 - AND IFNULL(COMMAND_CATEGORY_ACCESS.does_user_meet_id_filters, 0) = 0 + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 ) OR ( - a_require_any_non_id_search_filters_met = 1 + a_require_any_non_id_search_filters_met = 1 AND IFNULL(CATEGORY_BEST.does_meet_non_id_filters, 0) = 0 AND t_COMMAND_CATEGORY.does_meet_non_id_filters = 0 - AND IFNULL(COMMAND_CATEGORY_ACCESS.does_user_meet_non_id_filters, 0) = 0 + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 ) ; END IF; diff --git a/static/MySQL/71200_p_dog_calc_location.sql b/static/MySQL/71200_p_dog_calc_location.sql index 88a1ba7..e900b78 100644 --- a/static/MySQL/71200_p_dog_calc_location.sql +++ b/static/MySQL/71200_p_dog_calc_location.sql @@ -171,6 +171,8 @@ BEGIN CREATE TEMPORARY TABLE tmp_Location_Calc_Location ( id_location INT NOT NULL , id_location_parent INT + , exists_valid_link BIT + , id_user INT , does_meet_id_filters BIT NOT NULL , does_meet_non_id_filters BIT NOT NULL , csv_id_locations_parent TEXT @@ -450,100 +452,11 @@ BEGIN ELSEIF EXISTS () */ ELSE - IF a_debug = 1 THEN - SELECT 'Location Filters'; - WITH - Location_Id_Filter AS ( - SELECT LOCATIONS.id_location - FROM tmp_Split_Id_Calc_Location t_SPLIT_ID - INNER JOIN fetchmetrics.DOG_Location LOCATIONS ON t_SPLIT_ID.as_int = LOCATIONS.id_location - ) - , Location_Name_Filter AS ( - SELECT LOCATIONS.id_location - FROM tmp_Split_Name_Calc_Location t_SPLIT_NAME - INNER JOIN fetchmetrics.DOG_Location LOCATIONS ON LOCATIONS.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') - WHERE NULLIF(t_SPLIT_NAME.substring, '') IS NOT NULL - ) - , Location_Filters AS ( - SELECT - LOCATIONS_COMBINED.id_location - , MAX(LOCATIONS_COMBINED.does_meet_id_filter) AS does_meet_id_filter - , MAX(LOCATIONS_COMBINED.does_meet_name_filter) AS does_meet_name_filter - FROM ( - SELECT - LOCATIONS_ID_FILTER.id_location - , 1 AS does_meet_id_filter - , 0 AS does_meet_name_filter - FROM Location_Id_Filter LOCATIONS_ID_FILTER - UNION - SELECT - LOCATIONS_NAME_FILTER.id_location - , 0 AS does_meet_id_filter - , 1 AS does_meet_name_filter - FROM Location_Name_Filter LOCATIONS_NAME_FILTER - ) LOCATIONS_COMBINED - GROUP BY LOCATIONS_COMBINED.id_location - ) - SELECT - LOCATIONS.id_location - , CASE WHEN - v_has_filter_location_id = 0 - OR IFNULL(LOCATIONS_FILTERS.does_meet_id_filter, 0) = 1 - THEN 1 ELSE 0 END AS does_meet_id_filters - , CASE WHEN - ( - v_has_filter_location_name = 0 - ) - OR IFNULL(LOCATIONS_FILTERS.does_meet_name_filter, 0) = 1 - THEN 1 ELSE 0 END AS does_meet_non_id_filters - FROM fetchmetrics.DOG_Location LOCATIONS - LEFT JOIN Location_Filters LOCATIONS_FILTERS ON LOCATIONS.id_location = LOCATIONS_FILTERS.id_location - LEFT JOIN fetchmetrics.DOG_Location_User_Link LOCATION_USER_LINK - ON LOCATIONS.id_location = LOCATION_USER_LINK.id_location - AND ( - ( - a_get_inactive_location = 1 - AND a_get_inactive_user = 1 - ) - OR LOCATION_USER_LINK.active = 1 - ) - LEFT JOIN tmp_Calc_User_Access_Calc_Location t_USER - ON LOCATION_USER_LINK.id_user = t_USER.id_user - AND ( - a_get_inactive_user = 1 - OR t_USER.active = 1 - ) - LEFT JOIN fetchmetrics.DOG_Access_Level ACCESS_LEVEL - ON LOCATION_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level - AND ACCESS_LEVEL.active = 1 - WHERE - ( - a_get_all_location = 1 - OR ( - v_has_filter_location_id = 1 - AND LOCATIONS_FILTERS.does_meet_id_filter = 1 - ) - OR ( - v_has_filter_location_name = 1 - AND LOCATIONS_FILTERS.does_meet_name_filter = 1 - ) - ) - AND ( - v_is_super_user = 1 - OR ( - t_USER.id_user IS NOT NULL - AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view - ) - ) - AND ( - a_get_inactive_location = 1 - OR LOCATIONS.active = 1 - ) - ; - END IF; INSERT INTO tmp_Location_Calc_Location ( id_location , id_location_parent + , exists_valid_link + , id_user , does_meet_id_filters , does_meet_non_id_filters ) @@ -581,9 +494,55 @@ BEGIN ) LOCATIONS_COMBINED GROUP BY LOCATIONS_COMBINED.id_location ) + , Location_Access AS ( + SELECT + LOCATIONS.id_location + , CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END AS exists_valid_link + , ROW_NUMBER() OVER ( + PARTITION BY LOCATIONS.id_location + ORDER BY + CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END DESC + , t_USER.does_meet_id_filters DESC + , t_USER.does_meet_non_id_filters DESC + ) AS index_link_in_location + , t_USER.id_user + FROM fetchmetrics.DOG_Location LOCATIONS + LEFT JOIN fetchmetrics.DOG_Location_User_Link LOCATION_USER_LINK + ON LOCATIONS.id_location = LOCATION_USER_LINK.id_location + AND ( + ( + a_get_inactive_location = 1 + AND a_get_inactive_user = 1 + ) + OR LOCATION_USER_LINK.active = 1 + ) + LEFT JOIN tmp_Calc_User_Access_Calc_Location t_USER + ON LOCATION_USER_LINK.id_user = t_USER.id_user + AND ( + a_get_inactive_user = 1 + OR t_USER.active = 1 + ) + LEFT JOIN fetchmetrics.DOG_Access_Level ACCESS_LEVEL + ON LOCATION_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level + AND ACCESS_LEVEL.active = 1 + ) SELECT LOCATIONS.id_location , LOCATIONS.id_location_parent + , IFNULL(LOCATIONS_ACCESS.exists_valid_link, 0) AS exists_valid_link + , LOCATIONS_ACCESS.id_user , CASE WHEN v_has_filter_location_id = 0 OR IFNULL(LOCATIONS_FILTERS.does_meet_id_filter, 0) = 1 @@ -596,26 +555,11 @@ BEGIN THEN 1 ELSE 0 END AS does_meet_non_id_filters FROM fetchmetrics.DOG_Location LOCATIONS LEFT JOIN Location_Filters LOCATIONS_FILTERS ON LOCATIONS.id_location = LOCATIONS_FILTERS.id_location - LEFT JOIN fetchmetrics.DOG_Location_User_Link LOCATION_USER_LINK - ON LOCATIONS.id_location = LOCATION_USER_LINK.id_location - AND ( - ( - a_get_inactive_location = 1 - AND a_get_inactive_user = 1 - ) - OR LOCATION_USER_LINK.active = 1 - ) - LEFT JOIN tmp_Calc_User_Access_Calc_Location t_USER - ON LOCATION_USER_LINK.id_user = t_USER.id_user - AND ( - a_get_inactive_user = 1 - OR t_USER.active = 1 - ) - LEFT JOIN fetchmetrics.DOG_Access_Level ACCESS_LEVEL - ON LOCATION_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level - AND ACCESS_LEVEL.active = 1 + LEFT JOIN Location_Access LOCATIONS_ACCESS + ON LOCATIONS.id_location = LOCATIONS_ACCESS.id_location + AND LOCATIONS_ACCESS.index_link_in_location = 1 WHERE - ( + ( a_get_all_location = 1 OR ( v_has_filter_location_id = 1 @@ -626,13 +570,7 @@ BEGIN AND LOCATIONS_FILTERS.does_meet_name_filter = 1 ) ) - AND ( - v_is_super_user = 1 - OR ( - t_USER.id_user IS NOT NULL - AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view - ) - ) + AND IFNULL(LOCATIONS_ACCESS.exists_valid_link, 0) = 1 AND ( a_get_inactive_location = 1 OR LOCATIONS.active = 1 @@ -651,6 +589,7 @@ BEGIN -- Filter records IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Location t_ERROR INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN + /* WITH Location_Access AS ( SELECT @@ -694,45 +633,35 @@ BEGIN ON LOCATION_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level AND ACCESS_LEVEL.active = 1 ) + */ DELETE t_LOCATIONS FROM tmp_Location_Calc_Location t_LOCATIONS - LEFT JOIN Location_Access LOCATION_ACCESS ON t_LOCATIONS.id_location = LOCATION_ACCESS.id_location + -- LEFT JOIN Location_Access LOCATION_ACCESS ON t_LOCATIONS.id_location = LOCATION_ACCESS.id_location + LEFT JOIN tmp_Calc_User_Access_Calc_Location t_USER ON t_LOCATIONS.id_user = t_USER.id_user WHERE ( a_require_all_id_search_filters_met = 1 AND ( t_LOCATIONS.does_meet_id_filters = 0 - OR ( - IFNULL(LOCATION_ACCESS.can_user_access_location, 0) = 0 - AND IFNULL(LOCATION_ACCESS.does_user_meet_non_id_filters, 0) = 0 - ) + OR IFNULL(t_USER.does_meet_id_filters, 0) = 0 ) ) OR ( a_require_all_non_id_search_filters_met = 1 AND ( t_LOCATIONS.does_meet_non_id_filters = 0 - OR ( - IFNULL(LOCATION_ACCESS.can_user_access_location, 0) = 0 - AND IFNULL(LOCATION_ACCESS.does_user_meet_non_id_filters, 0) = 0 - ) + OR IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 ) ) OR ( a_require_any_id_search_filters_met = 1 AND t_LOCATIONS.does_meet_id_filters = 0 - AND ( - IFNULL(LOCATION_ACCESS.can_user_access_location, 0) = 0 - AND IFNULL(LOCATION_ACCESS.does_user_meet_non_id_filters, 0) = 0 - ) + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 ) OR ( a_require_any_non_id_search_filters_met = 1 AND t_LOCATIONS.does_meet_non_id_filters = 0 - AND ( - IFNULL(LOCATION_ACCESS.can_user_access_location, 0) = 0 - AND IFNULL(LOCATION_ACCESS.does_user_meet_non_id_filters, 0) = 0 - ) + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 ) ; END IF; diff --git a/static/MySQL/71220_p_dog_calc_button_shape.sql b/static/MySQL/71220_p_dog_calc_button_shape.sql index c0c7ef4..6f8acd5 100644 --- a/static/MySQL/71220_p_dog_calc_button_shape.sql +++ b/static/MySQL/71220_p_dog_calc_button_shape.sql @@ -12,6 +12,11 @@ CREATE PROCEDURE fetchmetrics.p_dog_calc_button_shape ( , IN a_ids_button_shape TEXT , IN a_names_button_shape TEXT , IN a_notes_button_shape TEXT + , IN a_get_all_user BIT + , IN a_get_inactive_user BIT + , IN a_ids_user TEXT + , IN a_names_user TEXT + , IN a_emails_user TEXT , IN a_require_all_id_search_filters_met BIT , IN a_require_any_id_search_filters_met BIT , IN a_require_all_non_id_search_filters_met BIT @@ -31,6 +36,9 @@ BEGIN DECLARE v_id_permission_dog_view INT; DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; + DECLARE v_is_super_user BIT; + DECLARE v_priority_access_level_none INT; + DECLARE v_priority_access_level_view INT; DECLARE v_time_start TIMESTAMP(6); DECLARE exit handler for SQLEXCEPTION @@ -87,7 +95,9 @@ BEGIN SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1); - + SET v_priority_access_level_none := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'NONE' LIMIT 1); + SET v_priority_access_level_view := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.id_access_level = v_id_access_level_view); + CALL fetchmetrics.p_core_validate_guid ( a_guid ); @@ -113,6 +123,11 @@ BEGIN , a_ids_button_shape , a_names_button_shape , a_notes_button_shape + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met , a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met @@ -134,9 +149,30 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_Button_Shape; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_Button_Shape; DROP TEMPORARY TABLE IF EXISTS tmp_Button_Shape_Calc_Button_Shape; + DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_Button_Shape; + + CREATE TEMPORARY TABLE tmp_Calc_User_Access_Calc_Button_Shape ( + id_temp INT PRIMARY KEY AUTO_INCREMENT NOT NULL + , id_user INT + , id_role INT + , id_permission_required INT NOT NULL + , priority_access_level_required INT NOT NULL + , is_super_user BIT + , priority_access_level_user INT + , has_access BIT + , can_view BIT + , can_edit BIT + , can_admin BIT + , active BIT + + , does_meet_id_filters BIT + , does_meet_non_id_filters BIT + ); CREATE TEMPORARY TABLE tmp_Button_Shape_Calc_Button_Shape ( id_button_shape INT NOT NULL + , exists_valid_link BIT NOT NULL + , id_user INT , does_meet_id_filters BIT NOT NULL , does_meet_non_id_filters BIT NOT NULL ); @@ -170,6 +206,172 @@ BEGIN SET v_has_filter_button_shape_name = CASE WHEN a_names_button_shape <> '' THEN 1 ELSE 0 END; SET v_has_filter_button_shape_notes = CASE WHEN a_notes_button_shape <> '' THEN 1 ELSE 0 END; + + -- Permissions + IF a_debug = 1 THEN + SELECT + a_guid -- a_guid + , 0 -- get_all_user + , 0 -- get_inactive_user + , a_id_user -- ids_user + , '' -- a_auth0_ids_user + , '' -- a_names_user + , '' -- a_emails_user + , 1 -- a_require_all_id_search_filters_met + , 1 -- a_require_any_id_search_filters_met + , 0 -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_id_permission_dog_view -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL fetchmetrics.p_dog_calc_user_access( + a_guid -- a_guid + , 0 -- get_all_user + , 0 -- get_inactive_user + , a_id_user -- ids_user + , '' -- a_auth0_ids_user + , '' -- a_names_user + , '' -- a_emails_user + , 1 -- a_require_all_id_search_filters_met + , 1 -- a_require_any_id_search_filters_met + , 0 -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_id_permission_dog_view -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ); + + SELECT + IFNULL(CALC_USER_T.has_access, 0) + , IFNULL(CALC_USER_T.is_super_user, 0) + INTO + v_can_view + , v_is_super_user + FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T + WHERE CALC_USER_T.GUID = a_guid + LIMIT 1 + ; + + IF a_debug = 1 THEN + SELECT + v_can_view + , v_is_super_user + ; + END IF; + + IF (v_can_view = 0) THEN + DELETE t_ME + FROM tmp_Msg_Error_Calc_Button_Shape t_ME + WHERE t_ME.id_type <> v_id_type_error_no_permission + ; + INSERT INTO tmp_Msg_Error_Calc_Button_Shape ( + id_type + , code + , msg + ) + VALUES ( + v_id_type_error_no_permission + , v_code_type_error_no_permission + , 'You do not have permission to view Dogs and Button_Shapes.' + ) + ; + END IF; + + CALL fetchmetrics.p_dog_clear_calc_user_access( + a_guid + , 0 -- a_debug + ); + + -- Users + IF a_debug = 1 THEN + SELECT + a_guid -- guid + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , '' -- a_auth0_ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user + , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met + , 0 -- a_require_any_id_search_filters_met + , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_id_permission_dog_view -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL fetchmetrics.p_dog_calc_user_access( + a_guid-- guid + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , '' -- a_auth0_ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user + , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met + , 0 -- a_require_any_id_search_filters_met + , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_id_permission_dog_view -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ); + + INSERT INTO tmp_Calc_User_Access_Calc_Button_Shape ( + id_user + , id_role + , id_permission_required + , priority_access_level_required + , is_super_user + , priority_access_level_user + , has_access + , can_view + , can_edit + , can_admin + , active + , does_meet_id_filters + , does_meet_non_id_filters + ) + SELECT + CALC_USER_T.id_user + , CALC_USER_T.id_role + , CALC_USER_T.id_permission_required + , CALC_USER_T.priority_access_level_required + , CALC_USER_T.is_super_user + , CALC_USER_T.priority_access_level_user + , CALC_USER_T.has_access + , CALC_USER_T.can_view + , CALC_USER_T.can_edit + , CALC_USER_T.can_admin + , CALC_USER_T.active + , CALC_USER_T.does_meet_id_filters + , CALC_USER_T.does_meet_non_id_filters + FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T + WHERE CALC_USER_T.GUID = a_guid + ; + + IF a_debug = 1 THEN + SELECT 'After get many user'; + SELECT * FROM tmp_Calc_User_Access_Calc_Button_Shape; + SELECT COUNT(*) AS Count_Errors FROM tmp_Msg_Error_Calc_Button_Shape t_ERROR; + SELECT * FROM tmp_Msg_Error_Calc_Button_Shape t_ERROR; + END IF; + + CALL fetchmetrics.p_dog_clear_calc_user_access( + a_guid + , 0 -- a_debug + ); + + -- Button_Shapes IF v_has_filter_button_shape_id = 1 THEN CALL fetchmetrics.p_core_split(a_guid, a_ids_button_shape, ',', a_debug); @@ -238,12 +440,12 @@ BEGIN IF EXISTS ( SELECT * FROM tmp_Split_Id_Calc_Button_Shape t_SPLIT_ID - LEFT JOIN fetchmetrics.DOG_Button_Shape BUTTON_SHAPES ON t_SPLIT_ID.as_int = BUTTON_SHAPES.id_button_shape + LEFT JOIN fetchmetrics.DOG_Button_Shape BUTTON_SHAPE ON t_SPLIT_ID.as_int = BUTTON_SHAPE.id_button_shape WHERE ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(BUTTON_SHAPES.id_button_shape) + OR ISNULL(BUTTON_SHAPE.id_button_shape) OR ( - BUTTON_SHAPES.active = 0 + BUTTON_SHAPE.active = 0 AND a_get_inactive_button_shape = 0 ) ) THEN @@ -257,12 +459,12 @@ BEGIN , v_code_type_error_bad_data , CONCAT('Invalid or inactive Button_Shape IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT_ID.substring SEPARATOR ', '), 'NULL')) FROM tmp_Split_Id_Calc_Button_Shape t_SPLIT_ID - LEFT JOIN fetchmetrics.DOG_Button_Shape BUTTON_SHAPES ON t_SPLIT_ID.as_int = BUTTON_SHAPES.id_button_shape + LEFT JOIN fetchmetrics.DOG_Button_Shape BUTTON_SHAPE ON t_SPLIT_ID.as_int = BUTTON_SHAPE.id_button_shape WHERE ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(BUTTON_SHAPES.id_button_shape) + OR ISNULL(BUTTON_SHAPE.id_button_shape) OR ( - BUTTON_SHAPES.active = 0 + BUTTON_SHAPE.active = 0 AND a_get_inactive_button_shape = 0 ) ; @@ -272,88 +474,140 @@ BEGIN ELSE INSERT INTO tmp_Button_Shape_Calc_Button_Shape ( id_button_shape + , exists_valid_link + , id_user , does_meet_id_filters , does_meet_non_id_filters ) WITH Button_Shape_Id_Filter AS ( - SELECT BUTTON_SHAPES.id_button_shape + SELECT BUTTON_SHAPE.id_button_shape FROM tmp_Split_Id_Calc_Button_Shape t_SPLIT_ID - INNER JOIN fetchmetrics.DOG_Button_Shape BUTTON_SHAPES ON t_SPLIT_ID.as_int = BUTTON_SHAPES.id_button_shape + INNER JOIN fetchmetrics.DOG_Button_Shape BUTTON_SHAPE ON t_SPLIT_ID.as_int = BUTTON_SHAPE.id_button_shape ) , Button_Shape_Name_Filter AS ( - SELECT BUTTON_SHAPES.id_button_shape + SELECT BUTTON_SHAPE.id_button_shape FROM tmp_Split_Name_Calc_Button_Shape t_SPLIT_NAME - INNER JOIN fetchmetrics.DOG_Button_Shape BUTTON_SHAPES ON BUTTON_SHAPES.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') + INNER JOIN fetchmetrics.DOG_Button_Shape BUTTON_SHAPE ON BUTTON_SHAPE.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') WHERE NULLIF(t_SPLIT_NAME.substring, '') IS NOT NULL ) , Button_Shape_Notes_Filter AS ( - SELECT BUTTON_SHAPES.id_button_shape + SELECT BUTTON_SHAPE.id_button_shape FROM tmp_Split_Notes_Calc_Button_Shape t_SPLIT_NOTES - INNER JOIN fetchmetrics.DOG_Button_Shape BUTTON_SHAPES ON BUTTON_SHAPES.name LIKE CONCAT('%', t_SPLIT_NOTES.substring, '%') + INNER JOIN fetchmetrics.DOG_Button_Shape BUTTON_SHAPE ON BUTTON_SHAPE.name LIKE CONCAT('%', t_SPLIT_NOTES.substring, '%') WHERE NULLIF(t_SPLIT_NOTES.substring, '') IS NOT NULL ) , Button_Shape_Filters AS ( SELECT - BUTTON_SHAPES_COMBINED.id_button_shape - , MAX(BUTTON_SHAPES_COMBINED.does_meet_id_filter) AS does_meet_id_filter - , MAX(BUTTON_SHAPES_COMBINED.does_meet_name_filter) AS does_meet_name_filter - , MAX(BUTTON_SHAPES_COMBINED.does_meet_notes_filter) AS does_meet_notes_filter + BUTTON_SHAPE_COMBINED.id_button_shape + , MAX(BUTTON_SHAPE_COMBINED.does_meet_id_filter) AS does_meet_id_filter + , MAX(BUTTON_SHAPE_COMBINED.does_meet_name_filter) AS does_meet_name_filter + , MAX(BUTTON_SHAPE_COMBINED.does_meet_notes_filter) AS does_meet_notes_filter FROM ( SELECT - BUTTON_SHAPES_ID_FILTER.id_button_shape + BUTTON_SHAPE_ID_FILTER.id_button_shape , 1 AS does_meet_id_filter , 0 AS does_meet_name_filter , 0 AS does_meet_notes_filter - FROM Button_Shape_Id_Filter BUTTON_SHAPES_ID_FILTER + FROM Button_Shape_Id_Filter BUTTON_SHAPE_ID_FILTER UNION SELECT - BUTTON_SHAPES_NAME_FILTER.id_button_shape + BUTTON_SHAPE_NAME_FILTER.id_button_shape , 0 AS does_meet_id_filter , 1 AS does_meet_name_filter , 0 AS does_meet_notes_filter - FROM Button_Shape_Name_Filter BUTTON_SHAPES_NAME_FILTER + FROM Button_Shape_Name_Filter BUTTON_SHAPE_NAME_FILTER UNION SELECT - BUTTON_SHAPES_NOTES_FILTER.id_button_shape + BUTTON_SHAPE_NOTES_FILTER.id_button_shape , 0 AS does_meet_id_filter , 0 AS does_meet_name_filter , 1 AS does_meet_notes_filter - FROM Button_Shape_Notes_Filter BUTTON_SHAPES_NOTES_FILTER - ) BUTTON_SHAPES_COMBINED - GROUP BY BUTTON_SHAPES_COMBINED.id_button_shape + FROM Button_Shape_Notes_Filter BUTTON_SHAPE_NOTES_FILTER + ) BUTTON_SHAPE_COMBINED + GROUP BY BUTTON_SHAPE_COMBINED.id_button_shape + ) + , Button_Shape_Access AS ( + SELECT + BUTTON_SHAPE.id_button_shape + , CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END AS exists_valid_link + , ROW_NUMBER() OVER ( + PARTITION BY BUTTON_SHAPE.id_button_shape + ORDER BY + CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END DESC + , t_USER.does_meet_id_filters DESC + , t_USER.does_meet_non_id_filters DESC + ) AS index_link_in_button_shape + , t_USER.id_user + FROM fetchmetrics.DOG_Button_Shape BUTTON_SHAPE + LEFT JOIN fetchmetrics.DOG_Button_Shape_User_Link BUTTON_SHAPE_USER_LINK + ON BUTTON_SHAPE.id_button_shape = BUTTON_SHAPE_USER_LINK.id_button_shape + AND ( + ( + a_get_inactive_button_shape = 1 + AND a_get_inactive_user = 1 + ) + OR BUTTON_SHAPE_USER_LINK.active = 1 + ) + LEFT JOIN tmp_Calc_User_Access_Calc_Button_Shape t_USER + ON BUTTON_SHAPE_USER_LINK.id_user = t_USER.id_user + AND ( + a_get_inactive_user = 1 + OR t_USER.active = 1 + ) + LEFT JOIN fetchmetrics.DOG_Access_Level ACCESS_LEVEL + ON BUTTON_SHAPE_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level + AND ACCESS_LEVEL.active = 1 ) SELECT - BUTTON_SHAPES.id_button_shape + BUTTON_SHAPE.id_button_shape + , BUTTON_SHAPE_ACCESS.exists_valid_link + , BUTTON_SHAPE_ACCESS.id_user , CASE WHEN v_has_filter_button_shape_id = 0 - OR IFNULL(BUTTON_SHAPES_FILTERS.does_meet_id_filter, 0) = 1 + OR IFNULL(BUTTON_SHAPE_FILTERS.does_meet_id_filter, 0) = 1 THEN 1 ELSE 0 END AS does_meet_id_filters , CASE WHEN ( v_has_filter_button_shape_name = 0 AND v_has_filter_button_shape_notes = 0 ) - OR IFNULL(BUTTON_SHAPES_FILTERS.does_meet_name_filter, 0) = 1 - OR IFNULL(BUTTON_SHAPES_FILTERS.does_meet_notes_filter, 0) = 1 + OR IFNULL(BUTTON_SHAPE_FILTERS.does_meet_name_filter, 0) = 1 + OR IFNULL(BUTTON_SHAPE_FILTERS.does_meet_notes_filter, 0) = 1 THEN 1 ELSE 0 END AS does_meet_non_id_filters - FROM fetchmetrics.DOG_Button_Shape BUTTON_SHAPES - LEFT JOIN Button_Shape_Filters BUTTON_SHAPES_FILTERS ON BUTTON_SHAPES.id_button_shape = BUTTON_SHAPES_FILTERS.id_button_shape + FROM fetchmetrics.DOG_Button_Shape BUTTON_SHAPE + LEFT JOIN Button_Shape_Filters BUTTON_SHAPE_FILTERS ON BUTTON_SHAPE.id_button_shape = BUTTON_SHAPE_FILTERS.id_button_shape + LEFT JOIN Button_Shape_Access BUTTON_SHAPE_ACCESS + ON BUTTON_SHAPE.id_button_shape = BUTTON_SHAPE_ACCESS.id_button_shape + AND BUTTON_SHAPE_ACCESS.index_link_in_button_shape = 1 WHERE ( a_get_all_button_shape = 1 OR ( v_has_filter_button_shape_id = 1 - AND BUTTON_SHAPES_FILTERS.does_meet_id_filter = 1 + AND BUTTON_SHAPE_FILTERS.does_meet_id_filter = 1 ) OR ( v_has_filter_button_shape_name = 1 - AND BUTTON_SHAPES_FILTERS.does_meet_name_filter = 1 + AND BUTTON_SHAPE_FILTERS.does_meet_name_filter = 1 ) ) + AND IFNULL(BUTTON_SHAPE_ACCESS.exists_valid_link, 0) = 1 AND ( a_get_inactive_button_shape = 1 - OR BUTTON_SHAPES.active = 1 + OR BUTTON_SHAPE.active = 1 ) ; END IF; @@ -370,28 +624,45 @@ BEGIN -- Filter records IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Button_Shape t_ERROR INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN - DELETE t_BUTTON_SHAPES - FROM tmp_Button_Shape_Calc_Button_Shape t_BUTTON_SHAPES + DELETE t_BUTTON_SHAPE + FROM tmp_Button_Shape_Calc_Button_Shape t_BUTTON_SHAPE + LEFT JOIN tmp_Calc_User_Access_Calc_Button_Shape t_USER ON t_BUTTON_SHAPE.id_user = t_USER.id_user WHERE ( a_require_all_id_search_filters_met = 1 AND ( - t_BUTTON_SHAPES.does_meet_id_filters = 0 + t_BUTTON_SHAPE.does_meet_id_filters = 0 + OR ( + t_BUTTON_SHAPE.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 + ) ) ) OR ( a_require_all_non_id_search_filters_met = 1 AND ( - t_BUTTON_SHAPES.does_meet_non_id_filters = 0 + t_BUTTON_SHAPE.does_meet_non_id_filters = 0 + OR ( + t_BUTTON_SHAPE.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 + ) ) ) OR ( a_require_any_id_search_filters_met = 1 - AND t_BUTTON_SHAPES.does_meet_id_filters = 0 + AND t_BUTTON_SHAPE.does_meet_id_filters = 0 + AND ( + t_BUTTON_SHAPE.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 + ) ) OR ( a_require_any_non_id_search_filters_met = 1 - AND t_BUTTON_SHAPES.does_meet_non_id_filters = 0 + AND t_BUTTON_SHAPE.does_meet_non_id_filters = 0 + AND ( + t_BUTTON_SHAPE.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 + ) ) ; END IF; @@ -403,81 +674,6 @@ BEGIN -- Calculated fields - -- Permissions - IF a_debug = 1 THEN - SELECT - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ; - END IF; - - CALL fetchmetrics.p_dog_calc_user_access( - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ); - - SELECT - IFNULL(CALC_USER_T.has_access, 0) - INTO - v_can_view - FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T - WHERE CALC_USER_T.GUID = a_guid - LIMIT 1 - ; - - IF a_debug = 1 THEN - SELECT v_can_view; - END IF; - - IF (v_can_view = 0) THEN - DELETE t_ME - FROM tmp_Msg_Error_Calc_Button_Shape t_ME - WHERE t_ME.id_type <> v_id_type_error_no_permission - ; - INSERT INTO tmp_Msg_Error_Calc_Button_Shape ( - id_type - , code - , msg - ) - VALUES ( - v_id_type_error_no_permission - , v_code_type_error_no_permission - , 'You do not have permission to view Dogs and Button_Shapes.' - ) - ; - END IF; - - CALL fetchmetrics.p_dog_clear_calc_user_access( - a_guid - , 0 -- a_debug - ); - IF a_debug = 1 THEN SELECT 'Before non-permitted data deletion'; SELECT * FROM tmp_Button_Shape_Calc_Button_Shape; @@ -512,17 +708,17 @@ BEGIN ) SELECT a_guid - , t_BUTTON_SHAPES.id_button_shape - , BUTTON_SHAPES.code - , BUTTON_SHAPES.name - , BUTTON_SHAPES.notes - , BUTTON_SHAPES.active + , t_BUTTON_SHAPE.id_button_shape + , BUTTON_SHAPE.code + , BUTTON_SHAPE.name + , BUTTON_SHAPE.notes + , BUTTON_SHAPE.active - , t_BUTTON_SHAPES.does_meet_id_filters - , t_BUTTON_SHAPES.does_meet_non_id_filters - FROM fetchmetrics.DOG_Button_Shape BUTTON_SHAPES - INNER JOIN tmp_Button_Shape_Calc_Button_Shape t_BUTTON_SHAPES ON BUTTON_SHAPES.id_button_shape = t_BUTTON_SHAPES.id_button_shape - ORDER BY BUTTON_SHAPES.name + , t_BUTTON_SHAPE.does_meet_id_filters + , t_BUTTON_SHAPE.does_meet_non_id_filters + FROM fetchmetrics.DOG_Button_Shape BUTTON_SHAPE + INNER JOIN tmp_Button_Shape_Calc_Button_Shape t_BUTTON_SHAPE ON BUTTON_SHAPE.id_button_shape = t_BUTTON_SHAPE.id_button_shape + ORDER BY BUTTON_SHAPE.name ; COMMIT; @@ -546,14 +742,13 @@ BEGIN IF a_debug = 1 AND v_can_view = 1 THEN SELECT * FROM tmp_Button_Shape_Calc_Button_Shape; END IF; - - CALL fetchmetrics.p_dog_clear_calc_dog ( a_guid, 0 ); DROP TEMPORARY TABLE IF EXISTS tmp_Split_Notes_Calc_Button_Shape; DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name_Calc_Button_Shape; DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_Button_Shape; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_Button_Shape; DROP TEMPORARY TABLE IF EXISTS tmp_Button_Shape_Calc_Button_Shape; + DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_Button_Shape; IF a_debug = 1 THEN CALL fetchmetrics.p_core_debug_timing_reporting ( v_time_start ); @@ -564,6 +759,9 @@ DELIMITER ; /* +SELECT * +FROM fetchmetrics.DOG_Button_Shape +; CALL fetchmetrics.p_dog_calc_button_shape ( 'gripe ' -- a_guid @@ -573,6 +771,11 @@ CALL fetchmetrics.p_dog_calc_button_shape ( , '' -- a_ids_button_shape , '' -- a_names_button_shape , '' -- a_notes_button_shape + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , '' -- a_names_user + , '' -- a_emails_user , 0 -- a_require_all_id_search_filters_met , 0 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met diff --git a/static/MySQL/71220_p_dog_get_many_button_shape.sql b/static/MySQL/71220_p_dog_get_many_button_shape.sql index 85b37c1..41eed59 100644 --- a/static/MySQL/71220_p_dog_get_many_button_shape.sql +++ b/static/MySQL/71220_p_dog_get_many_button_shape.sql @@ -11,6 +11,11 @@ CREATE PROCEDURE fetchmetrics.p_dog_get_many_button_shape ( , IN a_ids_button_shape TEXT , IN a_names_button_shape TEXT , IN a_notes_button_shape TEXT + , IN a_get_all_user BIT + , IN a_get_inactive_user BIT + , IN a_ids_user TEXT + , IN a_names_user TEXT + , IN a_emails_user TEXT , IN a_require_all_id_search_filters_met BIT , IN a_require_any_id_search_filters_met BIT , IN a_require_all_non_id_search_filters_met BIT @@ -27,6 +32,9 @@ BEGIN DECLARE v_id_permission_dog_view INT; DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; + DECLARE v_is_super_user BIT; + DECLARE v_priority_access_level_none INT; + DECLARE v_priority_access_level_view INT; DECLARE v_time_start TIMESTAMP(6); DECLARE exit handler for SQLEXCEPTION @@ -84,7 +92,9 @@ BEGIN SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1); - + SET v_priority_access_level_none := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'NONE' LIMIT 1); + SET v_priority_access_level_view := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.id_access_level = v_id_access_level_view); + SET a_id_user := IFNULL(a_id_user, 0); /* SET a_get_all_button_shape := IFNULL(a_get_all_button_shape, 0); @@ -107,6 +117,11 @@ BEGIN , a_ids_button_shape , a_names_button_shape , a_notes_button_shape + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met , a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met @@ -233,6 +248,11 @@ BEGIN , a_ids_button_shape -- a_ids_button_shape , a_names_button_shape -- a_names_button_shape , a_notes_button_shape -- a_notes_button_shape + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -250,6 +270,11 @@ BEGIN , a_ids_button_shape -- a_ids_button_shape , a_names_button_shape -- a_names_button_shape , a_notes_button_shape -- a_notes_button_shape + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -361,6 +386,11 @@ CALL fetchmetrics.p_dog_get_many_button_shape ( , '' -- a_ids_button_shape , '' -- a_names_button_shape , '' -- a_notes_button_shape + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , '' -- a_names_user + , '' -- a_emails_user , 1 -- a_require_all_id_search_filters_met , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met @@ -376,6 +406,11 @@ CALL fetchmetrics.p_dog_get_many_button_shape ( , '' -- a_ids_button_shape , 'pat,point' -- a_names_button_shape , 'pat,point' -- a_notes_button_shape + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , 'pat,point' -- a_names_user + , 'pat,point' -- a_emails_user , 1 -- a_require_all_id_search_filters_met , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met diff --git a/static/MySQL/71228_p_dog_calc_image.sql b/static/MySQL/71228_p_dog_calc_image.sql index 07e3fc2..d5966ee 100644 --- a/static/MySQL/71228_p_dog_calc_image.sql +++ b/static/MySQL/71228_p_dog_calc_image.sql @@ -19,6 +19,11 @@ CREATE PROCEDURE fetchmetrics.p_dog_calc_image ( , IN a_get_inactive_image BIT , IN a_ids_image TEXT , IN a_names_image TEXT + , IN a_get_all_user BIT + , IN a_get_inactive_user BIT + , IN a_ids_user TEXT + , IN a_names_user TEXT + , IN a_emails_user TEXT , IN a_require_all_id_search_filters_met BIT , IN a_require_any_id_search_filters_met BIT , IN a_require_all_non_id_search_filters_met BIT @@ -36,9 +41,14 @@ BEGIN DECLARE v_has_filter_image_name BIT; DECLARE v_id_access_level_view INT; DECLARE v_id_minimum INT; + DECLARE v_id_permission_command_view INT; DECLARE v_id_permission_dog_view INT; DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; + DECLARE v_ids_permission_required VARCHAR(200); + DECLARE v_is_super_user BIT; + DECLARE v_priority_access_level_none INT; + DECLARE v_priority_access_level_view INT; DECLARE v_time_start TIMESTAMP(6); DECLARE exit handler for SQLEXCEPTION @@ -93,10 +103,17 @@ BEGIN SET v_code_type_error_no_permission := 'NO_PERMISSION'; SET v_id_type_error_bad_data := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_bad_data LIMIT 1); SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); + SET v_id_permission_command_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'COMMAND_VIEW' LIMIT 1); SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1); - - + SET v_ids_permission_required := (SELECT CONCAT( + CONVERT(v_id_permission_dog_view, CHAR) + , ',' + , CONVERT(v_id_permission_command_view, CHAR) + )); + SET v_priority_access_level_none := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'NONE' LIMIT 1); + SET v_priority_access_level_view := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.id_access_level = v_id_access_level_view); + CALL fetchmetrics.p_core_validate_guid ( a_guid ); SET a_id_user := IFNULL(a_id_user, 0); @@ -135,6 +152,11 @@ BEGIN , a_get_inactive_image , a_ids_image , a_names_image + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met , a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met @@ -146,7 +168,9 @@ BEGIN SELECT v_id_type_error_bad_data , v_id_type_error_no_permission + , v_id_permission_command_view , v_id_permission_dog_view + , v_ids_permission_required , v_time_start ; END IF; @@ -157,6 +181,25 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp_Image_Calc_Image; DROP TEMPORARY TABLE IF EXISTS tmp_Dog_Calc_Image; DROP TEMPORARY TABLE IF EXISTS tmp_File_Type_Calc_Image; + DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_Image; + + CREATE TEMPORARY TABLE tmp_Calc_User_Access_Calc_Image ( + id_temp INT PRIMARY KEY AUTO_INCREMENT NOT NULL + , id_user INT + , id_role INT + , id_permission_required INT NOT NULL + , priority_access_level_required INT NOT NULL + , is_super_user BIT + , priority_access_level_user INT + , has_access BIT + , can_view BIT + , can_edit BIT + , can_admin BIT + , active BIT + + , does_meet_id_filters BIT + , does_meet_non_id_filters BIT + ); CREATE TEMPORARY TABLE tmp_File_Type_Calc_Image ( id_file_type INT NOT NULL @@ -166,10 +209,6 @@ BEGIN CREATE TEMPORARY TABLE tmp_Dog_Calc_Image ( id_dog INT NOT NULL - , name VARCHAR(250) - , appearance VARCHAR(1000) - , mass_kg DECIMAL(7, 3) - , notes TEXT , active BIT , does_meet_id_filters BIT NOT NULL @@ -179,6 +218,8 @@ BEGIN CREATE TEMPORARY TABLE tmp_Image_Calc_Image ( id_image INT NOT NULL , id_file_type INT NOT NULL + , exists_valid_link BIT NOT NULL + , id_user INT , does_meet_id_filters BIT NOT NULL , does_meet_non_id_filters BIT NOT NULL ); @@ -207,6 +248,172 @@ BEGIN SET v_has_filter_image_id = CASE WHEN a_ids_image <> '' THEN 1 ELSE 0 END; SET v_has_filter_image_name = CASE WHEN a_names_image <> '' THEN 1 ELSE 0 END; + -- Permissions + IF a_debug = 1 THEN + SELECT + a_guid -- a_guid + , 0 -- get_all_user + , 0 -- get_inactive_user + , a_id_user -- ids_user + , '' -- a_auth0_ids_user + , '' -- a_names_user + , '' -- a_emails_user + , 1 -- a_require_all_id_search_filters_met + , 1 -- a_require_any_id_search_filters_met + , 0 -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL fetchmetrics.p_dog_calc_user_access( + a_guid -- a_guid + , 0 -- get_all_user + , 0 -- get_inactive_user + , a_id_user -- ids_user + , '' -- a_auth0_ids_user + , '' -- a_names_user + , '' -- a_emails_user + , 1 -- a_require_all_id_search_filters_met + , 1 -- a_require_any_id_search_filters_met + , 0 -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ); + + SELECT + IFNULL(CALC_USER_T.has_access, 0) + , IFNULL(CALC_USER_T.is_super_user, 0) + INTO + v_can_view + , v_is_super_user + FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T + WHERE CALC_USER_T.GUID = a_guid + LIMIT 1 + ; + + IF a_debug = 1 THEN + SELECT + v_can_view + , v_is_super_user + ; + END IF; + + IF (v_can_view = 0) THEN + DELETE t_ME + FROM tmp_Msg_Error_Calc_Image t_ME + WHERE t_ME.id_type <> v_id_type_error_no_permission + ; + INSERT INTO tmp_Msg_Error_Calc_Image ( + id_type + , code + , msg + ) + VALUES ( + v_id_type_error_no_permission + , v_code_type_error_no_permission + , 'You do not have permission to view Dogs and Images.' + ) + ; + END IF; + + CALL fetchmetrics.p_dog_clear_calc_user_access( + a_guid + , 0 -- a_debug + ); + + -- Users + IF a_debug = 1 THEN + SELECT + a_guid -- guid + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , '' -- a_auth0_ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user + , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met + , 0 -- a_require_any_id_search_filters_met + , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL fetchmetrics.p_dog_calc_user_access( + a_guid-- guid + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , '' -- a_auth0_ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user + , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met + , 0 -- a_require_any_id_search_filters_met + , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ); + + INSERT INTO tmp_Calc_User_Access_Calc_Image ( + id_user + , id_role + , id_permission_required + , priority_access_level_required + , is_super_user + , priority_access_level_user + , has_access + , can_view + , can_edit + , can_admin + , active + , does_meet_id_filters + , does_meet_non_id_filters + ) + SELECT + CALC_USER_T.id_user + , CALC_USER_T.id_role + , CALC_USER_T.id_permission_required + , CALC_USER_T.priority_access_level_required + , CALC_USER_T.is_super_user + , CALC_USER_T.priority_access_level_user + , CALC_USER_T.has_access + , CALC_USER_T.can_view + , CALC_USER_T.can_edit + , CALC_USER_T.can_admin + , CALC_USER_T.active + , CALC_USER_T.does_meet_id_filters + , CALC_USER_T.does_meet_non_id_filters + FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T + WHERE CALC_USER_T.GUID = a_guid + ; + + IF a_debug = 1 THEN + SELECT 'After get many user'; + SELECT * FROM tmp_Calc_User_Access_Calc_Image; + SELECT COUNT(*) AS Count_Errors FROM tmp_Msg_Error_Calc_Image t_ERROR; + SELECT * FROM tmp_Msg_Error_Calc_Image t_ERROR; + END IF; + + CALL fetchmetrics.p_dog_clear_calc_user_access( + a_guid + , 0 -- a_debug + ); + + + -- File Types IF v_has_filter_file_type_id = 1 THEN CALL fetchmetrics.p_core_split(a_guid, a_ids_file_type, ',', a_debug); @@ -286,72 +493,6 @@ BEGIN ELSEIF EXISTS () */ ELSE - IF a_debug = 1 THEN - SELECT 'File_Type Filters'; - WITH - File_Type_Id_Filter AS ( - SELECT FILE_TYPES.id_file_type - FROM tmp_Split_Id_Calc_Image t_SPLIT_ID - INNER JOIN fetchmetrics.CORE_File_Type FILE_TYPES ON t_SPLIT_ID.as_int = FILE_TYPES.id_file_type - ) - , File_Type_Name_Filter AS ( - SELECT FILE_TYPES.id_file_type - FROM tmp_Split_Name_Calc_Image t_SPLIT_NAME - INNER JOIN fetchmetrics.CORE_File_Type FILE_TYPES ON FILE_TYPES.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') - WHERE NULLIF(t_SPLIT_NAME.substring, '') IS NOT NULL - ) - , File_Type_Filters AS ( - SELECT - FILE_TYPES_COMBINED.id_file_type - , MAX(FILE_TYPES_COMBINED.does_meet_id_filter) AS does_meet_id_filter - , MAX(FILE_TYPES_COMBINED.does_meet_name_filter) AS does_meet_name_filter - FROM ( - SELECT - FILE_TYPES_ID_FILTER.id_file_type - , 1 AS does_meet_id_filter - , 0 AS does_meet_name_filter - FROM File_Type_Id_Filter FILE_TYPES_ID_FILTER - UNION - SELECT - FILE_TYPES_NAME_FILTER.id_file_type - , 0 AS does_meet_id_filter - , 1 AS does_meet_name_filter - FROM File_Type_Name_Filter FILE_TYPES_NAME_FILTER - ) FILE_TYPES_COMBINED - GROUP BY FILE_TYPES_COMBINED.id_file_type - ) - SELECT - FILE_TYPES.id_file_type - , CASE WHEN - v_has_filter_file_type_id = 0 - OR FILE_TYPES_FILTERS.does_meet_id_filter = 1 - THEN 1 ELSE 0 END AS does_meet_id_filters - , CASE WHEN - ( - v_has_filter_file_type_name = 0 - ) - OR FILE_TYPES_FILTERS.does_meet_name_filter = 1 - THEN 1 ELSE 0 END AS does_meet_non_id_filters - FROM fetchmetrics.CORE_File_Type FILE_TYPES - LEFT JOIN File_Type_Filters FILE_TYPES_FILTERS ON FILE_TYPES.id_file_type = FILE_TYPES_FILTERS.id_file_type - WHERE - ( - a_get_all_file_type = 1 - OR ( - v_has_filter_file_type_id = 1 - AND FILE_TYPES_FILTERS.does_meet_id_filter = 1 - ) - OR ( - v_has_filter_file_type_name = 1 - AND FILE_TYPES_FILTERS.does_meet_name_filter = 1 - ) - ) - AND ( - a_get_inactive_file_type = 1 - OR FILE_TYPES.active = 1 - ) - ; - END IF; INSERT INTO tmp_File_Type_Calc_Image ( id_file_type , does_meet_id_filters @@ -439,6 +580,11 @@ BEGIN , a_get_inactive_dog -- a_get_inactive_dog , a_ids_dog -- a_ids_dog , a_names_dog -- a_names_dog + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , 0 -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -448,13 +594,18 @@ BEGIN ; END IF; - CALL fetchmetrics.p_dog_calc_dog( + CALL fetchmetrics.p_dog_calc_dog ( a_guid -- a_guid , a_id_user -- a_id_user , a_get_all_dog -- a_get_all_dog , a_get_inactive_dog -- a_get_inactive_dog , a_ids_dog -- a_ids_dog , a_names_dog -- a_names_dog + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , 0 -- a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -465,10 +616,6 @@ BEGIN INSERT INTO tmp_Dog_Calc_Image ( id_dog - , name - , appearance - , mass_kg - , notes , active , does_meet_id_filters @@ -476,10 +623,6 @@ BEGIN ) SELECT DOG_T.id_dog - , DOG_T.name - , DOG_T.appearance - , DOG_T.mass_kg - , DOG_T.notes , DOG_T.active , DOG_T.does_meet_id_filters @@ -575,6 +718,9 @@ BEGIN ELSE INSERT INTO tmp_Image_Calc_Image ( id_image + , id_file_type + , exists_valid_link + , id_user , does_meet_id_filters , does_meet_non_id_filters ) @@ -612,8 +758,55 @@ BEGIN ) IMAGES_COMBINED GROUP BY IMAGES_COMBINED.id_image ) + , Image_Access AS ( + SELECT + IMAGES.id_image + , CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END AS exists_valid_link + , ROW_NUMBER() OVER ( + PARTITION BY IMAGES.id_image + ORDER BY + CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END DESC + , t_USER.does_meet_id_filters DESC + , t_USER.does_meet_non_id_filters DESC + ) AS index_link_in_image + , t_USER.id_user + FROM fetchmetrics.DOG_Image IMAGES + LEFT JOIN fetchmetrics.DOG_Image_User_Link IMAGES_USER_LINK + ON IMAGES.id_image = IMAGES_USER_LINK.id_image + AND ( + ( + a_get_inactive_image = 1 + AND a_get_inactive_user = 1 + ) + OR IMAGES_USER_LINK.active = 1 + ) + LEFT JOIN tmp_Calc_User_Access_Calc_Image t_USER + ON IMAGES_USER_LINK.id_user = t_USER.id_user + AND ( + a_get_inactive_user = 1 + OR t_USER.active = 1 + ) + LEFT JOIN fetchmetrics.DOG_Access_Level ACCESS_LEVEL + ON IMAGES_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level + AND ACCESS_LEVEL.active = 1 + ) SELECT IMAGES.id_image + , IMAGES.id_file_type + , IFNULL(IMAGES_ACCESS.exists_valid_link, 0) AS exists_valid_link + , IMAGES_ACCESS.id_user , CASE WHEN v_has_filter_image_id = 0 OR IFNULL(IMAGES_FILTERS.does_meet_id_filter, 0) = 1 @@ -628,6 +821,9 @@ BEGIN INNER JOIN tmp_File_Type_Calc_Image t_FILE_TYPE ON IMAGES.id_file_type = t_FILE_TYPE.id_file_type LEFT JOIN tmp_Dog_Calc_Image t_DOG ON IMAGES.id_dog = t_DOG.id_dog LEFT JOIN Image_Filters IMAGES_FILTERS ON IMAGES.id_image = IMAGES_FILTERS.id_image + LEFT JOIN Image_Access IMAGES_ACCESS + ON IMAGES.id_image = IMAGES_ACCESS.id_image + AND IMAGES_ACCESS.index_link_in_image = 1 WHERE ( a_get_all_image = 1 @@ -640,6 +836,7 @@ BEGIN AND IMAGES_FILTERS.does_meet_name_filter = 1 ) ) + AND IFNULL(IMAGES_ACCESS.exists_valid_link, 0) = 1 AND ( a_get_inactive_image = 1 OR IMAGES.active = 1 @@ -661,12 +858,17 @@ BEGIN DELETE t_IMAGES FROM tmp_Image_Calc_Image t_IMAGES LEFT JOIN tmp_File_Type_Calc_Image t_FILE_TYPE ON t_IMAGES.id_file_type = t_FILE_TYPE.id_file_type + LEFT JOIN tmp_Calc_User_Access_Calc_Image t_USER ON t_IMAGES.id_user = t_USER.id_user WHERE ( a_require_all_id_search_filters_met = 1 AND ( t_IMAGES.does_meet_id_filters = 0 OR IFNULL(t_FILE_TYPE.does_meet_id_filters, 0) = 0 + OR ( + t_IMAGES.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 + ) ) ) OR ( @@ -674,17 +876,29 @@ BEGIN AND ( t_IMAGES.does_meet_non_id_filters = 0 OR IFNULL(t_FILE_TYPE.does_meet_non_id_filters, 0) = 0 + OR ( + t_IMAGES.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 + ) ) ) OR ( a_require_any_id_search_filters_met = 1 AND t_IMAGES.does_meet_id_filters = 0 AND IFNULL(t_FILE_TYPE.does_meet_id_filters, 0) = 0 + AND ( + t_IMAGES.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 + ) ) OR ( a_require_any_non_id_search_filters_met = 1 AND t_IMAGES.does_meet_non_id_filters = 0 AND IFNULL(t_FILE_TYPE.does_meet_non_id_filters, 0) = 0 + AND ( + t_IMAGES.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 + ) ) ; END IF; @@ -696,80 +910,6 @@ BEGIN -- Calculated fields - -- Permissions - IF a_debug = 1 THEN - SELECT - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ; - END IF; - - CALL fetchmetrics.p_dog_calc_user_access( - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ); - - SELECT - IFNULL(CALC_USER_T.has_access, 0) - INTO - v_can_view - FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T - WHERE CALC_USER_T.GUID = a_guid - LIMIT 1 - ; - - IF a_debug = 1 THEN - SELECT v_can_view; - END IF; - - IF (v_can_view = 0) THEN - DELETE t_ME - FROM tmp_Msg_Error_Calc_Image t_ME - WHERE t_ME.id_type <> v_id_type_error_no_permission - ; - INSERT INTO tmp_Msg_Error_Calc_Image ( - id_type - , code - , msg - ) - VALUES ( - v_id_type_error_no_permission - , v_code_type_error_no_permission - , 'You do not have permission to view Dogs and Images.' - ) - ; - END IF; - - CALL fetchmetrics.p_dog_clear_calc_user_access( - a_guid - , 0 -- a_debug - ); IF a_debug = 1 THEN SELECT 'Before non-permitted data deletion'; @@ -841,8 +981,11 @@ BEGIN IF a_debug = 1 AND v_can_view = 1 THEN SELECT * FROM tmp_Image_Calc_Image; END IF; - - CALL fetchmetrics.p_dog_clear_calc_dog ( a_guid, 0 ); + + CALL fetchmetrics.p_dog_clear_calc_dog ( + a_guid -- a_guid + , 0 -- debug + ); DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name_Calc_Image; DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_Image; @@ -850,6 +993,7 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp_Image_Calc_Image; DROP TEMPORARY TABLE IF EXISTS tmp_Dog_Calc_Image; DROP TEMPORARY TABLE IF EXISTS tmp_File_Type_Calc_Image; + DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_Image; IF a_debug = 1 THEN CALL fetchmetrics.p_core_debug_timing_reporting ( v_time_start ); @@ -860,6 +1004,12 @@ DELIMITER ; /* +SELECT * +FROM fetchmetrics.DOG_Image +; +SELECT * +FROM fetchmetrics.DOG_Image_User_Link +; CALL fetchmetrics.p_dog_calc_image ( 'grope ' -- a_guid @@ -876,6 +1026,11 @@ CALL fetchmetrics.p_dog_calc_image ( , 0 -- a_get_inactive_image , '' -- a_ids_image , '' -- a_names_image + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , '' -- a_names_user + , '' -- a_emails_user , 0 -- a_require_all_id_search_filters_met , 0 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met diff --git a/static/MySQL/71228_p_dog_get_many_image.sql b/static/MySQL/71228_p_dog_get_many_image.sql index 50757ea..8844964 100644 --- a/static/MySQL/71228_p_dog_get_many_image.sql +++ b/static/MySQL/71228_p_dog_get_many_image.sql @@ -18,6 +18,11 @@ CREATE PROCEDURE fetchmetrics.p_dog_get_many_image ( , IN a_get_inactive_image BIT , IN a_ids_image TEXT , IN a_names_image TEXT + , IN a_get_all_user BIT + , IN a_get_inactive_user BIT + , IN a_ids_user TEXT + , IN a_names_user TEXT + , IN a_emails_user TEXT , IN a_require_all_id_search_filters_met BIT , IN a_require_any_id_search_filters_met BIT , IN a_require_all_non_id_search_filters_met BIT @@ -32,9 +37,14 @@ BEGIN DECLARE v_guid BINARY(36); DECLARE v_id_access_level_view INT; DECLARE v_id_minimum INT; + DECLARE v_id_permission_command_view INT; DECLARE v_id_permission_dog_view INT; DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; + DECLARE v_ids_permission_required VARCHAR(200); + DECLARE v_is_super_user BIT; + DECLARE v_priority_access_level_none INT; + DECLARE v_priority_access_level_view INT; DECLARE v_time_start TIMESTAMP(6); DECLARE exit handler for SQLEXCEPTION @@ -90,9 +100,17 @@ BEGIN SET v_code_type_error_no_permission := 'NO_PERMISSION'; SET v_id_type_error_bad_data := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_bad_data LIMIT 1); SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); + SET v_id_permission_command_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'COMMAND_VIEW' LIMIT 1); SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1); - + SET v_ids_permission_required := (SELECT CONCAT( + CONVERT(v_id_permission_dog_view, CHAR) + , ',' + , CONVERT(v_id_permission_command_view, CHAR) + )); + SET v_priority_access_level_none := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'NONE' LIMIT 1); + SET v_priority_access_level_view := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.id_access_level = v_id_access_level_view); + SET a_id_user := IFNULL(a_id_user, 0); /* SET a_get_all_file_type := IFNULL(a_get_all_file_type, 0); @@ -142,7 +160,9 @@ BEGIN v_id_type_error_bad_data , v_id_type_error_no_permission , v_guid + , v_id_permission_command_view , v_id_permission_dog_view + , v_ids_permission_required , v_time_start ; END IF; @@ -183,7 +203,7 @@ BEGIN , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission + , v_ids_permission_required -- ids_permission , v_id_access_level_view -- ids_access_level , 0 -- a_show_errors , 0 -- a_debug @@ -202,7 +222,7 @@ BEGIN , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission + , v_ids_permission_required -- ids_permission , v_id_access_level_view -- ids_access_level , 0 -- a_show_errors , 0 -- a_debug @@ -210,15 +230,20 @@ BEGIN SELECT IFNULL(CALC_USER_T.has_access, 0) + , IFNULL(CALC_USER_T.is_super_user, 0) INTO v_can_view - FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T - WHERE CALC_USER_T.GUID = v_guid + , v_is_super_user + FROM demo.DOG_Calc_User_Access_Temp CALC_USER_T + WHERE CALC_USER_T.GUID = V_GUID LIMIT 1 ; IF a_debug = 1 THEN - SELECT v_can_view; + SELECT + v_can_view + , v_is_super_user + ; SELECT COUNT(*) AS Count_Errors FROM tmp_Msg_Error t_ERROR; SELECT * FROM tmp_Msg_Error t_ERROR; END IF; @@ -265,6 +290,11 @@ BEGIN , a_get_inactive_image -- a_get_inactive_image , a_ids_image -- a_ids_image , a_names_image -- a_names_image + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -289,6 +319,11 @@ BEGIN , a_get_inactive_image -- a_get_inactive_image , a_ids_image -- a_ids_image , a_names_image -- a_names_image + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -416,6 +451,11 @@ CALL fetchmetrics.p_dog_get_many_image ( , 0 -- a_get_inactive_image , '' -- a_ids_image , '' -- a_names_image + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , '' -- a_names_user + , '' -- a_emails_user , 1 -- a_require_all_id_search_filters_met , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met @@ -439,6 +479,11 @@ CALL fetchmetrics.p_dog_get_many_image ( , 0 -- a_get_inactive_image , '' -- a_ids_image , 'pat,point' -- a_names_image + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , 'pat,point' -- a_names_user + , 'pat,point' -- a_emails_user , 1 -- a_require_all_id_search_filters_met , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met diff --git a/static/MySQL/71312_p_dog_calc_distraction_type.sql b/static/MySQL/71312_p_dog_calc_distraction_type.sql index f8b97a8..4b64e1e 100644 --- a/static/MySQL/71312_p_dog_calc_distraction_type.sql +++ b/static/MySQL/71312_p_dog_calc_distraction_type.sql @@ -11,6 +11,11 @@ CREATE PROCEDURE fetchmetrics.p_dog_calc_distraction_type ( , IN a_get_inactive_distraction_type BIT , IN a_ids_distraction_type TEXT , IN a_names_distraction_type TEXT + , IN a_get_all_user BIT + , IN a_get_inactive_user BIT + , IN a_ids_user TEXT + , IN a_names_user TEXT + , IN a_emails_user TEXT , IN a_require_all_id_search_filters_met BIT , IN a_require_any_id_search_filters_met BIT , IN a_require_all_non_id_search_filters_met BIT @@ -29,6 +34,9 @@ BEGIN DECLARE v_id_permission_dog_view INT; DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; + DECLARE v_is_super_user BIT; + DECLARE v_priority_access_level_none INT; + DECLARE v_priority_access_level_view INT; DECLARE v_time_start TIMESTAMP(6); DECLARE exit handler for SQLEXCEPTION @@ -85,7 +93,9 @@ BEGIN SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1); - + SET v_priority_access_level_none := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'NONE' LIMIT 1); + SET v_priority_access_level_view := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.id_access_level = v_id_access_level_view); + CALL fetchmetrics.p_core_validate_guid ( a_guid ); @@ -109,6 +119,11 @@ BEGIN , a_get_inactive_distraction_type , a_ids_distraction_type , a_names_distraction_type + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met , a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met @@ -129,9 +144,30 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_Distraction_Type; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_Distraction_Type; DROP TEMPORARY TABLE IF EXISTS tmp_Distraction_Type_Calc_Distraction_Type; + DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_Distraction_Type; + + CREATE TEMPORARY TABLE tmp_Calc_User_Access_Calc_Distraction_Type ( + id_temp INT PRIMARY KEY AUTO_INCREMENT NOT NULL + , id_user INT + , id_role INT + , id_permission_required INT NOT NULL + , priority_access_level_required INT NOT NULL + , is_super_user BIT + , priority_access_level_user INT + , has_access BIT + , can_view BIT + , can_edit BIT + , can_admin BIT + , active BIT + + , does_meet_id_filters BIT + , does_meet_non_id_filters BIT + ); CREATE TEMPORARY TABLE tmp_Distraction_Type_Calc_Distraction_Type ( id_type INT NOT NULL + , exists_valid_link BIT NOT NULL + , id_user INT , does_meet_id_filters BIT NOT NULL , does_meet_non_id_filters BIT NOT NULL ); @@ -158,6 +194,169 @@ BEGIN SET v_has_filter_distraction_type_id = CASE WHEN a_ids_distraction_type <> '' THEN 1 ELSE 0 END; SET v_has_filter_distraction_type_name = CASE WHEN a_names_distraction_type <> '' THEN 1 ELSE 0 END; + -- Permissions + IF a_debug = 1 THEN + SELECT + a_guid -- a_guid + , 0 -- get_all_user + , 0 -- get_inactive_user + , a_id_user -- ids_user + , '' -- a_auth0_ids_user + , '' -- a_names_user + , '' -- a_emails_user + , 1 -- a_require_all_id_search_filters_met + , 1 -- a_require_any_id_search_filters_met + , 0 -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_id_permission_dog_view -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL fetchmetrics.p_dog_calc_user_access( + a_guid -- a_guid + , 0 -- get_all_user + , 0 -- get_inactive_user + , a_id_user -- ids_user + , '' -- a_auth0_ids_user + , '' -- a_names_user + , '' -- a_emails_user + , 1 -- a_require_all_id_search_filters_met + , 1 -- a_require_any_id_search_filters_met + , 0 -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_id_permission_dog_view -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ); + + SELECT + IFNULL(CALC_USER_T.has_access, 0) + , IFNULL(CALC_USER_T.is_super_user, 0) + INTO + v_can_view + , v_is_super_user + FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T + WHERE CALC_USER_T.guid = a_guid + LIMIT 1 + ; + + IF a_debug = 1 THEN + SELECT + v_can_view + , v_is_super_user + ; + END IF; + + IF (v_can_view = 0) THEN + DELETE t_ME + FROM tmp_Msg_Error_Calc_Distraction_Type t_ME + WHERE t_ME.id_type <> v_id_type_error_no_permission + ; + INSERT INTO tmp_Msg_Error_Calc_Distraction_Type ( + id_type + , code + , msg + ) + VALUES ( + v_id_type_error_no_permission + , v_code_type_error_no_permission + , 'You do not have permission to view Dogs and Distraction_Types.' + ) + ; + END IF; + + CALL fetchmetrics.p_dog_clear_calc_user_access( + a_guid + , 0 -- a_debug + ); + + -- Users + IF a_debug = 1 THEN + SELECT + a_guid -- guid + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , '' -- a_auth0_ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user + , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met + , 0 -- a_require_any_id_search_filters_met + , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_id_permission_dog_view -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL fetchmetrics.p_dog_calc_user_access( + a_guid-- guid + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , '' -- a_auth0_ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user + , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met + , 0 -- a_require_any_id_search_filters_met + , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_id_permission_dog_view -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ); + + INSERT INTO tmp_Calc_User_Access_Calc_Distraction_Type ( + id_user + , id_role + , id_permission_required + , priority_access_level_required + , is_super_user + , priority_access_level_user + , has_access + , can_view + , can_edit + , can_admin + , active + , does_meet_id_filters + , does_meet_non_id_filters + ) + SELECT + CALC_USER_T.id_user + , CALC_USER_T.id_role + , CALC_USER_T.id_permission_required + , CALC_USER_T.priority_access_level_required + , CALC_USER_T.is_super_user + , CALC_USER_T.priority_access_level_user + , CALC_USER_T.has_access + , CALC_USER_T.can_view + , CALC_USER_T.can_edit + , CALC_USER_T.can_admin + , CALC_USER_T.active + , CALC_USER_T.does_meet_id_filters + , CALC_USER_T.does_meet_non_id_filters + FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T + WHERE CALC_USER_T.GUID = a_guid + ; + + IF a_debug = 1 THEN + SELECT 'After get many user'; + SELECT * FROM tmp_Calc_User_Access_Calc_Distraction_Type; + END IF; + + CALL fetchmetrics.p_dog_clear_calc_user_access( + a_guid + , 0 -- a_debug + ); + + -- Distraction_Types IF v_has_filter_distraction_type_id = 1 THEN CALL fetchmetrics.p_core_split(a_guid, a_ids_distraction_type, ',', a_debug); @@ -205,12 +404,12 @@ BEGIN IF EXISTS ( SELECT * FROM tmp_Split_Id_Calc_Distraction_Type t_SPLIT_ID - LEFT JOIN fetchmetrics.DOG_Distraction_Type DISTRACTION_TYPES ON t_SPLIT_ID.as_int = DISTRACTION_TYPES.id_type + LEFT JOIN fetchmetrics.DOG_Distraction_Type DISTRACTION_TYPE ON t_SPLIT_ID.as_int = DISTRACTION_TYPE.id_type WHERE ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(DISTRACTION_TYPES.id_type) + OR ISNULL(DISTRACTION_TYPE.id_type) OR ( - DISTRACTION_TYPES.active = 0 + DISTRACTION_TYPE.active = 0 AND a_get_inactive_distraction_type = 0 ) ) THEN @@ -224,12 +423,12 @@ BEGIN , v_code_type_error_bad_data , CONCAT('Invalid or inactive Distraction_Type IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT_ID.substring SEPARATOR ', '), 'NULL')) FROM tmp_Split_Id_Calc_Distraction_Type t_SPLIT_ID - LEFT JOIN fetchmetrics.DOG_Distraction_Type DISTRACTION_TYPES ON t_SPLIT_ID.as_int = DISTRACTION_TYPES.id_type + LEFT JOIN fetchmetrics.DOG_Distraction_Type DISTRACTION_TYPE ON t_SPLIT_ID.as_int = DISTRACTION_TYPE.id_type WHERE ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(DISTRACTION_TYPES.id_type) + OR ISNULL(DISTRACTION_TYPE.id_type) OR ( - DISTRACTION_TYPES.active = 0 + DISTRACTION_TYPE.active = 0 AND a_get_inactive_distraction_type = 0 ) ; @@ -239,70 +438,122 @@ BEGIN ELSE INSERT INTO tmp_Distraction_Type_Calc_Distraction_Type ( id_type + , exists_valid_link + , id_user , does_meet_id_filters , does_meet_non_id_filters ) WITH Distraction_Type_Id_Filter AS ( - SELECT DISTRACTION_TYPES.id_type + SELECT DISTRACTION_TYPE.id_type FROM tmp_Split_Id_Calc_Distraction_Type t_SPLIT_ID - INNER JOIN fetchmetrics.DOG_Distraction_Type DISTRACTION_TYPES ON t_SPLIT_ID.as_int = DISTRACTION_TYPES.id_type + INNER JOIN fetchmetrics.DOG_Distraction_Type DISTRACTION_TYPE ON t_SPLIT_ID.as_int = DISTRACTION_TYPE.id_type ) , Distraction_Type_Name_Filter AS ( - SELECT DISTRACTION_TYPES.id_type + SELECT DISTRACTION_TYPE.id_type FROM tmp_Split_Name_Calc_Distraction_Type t_SPLIT_NAME - INNER JOIN fetchmetrics.DOG_Distraction_Type DISTRACTION_TYPES ON DISTRACTION_TYPES.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') + INNER JOIN fetchmetrics.DOG_Distraction_Type DISTRACTION_TYPE ON DISTRACTION_TYPE.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') WHERE NULLIF(t_SPLIT_NAME.substring, '') IS NOT NULL ) , Distraction_Type_Filters AS ( SELECT - DISTRACTION_TYPES_COMBINED.id_type - , MAX(DISTRACTION_TYPES_COMBINED.does_meet_id_filter) AS does_meet_id_filter - , MAX(DISTRACTION_TYPES_COMBINED.does_meet_name_filter) AS does_meet_name_filter + DISTRACTION_TYPE_COMBINED.id_type + , MAX(DISTRACTION_TYPE_COMBINED.does_meet_id_filter) AS does_meet_id_filter + , MAX(DISTRACTION_TYPE_COMBINED.does_meet_name_filter) AS does_meet_name_filter FROM ( SELECT - DISTRACTION_TYPES_ID_FILTER.id_type + DISTRACTION_TYPE_ID_FILTER.id_type , 1 AS does_meet_id_filter , 0 AS does_meet_name_filter - FROM Distraction_Type_Id_Filter DISTRACTION_TYPES_ID_FILTER + FROM Distraction_Type_Id_Filter DISTRACTION_TYPE_ID_FILTER UNION SELECT - DISTRACTION_TYPES_NAME_FILTER.id_type + DISTRACTION_TYPE_NAME_FILTER.id_type , 0 AS does_meet_id_filter , 1 AS does_meet_name_filter - FROM Distraction_Type_Name_Filter DISTRACTION_TYPES_NAME_FILTER - ) DISTRACTION_TYPES_COMBINED - GROUP BY DISTRACTION_TYPES_COMBINED.id_type + FROM Distraction_Type_Name_Filter DISTRACTION_TYPE_NAME_FILTER + ) DISTRACTION_TYPE_COMBINED + GROUP BY DISTRACTION_TYPE_COMBINED.id_type + ) + , Distraction_Type_Access AS ( + SELECT + DISTRACTION_TYPE.id_type + , CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END AS exists_valid_link + , ROW_NUMBER() OVER ( + PARTITION BY DISTRACTION_TYPE.id_type + ORDER BY + CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END DESC + , t_USER.does_meet_id_filters DESC + , t_USER.does_meet_non_id_filters DESC + ) AS index_link_in_distraction_type + , t_USER.id_user + FROM fetchmetrics.DOG_Distraction_Type DISTRACTION_TYPE + LEFT JOIN fetchmetrics.DOG_Distraction_Type_User_Link DISTRACTION_TYPE_USER_LINK + ON DISTRACTION_TYPE.id_type = DISTRACTION_TYPE_USER_LINK.id_distraction_type + AND ( + ( + a_get_inactive_distraction_type = 1 + AND a_get_inactive_user = 1 + ) + OR DISTRACTION_TYPE_USER_LINK.active = 1 + ) + LEFT JOIN tmp_Calc_User_Access_Calc_Distraction_Type t_USER + ON DISTRACTION_TYPE_USER_LINK.id_user = t_USER.id_user + AND ( + a_get_inactive_user = 1 + OR t_USER.active = 1 + ) + LEFT JOIN fetchmetrics.DOG_Access_Level ACCESS_LEVEL + ON DISTRACTION_TYPE_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level + AND ACCESS_LEVEL.active = 1 ) SELECT - DISTRACTION_TYPES.id_type + DISTRACTION_TYPE.id_type + , IFNULL(DISTRACTION_TYPE_ACCESS.exists_valid_link, 0) AS exists_valid_link + , DISTRACTION_TYPE_ACCESS.id_user , CASE WHEN v_has_filter_distraction_type_id = 0 - OR IFNULL(DISTRACTION_TYPES_FILTERS.does_meet_id_filter, 0) = 1 + OR IFNULL(DISTRACTION_TYPE_FILTERS.does_meet_id_filter, 0) = 1 THEN 1 ELSE 0 END AS does_meet_id_filters , CASE WHEN ( v_has_filter_distraction_type_name = 0 ) - OR IFNULL(DISTRACTION_TYPES_FILTERS.does_meet_name_filter, 0) = 1 + OR IFNULL(DISTRACTION_TYPE_FILTERS.does_meet_name_filter, 0) = 1 THEN 1 ELSE 0 END AS does_meet_non_id_filters - FROM fetchmetrics.DOG_Distraction_Type DISTRACTION_TYPES - LEFT JOIN Distraction_Type_Filters DISTRACTION_TYPES_FILTERS ON DISTRACTION_TYPES.id_type = DISTRACTION_TYPES_FILTERS.id_type + FROM fetchmetrics.DOG_Distraction_Type DISTRACTION_TYPE + LEFT JOIN Distraction_Type_Filters DISTRACTION_TYPE_FILTERS ON DISTRACTION_TYPE.id_type = DISTRACTION_TYPE_FILTERS.id_type + LEFT JOIN Distraction_Type_Access DISTRACTION_TYPE_ACCESS + ON DISTRACTION_TYPE.id_type = DISTRACTION_TYPE_ACCESS.id_type + AND DISTRACTION_TYPE_ACCESS.index_link_in_distraction_type = 1 WHERE ( a_get_all_distraction_type = 1 OR ( v_has_filter_distraction_type_id = 1 - AND DISTRACTION_TYPES_FILTERS.does_meet_id_filter = 1 + AND DISTRACTION_TYPE_FILTERS.does_meet_id_filter = 1 ) OR ( v_has_filter_distraction_type_name = 1 - AND DISTRACTION_TYPES_FILTERS.does_meet_name_filter = 1 + AND DISTRACTION_TYPE_FILTERS.does_meet_name_filter = 1 ) ) + AND IFNULL(DISTRACTION_TYPE_ACCESS.exists_valid_link, 0) = 1 AND ( a_get_inactive_distraction_type = 1 - OR DISTRACTION_TYPES.active = 1 + OR DISTRACTION_TYPE.active = 1 ) ; END IF; @@ -318,28 +569,45 @@ BEGIN -- Filter records IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Distraction_Type t_ERROR INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN - DELETE t_DISTRACTION_TYPES - FROM tmp_Distraction_Type_Calc_Distraction_Type t_DISTRACTION_TYPES + DELETE t_DISTRACTION_TYPE + FROM tmp_Distraction_Type_Calc_Distraction_Type t_DISTRACTION_TYPE + LEFT JOIN tmp_Calc_User_Access_Calc_Distraction_Type t_USER ON t_DISTRACTION_TYPE.id_user = t_USER.id_user WHERE ( a_require_all_id_search_filters_met = 1 AND ( - t_DISTRACTION_TYPES.does_meet_id_filters = 0 + t_DISTRACTION_TYPE.does_meet_id_filters = 0 + OR ( + t_DISTRACTION_TYPE.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 + ) ) ) OR ( a_require_all_non_id_search_filters_met = 1 AND ( - t_DISTRACTION_TYPES.does_meet_non_id_filters = 0 + t_DISTRACTION_TYPE.does_meet_non_id_filters = 0 + OR ( + t_DISTRACTION_TYPE.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 + ) ) ) OR ( a_require_any_id_search_filters_met = 1 - AND t_DISTRACTION_TYPES.does_meet_id_filters = 0 + AND t_DISTRACTION_TYPE.does_meet_id_filters = 0 + AND ( + t_DISTRACTION_TYPE.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 + ) ) OR ( a_require_any_non_id_search_filters_met = 1 - AND t_DISTRACTION_TYPES.does_meet_non_id_filters = 0 + AND t_DISTRACTION_TYPE.does_meet_non_id_filters = 0 + AND ( + t_DISTRACTION_TYPE.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 + ) ) ; END IF; @@ -351,80 +619,6 @@ BEGIN -- Calculated fields - -- Permissions - IF a_debug = 1 THEN - SELECT - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ; - END IF; - - CALL fetchmetrics.p_dog_calc_user_access( - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ); - - SELECT - IFNULL(CALC_USER_T.has_access, 0) - INTO - v_can_view - FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T - WHERE CALC_USER_T.GUID = a_guid - LIMIT 1 - ; - - IF a_debug = 1 THEN - SELECT v_can_view; - END IF; - - IF (v_can_view = 0) THEN - DELETE t_ME - FROM tmp_Msg_Error_Calc_Distraction_Type t_ME - WHERE t_ME.id_type <> v_id_type_error_no_permission - ; - INSERT INTO tmp_Msg_Error_Calc_Distraction_Type ( - id_type - , code - , msg - ) - VALUES ( - v_id_type_error_no_permission - , v_code_type_error_no_permission - , 'You do not have permission to view Dogs and Distraction_Types.' - ) - ; - END IF; - - CALL fetchmetrics.p_dog_clear_calc_user_access( - a_guid - , 0 -- a_debug - ); IF a_debug = 1 THEN SELECT 'Before non-permitted data deletion'; @@ -459,16 +653,16 @@ BEGIN ) SELECT a_guid - , t_DISTRACTION_TYPES.id_type - , DISTRACTION_TYPES.code - , DISTRACTION_TYPES.name - , DISTRACTION_TYPES.active + , t_DISTRACTION_TYPE.id_type + , DISTRACTION_TYPE.code + , DISTRACTION_TYPE.name + , DISTRACTION_TYPE.active - , t_DISTRACTION_TYPES.does_meet_id_filters - , t_DISTRACTION_TYPES.does_meet_non_id_filters - FROM fetchmetrics.DOG_Distraction_Type DISTRACTION_TYPES - INNER JOIN tmp_Distraction_Type_Calc_Distraction_Type t_DISTRACTION_TYPES ON DISTRACTION_TYPES.id_type = t_DISTRACTION_TYPES.id_type - ORDER BY DISTRACTION_TYPES.name + , t_DISTRACTION_TYPE.does_meet_id_filters + , t_DISTRACTION_TYPE.does_meet_non_id_filters + FROM fetchmetrics.DOG_Distraction_Type DISTRACTION_TYPE + INNER JOIN tmp_Distraction_Type_Calc_Distraction_Type t_DISTRACTION_TYPE ON DISTRACTION_TYPE.id_type = t_DISTRACTION_TYPE.id_type + ORDER BY DISTRACTION_TYPE.name ; COMMIT; @@ -499,6 +693,7 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_Distraction_Type; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_Distraction_Type; DROP TEMPORARY TABLE IF EXISTS tmp_Distraction_Type_Calc_Distraction_Type; + DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_Distraction_Type; IF a_debug = 1 THEN CALL fetchmetrics.p_core_debug_timing_reporting ( v_time_start ); @@ -517,6 +712,11 @@ CALL fetchmetrics.p_dog_calc_distraction_type ( , 0 -- a_get_inactive_distraction_type , '' -- a_ids_distraction_type , '' -- a_names_distraction_type + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , '' -- a_names_user + , '' -- a_emails_user , 0 -- a_require_all_id_search_filters_met , 0 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met diff --git a/static/MySQL/71312_p_dog_get_many_distraction_type.sql b/static/MySQL/71312_p_dog_get_many_distraction_type.sql index 39dc014..f7ba16c 100644 --- a/static/MySQL/71312_p_dog_get_many_distraction_type.sql +++ b/static/MySQL/71312_p_dog_get_many_distraction_type.sql @@ -10,6 +10,11 @@ CREATE PROCEDURE fetchmetrics.p_dog_get_many_distraction_type ( , IN a_get_inactive_distraction_type BIT , IN a_ids_distraction_type TEXT , IN a_names_distraction_type TEXT + , IN a_get_all_user BIT + , IN a_get_inactive_user BIT + , IN a_ids_user TEXT + , IN a_names_user TEXT + , IN a_emails_user TEXT , IN a_require_all_id_search_filters_met BIT , IN a_require_any_id_search_filters_met BIT , IN a_require_all_non_id_search_filters_met BIT @@ -104,6 +109,11 @@ BEGIN , a_get_inactive_distraction_type , a_ids_distraction_type , a_names_distraction_type + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met , a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met @@ -228,6 +238,11 @@ BEGIN , a_get_inactive_distraction_type -- a_get_inactive_distraction_type , a_ids_distraction_type -- a_ids_distraction_type , a_names_distraction_type -- a_names_distraction_type + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -244,6 +259,11 @@ BEGIN , a_get_inactive_distraction_type -- a_get_inactive_distraction_type , a_ids_distraction_type -- a_ids_distraction_type , a_names_distraction_type -- a_names_distraction_type + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -351,6 +371,11 @@ CALL fetchmetrics.p_dog_get_many_distraction_type ( , 0 -- a_get_inactive_distraction_type , '' -- a_ids_distraction_type , '' -- a_names_distraction_type + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , '' -- a_names_user + , '' -- a_emails_user , 1 -- a_require_all_id_search_filters_met , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met @@ -365,6 +390,11 @@ CALL fetchmetrics.p_dog_get_many_distraction_type ( , 0 -- a_get_inactive_distraction_type , '' -- a_ids_distraction_type , 'pat,point' -- a_names_distraction_type + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , 'pat,point' -- a_names_user + , 'pat,point' -- a_emails_user , 1 -- a_require_all_id_search_filters_met , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met diff --git a/static/MySQL/71316_p_dog_calc_distraction_intensity_level.sql b/static/MySQL/71316_p_dog_calc_distraction_intensity_level.sql index a4c52eb..b98bb93 100644 --- a/static/MySQL/71316_p_dog_calc_distraction_intensity_level.sql +++ b/static/MySQL/71316_p_dog_calc_distraction_intensity_level.sql @@ -11,6 +11,11 @@ CREATE PROCEDURE fetchmetrics.p_dog_calc_distraction_intensity_level ( , IN a_get_inactive_distraction_intensity_level BIT , IN a_ids_distraction_intensity_level TEXT , IN a_names_distraction_intensity_level TEXT + , IN a_get_all_user BIT + , IN a_get_inactive_user BIT + , IN a_ids_user TEXT + , IN a_names_user TEXT + , IN a_emails_user TEXT , IN a_require_all_id_search_filters_met BIT , IN a_require_any_id_search_filters_met BIT , IN a_require_all_non_id_search_filters_met BIT @@ -26,9 +31,14 @@ BEGIN DECLARE v_has_filter_distraction_intensity_level_name BIT; DECLARE v_id_access_level_view INT; DECLARE v_id_minimum INT; + DECLARE v_id_permission_command_view INT; DECLARE v_id_permission_dog_view INT; DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; + DECLARE v_ids_permission_required VARCHAR(200); + DECLARE v_is_super_user BIT; + DECLARE v_priority_access_level_none INT; + DECLARE v_priority_access_level_view INT; DECLARE v_time_start TIMESTAMP(6); DECLARE exit handler for SQLEXCEPTION @@ -61,19 +71,21 @@ BEGIN WHERE MET.code = 'MYSQL_ERROR' ; - SELECT - t_ERROR.id_error - , t_ERROR.id_type - , t_ERROR.code - , ERROR_TYPE.name - , ERROR_TYPE.description - , ERROR_TYPE.is_breaking_error - , ERROR_TYPE.background_colour - , ERROR_TYPE.text_colour - , t_ERROR.msg - FROM tmp_Msg_Error_Calc_Distraction_Intensity_Level t_ERROR - INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type - ; + IF a_show_errors = 1 THEN + SELECT + t_ERROR.id_error + , t_ERROR.id_type + , t_ERROR.code + , ERROR_TYPE.name + , ERROR_TYPE.description + , ERROR_TYPE.is_breaking_error + , ERROR_TYPE.background_colour + , ERROR_TYPE.text_colour + , t_ERROR.msg + FROM tmp_Msg_Error_Calc_Distraction_Intensity_Level t_ERROR + INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type + ; + END IF; DROP TABLE IF EXISTS tmp_Msg_Error_Calc_Distraction_Intensity_Level; END; @@ -83,9 +95,17 @@ BEGIN SET v_code_type_error_no_permission := 'NO_PERMISSION'; SET v_id_type_error_bad_data := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_bad_data LIMIT 1); SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); + SET v_id_permission_command_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'COMMAND_VIEW' LIMIT 1); SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1); - + SET v_ids_permission_required := (SELECT CONCAT( + CONVERT(v_id_permission_dog_view, CHAR) + , ',' + , CONVERT(v_id_permission_command_view, CHAR) + )); + SET v_priority_access_level_none := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'NONE' LIMIT 1); + SET v_priority_access_level_view := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.id_access_level = v_id_access_level_view); + CALL fetchmetrics.p_core_validate_guid ( a_guid ); @@ -109,6 +129,11 @@ BEGIN , a_get_inactive_distraction_intensity_level , a_ids_distraction_intensity_level , a_names_distraction_intensity_level + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met , a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met @@ -120,7 +145,9 @@ BEGIN SELECT v_id_type_error_bad_data , v_id_type_error_no_permission + , v_id_permission_command_view , v_id_permission_dog_view + , v_ids_permission_required , v_time_start ; END IF; @@ -129,9 +156,30 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_Distraction_Intensity_Level; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_Distraction_Intensity_Level; DROP TEMPORARY TABLE IF EXISTS tmp_Distraction_Intensity_Level_Calc_Distraction_Intensity_Level; + DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_Distraction_Intensity_Level; + + CREATE TEMPORARY TABLE tmp_Calc_User_Access_Calc_Distraction_Intensity_Level ( + id_temp INT PRIMARY KEY AUTO_INCREMENT NOT NULL + , id_user INT + , id_role INT + , id_permission_required INT NOT NULL + , priority_access_level_required INT NOT NULL + , is_super_user BIT + , priority_access_level_user INT + , has_access BIT + , can_view BIT + , can_edit BIT + , can_admin BIT + , active BIT + + , does_meet_id_filters BIT + , does_meet_non_id_filters BIT + ); CREATE TEMPORARY TABLE tmp_Distraction_Intensity_Level_Calc_Distraction_Intensity_Level ( id_intensity_level INT NOT NULL + , exists_valid_link BIT NOT NULL + , id_user INT , does_meet_id_filters BIT NOT NULL , does_meet_non_id_filters BIT NOT NULL ); @@ -158,7 +206,171 @@ BEGIN SET v_has_filter_distraction_intensity_level_id = CASE WHEN a_ids_distraction_intensity_level <> '' THEN 1 ELSE 0 END; SET v_has_filter_distraction_intensity_level_name = CASE WHEN a_names_distraction_intensity_level <> '' THEN 1 ELSE 0 END; - -- Distraction_Intensity_Levels + + -- Permissions + IF a_debug = 1 THEN + SELECT + a_guid -- a_guid + , 0 -- get_all_user + , 0 -- get_inactive_user + , a_id_user -- ids_user + , '' -- a_auth0_ids_user + , '' -- a_names_user + , '' -- a_emails_user + , 1 -- a_require_all_id_search_filters_met + , 1 -- a_require_any_id_search_filters_met + , 0 -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL fetchmetrics.p_dog_calc_user_access( + a_guid -- a_guid + , 0 -- get_all_user + , 0 -- get_inactive_user + , a_id_user -- ids_user + , '' -- a_auth0_ids_user + , '' -- a_names_user + , '' -- a_emails_user + , 1 -- a_require_all_id_search_filters_met + , 1 -- a_require_any_id_search_filters_met + , 0 -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ); + + SELECT + IFNULL(CALC_USER_T.has_access, 0) + , IFNULL(CALC_USER_T.is_super_user, 0) + INTO + v_can_view + , v_is_super_user + FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T + WHERE CALC_USER_T.guid = a_guid + LIMIT 1 + ; + + IF a_debug = 1 THEN + SELECT + v_can_view + , v_is_super_user + ; + END IF; + + IF (v_can_view = 0) THEN + DELETE t_ME + FROM tmp_Msg_Error_Calc_Distraction_Intensity_Level t_ME + WHERE t_ME.id_type <> v_id_type_error_no_permission + ; + INSERT INTO tmp_Msg_Error_Calc_Distraction_Intensity_Level ( + id_type + , code + , msg + ) + VALUES ( + v_id_type_error_no_permission + , v_code_type_error_no_permission + , 'You do not have permission to view Dogs and DISTRACTION_INTENSITY_LEVEL.' + ) + ; + END IF; + + CALL fetchmetrics.p_dog_clear_calc_user_access( + a_guid + , 0 -- a_debug + ); + + -- Users + IF a_debug = 1 THEN + SELECT + a_guid -- guid + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , '' -- a_auth0_ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user + , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met + , 0 -- a_require_any_id_search_filters_met + , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL fetchmetrics.p_dog_calc_user_access( + a_guid-- guid + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , '' -- a_auth0_ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user + , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met + , 0 -- a_require_any_id_search_filters_met + , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ); + + INSERT INTO tmp_Calc_User_Access_Calc_Distraction_Intensity_Level ( + id_user + , id_role + , id_permission_required + , priority_access_level_required + , is_super_user + , priority_access_level_user + , has_access + , can_view + , can_edit + , can_admin + , active + , does_meet_id_filters + , does_meet_non_id_filters + ) + SELECT + CALC_USER_T.id_user + , CALC_USER_T.id_role + , CALC_USER_T.id_permission_required + , CALC_USER_T.priority_access_level_required + , CALC_USER_T.is_super_user + , CALC_USER_T.priority_access_level_user + , CALC_USER_T.has_access + , CALC_USER_T.can_view + , CALC_USER_T.can_edit + , CALC_USER_T.can_admin + , CALC_USER_T.active + , CALC_USER_T.does_meet_id_filters + , CALC_USER_T.does_meet_non_id_filters + FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T + WHERE CALC_USER_T.GUID = a_guid + ; + + IF a_debug = 1 THEN + SELECT 'After get many user'; + SELECT * FROM tmp_Calc_User_Access_Calc_Distraction_Intensity_Level; + END IF; + + CALL fetchmetrics.p_dog_clear_calc_user_access( + a_guid + , 0 -- a_debug + ); + + + -- DISTRACTION_INTENSITY_LEVEL IF v_has_filter_distraction_intensity_level_id = 1 THEN CALL fetchmetrics.p_core_split(a_guid, a_ids_distraction_intensity_level, ',', a_debug); @@ -205,12 +417,12 @@ BEGIN IF EXISTS ( SELECT * FROM tmp_Split_Id_Calc_Distraction_Intensity_Level t_SPLIT_ID - LEFT JOIN fetchmetrics.DOG_Distraction_Intensity_Level DISTRACTION_INTENSITY_LEVELS ON t_SPLIT_ID.as_int = DISTRACTION_INTENSITY_LEVELS.id_intensity_level + LEFT JOIN fetchmetrics.DOG_Distraction_Intensity_Level DISTRACTION_INTENSITY_LEVEL ON t_SPLIT_ID.as_int = DISTRACTION_INTENSITY_LEVEL.id_intensity_level WHERE ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(DISTRACTION_INTENSITY_LEVELS.id_intensity_level) + OR ISNULL(DISTRACTION_INTENSITY_LEVEL.id_intensity_level) OR ( - DISTRACTION_INTENSITY_LEVELS.active = 0 + DISTRACTION_INTENSITY_LEVEL.active = 0 AND a_get_inactive_distraction_intensity_level = 0 ) ) THEN @@ -224,12 +436,12 @@ BEGIN , v_code_type_error_bad_data , CONCAT('Invalid or inactive Distraction_Intensity_Level IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT_ID.substring SEPARATOR ', '), 'NULL')) FROM tmp_Split_Id_Calc_Distraction_Intensity_Level t_SPLIT_ID - LEFT JOIN fetchmetrics.DOG_Distraction_Intensity_Level DISTRACTION_INTENSITY_LEVELS ON t_SPLIT_ID.as_int = DISTRACTION_INTENSITY_LEVELS.id_intensity_level + LEFT JOIN fetchmetrics.DOG_Distraction_Intensity_Level DISTRACTION_INTENSITY_LEVEL ON t_SPLIT_ID.as_int = DISTRACTION_INTENSITY_LEVEL.id_intensity_level WHERE ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(DISTRACTION_INTENSITY_LEVELS.id_intensity_level) + OR ISNULL(DISTRACTION_INTENSITY_LEVEL.id_intensity_level) OR ( - DISTRACTION_INTENSITY_LEVELS.active = 0 + DISTRACTION_INTENSITY_LEVEL.active = 0 AND a_get_inactive_distraction_intensity_level = 0 ) ; @@ -239,70 +451,122 @@ BEGIN ELSE INSERT INTO tmp_Distraction_Intensity_Level_Calc_Distraction_Intensity_Level ( id_intensity_level + , exists_valid_link + , id_user , does_meet_id_filters , does_meet_non_id_filters ) WITH Distraction_Intensity_Level_Id_Filter AS ( - SELECT DISTRACTION_INTENSITY_LEVELS.id_intensity_level + SELECT DISTRACTION_INTENSITY_LEVEL.id_intensity_level FROM tmp_Split_Id_Calc_Distraction_Intensity_Level t_SPLIT_ID - INNER JOIN fetchmetrics.DOG_Distraction_Intensity_Level DISTRACTION_INTENSITY_LEVELS ON t_SPLIT_ID.as_int = DISTRACTION_INTENSITY_LEVELS.id_intensity_level + INNER JOIN fetchmetrics.DOG_Distraction_Intensity_Level DISTRACTION_INTENSITY_LEVEL ON t_SPLIT_ID.as_int = DISTRACTION_INTENSITY_LEVEL.id_intensity_level ) , Distraction_Intensity_Level_Name_Filter AS ( - SELECT DISTRACTION_INTENSITY_LEVELS.id_intensity_level + SELECT DISTRACTION_INTENSITY_LEVEL.id_intensity_level FROM tmp_Split_Name_Calc_Distraction_Intensity_Level t_SPLIT_NAME - INNER JOIN fetchmetrics.DOG_Distraction_Intensity_Level DISTRACTION_INTENSITY_LEVELS ON DISTRACTION_INTENSITY_LEVELS.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') + INNER JOIN fetchmetrics.DOG_Distraction_Intensity_Level DISTRACTION_INTENSITY_LEVEL ON DISTRACTION_INTENSITY_LEVEL.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') WHERE NULLIF(t_SPLIT_NAME.substring, '') IS NOT NULL ) , Distraction_Intensity_Level_Filters AS ( SELECT - DISTRACTION_INTENSITY_LEVELS_COMBINED.id_intensity_level - , MAX(DISTRACTION_INTENSITY_LEVELS_COMBINED.does_meet_id_filter) AS does_meet_id_filter - , MAX(DISTRACTION_INTENSITY_LEVELS_COMBINED.does_meet_name_filter) AS does_meet_name_filter + DISTRACTION_INTENSITY_LEVEL_COMBINED.id_intensity_level + , MAX(DISTRACTION_INTENSITY_LEVEL_COMBINED.does_meet_id_filter) AS does_meet_id_filter + , MAX(DISTRACTION_INTENSITY_LEVEL_COMBINED.does_meet_name_filter) AS does_meet_name_filter FROM ( SELECT - DISTRACTION_INTENSITY_LEVELS_ID_FILTER.id_intensity_level + DISTRACTION_INTENSITY_LEVEL_ID_FILTER.id_intensity_level , 1 AS does_meet_id_filter , 0 AS does_meet_name_filter - FROM Distraction_Intensity_Level_Id_Filter DISTRACTION_INTENSITY_LEVELS_ID_FILTER + FROM Distraction_Intensity_Level_Id_Filter DISTRACTION_INTENSITY_LEVEL_ID_FILTER UNION SELECT - DISTRACTION_INTENSITY_LEVELS_NAME_FILTER.id_intensity_level + DISTRACTION_INTENSITY_LEVEL_NAME_FILTER.id_intensity_level , 0 AS does_meet_id_filter , 1 AS does_meet_name_filter - FROM Distraction_Intensity_Level_Name_Filter DISTRACTION_INTENSITY_LEVELS_NAME_FILTER - ) DISTRACTION_INTENSITY_LEVELS_COMBINED - GROUP BY DISTRACTION_INTENSITY_LEVELS_COMBINED.id_intensity_level + FROM Distraction_Intensity_Level_Name_Filter DISTRACTION_INTENSITY_LEVEL_NAME_FILTER + ) DISTRACTION_INTENSITY_LEVEL_COMBINED + GROUP BY DISTRACTION_INTENSITY_LEVEL_COMBINED.id_intensity_level + ) + , Distraction_Intensity_Level_Access AS ( + SELECT + DISTRACTION_INTENSITY_LEVEL.id_intensity_level + , CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END AS exists_valid_link + , ROW_NUMBER() OVER ( + PARTITION BY DISTRACTION_INTENSITY_LEVEL.id_intensity_level + ORDER BY + CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END DESC + , t_USER.does_meet_id_filters DESC + , t_USER.does_meet_non_id_filters DESC + ) AS index_link_in_distraction_intensity_level + , t_USER.id_user + FROM fetchmetrics.DOG_Distraction_Intensity_Level DISTRACTION_INTENSITY_LEVEL + LEFT JOIN fetchmetrics.DOG_Distraction_Intensity_Level_User_Link DISTRACTION_INTENSITY_LEVEL_USER_LINK + ON DISTRACTION_INTENSITY_LEVEL.id_intensity_level = DISTRACTION_INTENSITY_LEVEL_USER_LINK.id_intensity_level + AND ( + ( + a_get_inactive_distraction_intensity_level = 1 + AND a_get_inactive_user = 1 + ) + OR DISTRACTION_INTENSITY_LEVEL_USER_LINK.active = 1 + ) + LEFT JOIN tmp_Calc_User_Access_Calc_Distraction_Intensity_Level t_USER + ON DISTRACTION_INTENSITY_LEVEL_USER_LINK.id_user = t_USER.id_user + AND ( + a_get_inactive_user = 1 + OR t_USER.active = 1 + ) + LEFT JOIN fetchmetrics.DOG_Access_Level ACCESS_LEVEL + ON DISTRACTION_INTENSITY_LEVEL_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level + AND ACCESS_LEVEL.active = 1 ) SELECT - DISTRACTION_INTENSITY_LEVELS.id_intensity_level + DISTRACTION_INTENSITY_LEVEL.id_intensity_level + , IFNULL(DISTRACTION_INTENSITY_LEVEL_ACCESS.exists_valid_link, 0) AS exists_valid_link + , DISTRACTION_INTENSITY_LEVEL_ACCESS.id_user , CASE WHEN v_has_filter_distraction_intensity_level_id = 0 - OR IFNULL(DISTRACTION_INTENSITY_LEVELS_FILTERS.does_meet_id_filter, 0) = 1 + OR IFNULL(DISTRACTION_INTENSITY_LEVEL_FILTERS.does_meet_id_filter, 0) = 1 THEN 1 ELSE 0 END AS does_meet_id_filters , CASE WHEN ( v_has_filter_distraction_intensity_level_name = 0 ) - OR IFNULL(DISTRACTION_INTENSITY_LEVELS_FILTERS.does_meet_name_filter, 0) = 1 + OR IFNULL(DISTRACTION_INTENSITY_LEVEL_FILTERS.does_meet_name_filter, 0) = 1 THEN 1 ELSE 0 END AS does_meet_non_id_filters - FROM fetchmetrics.DOG_Distraction_Intensity_Level DISTRACTION_INTENSITY_LEVELS - LEFT JOIN Distraction_Intensity_Level_Filters DISTRACTION_INTENSITY_LEVELS_FILTERS ON DISTRACTION_INTENSITY_LEVELS.id_intensity_level = DISTRACTION_INTENSITY_LEVELS_FILTERS.id_intensity_level + FROM fetchmetrics.DOG_Distraction_Intensity_Level DISTRACTION_INTENSITY_LEVEL + LEFT JOIN Distraction_Intensity_Level_Filters DISTRACTION_INTENSITY_LEVEL_FILTERS ON DISTRACTION_INTENSITY_LEVEL.id_intensity_level = DISTRACTION_INTENSITY_LEVEL_FILTERS.id_intensity_level + LEFT JOIN Distraction_Intensity_Level_Access DISTRACTION_INTENSITY_LEVEL_ACCESS + ON DISTRACTION_INTENSITY_LEVEL.id_intensity_level = DISTRACTION_INTENSITY_LEVEL_ACCESS.id_intensity_level + AND DISTRACTION_INTENSITY_LEVEL_ACCESS.index_link_in_distraction_intensity_level = 1 WHERE ( a_get_all_distraction_intensity_level = 1 OR ( v_has_filter_distraction_intensity_level_id = 1 - AND DISTRACTION_INTENSITY_LEVELS_FILTERS.does_meet_id_filter = 1 + AND DISTRACTION_INTENSITY_LEVEL_FILTERS.does_meet_id_filter = 1 ) OR ( v_has_filter_distraction_intensity_level_name = 1 - AND DISTRACTION_INTENSITY_LEVELS_FILTERS.does_meet_name_filter = 1 + AND DISTRACTION_INTENSITY_LEVEL_FILTERS.does_meet_name_filter = 1 ) ) + AND IFNULL(DISTRACTION_INTENSITY_LEVEL_ACCESS.exists_valid_link, 0) = 1 AND ( a_get_inactive_distraction_intensity_level = 1 - OR DISTRACTION_INTENSITY_LEVELS.active = 1 + OR DISTRACTION_INTENSITY_LEVEL.active = 1 ) ; END IF; @@ -312,119 +576,62 @@ BEGIN DELETE FROM tmp_Split_Name_Calc_Distraction_Intensity_Level; IF a_debug = 1 THEN - SELECT 'After get Distraction_Intensity_Levels '; + SELECT 'After get DISTRACTION_INTENSITY_LEVEL '; SELECT * FROM tmp_Distraction_Intensity_Level_Calc_Distraction_Intensity_Level; END IF; -- Filter records IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Distraction_Intensity_Level t_ERROR INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN - DELETE t_DISTRACTION_INTENSITY_LEVELS - FROM tmp_Distraction_Intensity_Level_Calc_Distraction_Intensity_Level t_DISTRACTION_INTENSITY_LEVELS + DELETE t_DISTRACTION_INTENSITY_LEVEL + FROM tmp_Distraction_Intensity_Level_Calc_Distraction_Intensity_Level t_DISTRACTION_INTENSITY_LEVEL + LEFT JOIN tmp_Calc_User_Access_Calc_Distraction_Intensity_Level t_USER ON t_DISTRACTION_INTENSITY_LEVEL.id_user = t_USER.id_user WHERE ( a_require_all_id_search_filters_met = 1 AND ( - t_DISTRACTION_INTENSITY_LEVELS.does_meet_id_filters = 0 + t_DISTRACTION_INTENSITY_LEVEL.does_meet_id_filters = 0 + OR ( + t_DISTRACTION_INTENSITY_LEVEL.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 + ) ) ) OR ( a_require_all_non_id_search_filters_met = 1 AND ( - t_DISTRACTION_INTENSITY_LEVELS.does_meet_non_id_filters = 0 + t_DISTRACTION_INTENSITY_LEVEL.does_meet_non_id_filters = 0 + OR ( + t_DISTRACTION_INTENSITY_LEVEL.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 + ) ) ) OR ( a_require_any_id_search_filters_met = 1 - AND t_DISTRACTION_INTENSITY_LEVELS.does_meet_id_filters = 0 + AND t_DISTRACTION_INTENSITY_LEVEL.does_meet_id_filters = 0 + AND ( + t_DISTRACTION_INTENSITY_LEVEL.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 + ) ) OR ( a_require_any_non_id_search_filters_met = 1 - AND t_DISTRACTION_INTENSITY_LEVELS.does_meet_non_id_filters = 0 + AND t_DISTRACTION_INTENSITY_LEVEL.does_meet_non_id_filters = 0 + AND ( + t_DISTRACTION_INTENSITY_LEVEL.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 + ) ) ; END IF; IF a_debug = 1 THEN - SELECT 'After filter Distraction_Intensity_Levels'; + SELECT 'After filter DISTRACTION_INTENSITY_LEVEL'; SELECT * FROM tmp_Distraction_Intensity_Level_Calc_Distraction_Intensity_Level; END IF; -- Calculated fields - -- Permissions - IF a_debug = 1 THEN - SELECT - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ; - END IF; - - CALL fetchmetrics.p_dog_calc_user_access( - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ); - - SELECT - IFNULL(CALC_USER_T.has_access, 0) - INTO - v_can_view - FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T - WHERE CALC_USER_T.GUID = a_guid - LIMIT 1 - ; - - IF a_debug = 1 THEN - SELECT v_can_view; - END IF; - - IF (v_can_view = 0) THEN - DELETE t_ME - FROM tmp_Msg_Error_Calc_Distraction_Intensity_Level t_ME - WHERE t_ME.id_type <> v_id_type_error_no_permission - ; - INSERT INTO tmp_Msg_Error_Calc_Distraction_Intensity_Level ( - id_type - , code - , msg - ) - VALUES ( - v_id_type_error_no_permission - , v_code_type_error_no_permission - , 'You do not have permission to view Dogs and Distraction_Intensity_Levels.' - ) - ; - END IF; - - CALL fetchmetrics.p_dog_clear_calc_user_access( - a_guid - , 0 -- a_debug - ); IF a_debug = 1 THEN SELECT 'Before non-permitted data deletion'; @@ -446,7 +653,7 @@ BEGIN -- Outputs START TRANSACTION; - -- Distraction_Intensity_Levels + -- DISTRACTION_INTENSITY_LEVEL INSERT INTO fetchmetrics.DOG_Distraction_Intensity_Level_Temp ( guid , id_intensity_level @@ -459,16 +666,16 @@ BEGIN ) SELECT a_guid - , t_DISTRACTION_INTENSITY_LEVELS.id_intensity_level - , DISTRACTION_INTENSITY_LEVELS.code - , DISTRACTION_INTENSITY_LEVELS.name - , DISTRACTION_INTENSITY_LEVELS.active + , t_DISTRACTION_INTENSITY_LEVEL.id_intensity_level + , DISTRACTION_INTENSITY_LEVEL.code + , DISTRACTION_INTENSITY_LEVEL.name + , DISTRACTION_INTENSITY_LEVEL.active - , t_DISTRACTION_INTENSITY_LEVELS.does_meet_id_filters - , t_DISTRACTION_INTENSITY_LEVELS.does_meet_non_id_filters - FROM fetchmetrics.DOG_Distraction_Intensity_Level DISTRACTION_INTENSITY_LEVELS - INNER JOIN tmp_Distraction_Intensity_Level_Calc_Distraction_Intensity_Level t_DISTRACTION_INTENSITY_LEVELS ON DISTRACTION_INTENSITY_LEVELS.id_intensity_level = t_DISTRACTION_INTENSITY_LEVELS.id_intensity_level - ORDER BY DISTRACTION_INTENSITY_LEVELS.name + , t_DISTRACTION_INTENSITY_LEVEL.does_meet_id_filters + , t_DISTRACTION_INTENSITY_LEVEL.does_meet_non_id_filters + FROM fetchmetrics.DOG_Distraction_Intensity_Level DISTRACTION_INTENSITY_LEVEL + INNER JOIN tmp_Distraction_Intensity_Level_Calc_Distraction_Intensity_Level t_DISTRACTION_INTENSITY_LEVEL ON DISTRACTION_INTENSITY_LEVEL.id_intensity_level = t_DISTRACTION_INTENSITY_LEVEL.id_intensity_level + ORDER BY DISTRACTION_INTENSITY_LEVEL.name ; COMMIT; @@ -499,6 +706,7 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_Distraction_Intensity_Level; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_Distraction_Intensity_Level; DROP TEMPORARY TABLE IF EXISTS tmp_Distraction_Intensity_Level_Calc_Distraction_Intensity_Level; + DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_Distraction_Intensity_Level; IF a_debug = 1 THEN CALL fetchmetrics.p_core_debug_timing_reporting ( v_time_start ); @@ -517,6 +725,11 @@ CALL fetchmetrics.p_dog_calc_distraction_intensity_level ( , 0 -- a_get_inactive_distraction_intensity_level , '' -- a_ids_distraction_intensity_level , '' -- a_names_distraction_intensity_level + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , '' -- a_names_user + , '' -- a_emails_user , 0 -- a_require_all_id_search_filters_met , 0 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met diff --git a/static/MySQL/71316_p_dog_get_many_distraction_intensity_level.sql b/static/MySQL/71316_p_dog_get_many_distraction_intensity_level.sql index 7ae8a04..4a6baea 100644 --- a/static/MySQL/71316_p_dog_get_many_distraction_intensity_level.sql +++ b/static/MySQL/71316_p_dog_get_many_distraction_intensity_level.sql @@ -10,6 +10,11 @@ CREATE PROCEDURE fetchmetrics.p_dog_get_many_distraction_intensity_level ( , IN a_get_inactive_distraction_intensity_level BIT , IN a_ids_distraction_intensity_level TEXT , IN a_names_distraction_intensity_level TEXT + , IN a_get_all_user BIT + , IN a_get_inactive_user BIT + , IN a_ids_user TEXT + , IN a_names_user TEXT + , IN a_emails_user TEXT , IN a_require_all_id_search_filters_met BIT , IN a_require_any_id_search_filters_met BIT , IN a_require_all_non_id_search_filters_met BIT @@ -81,7 +86,6 @@ BEGIN SET v_code_type_error_no_permission := 'NO_PERMISSION'; SET v_id_type_error_bad_data := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_bad_data LIMIT 1); SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); - SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1); SET a_id_user := IFNULL(a_id_user, 0); @@ -104,6 +108,11 @@ BEGIN , a_get_inactive_distraction_intensity_level , a_ids_distraction_intensity_level , a_names_distraction_intensity_level + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met , a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met @@ -115,7 +124,6 @@ BEGIN v_id_type_error_bad_data , v_id_type_error_no_permission , v_guid - , v_id_permission_dog_view , v_time_start ; END IF; @@ -140,82 +148,6 @@ BEGIN , msg TEXT NOT NULL ); - -- Permissions - IF a_debug = 1 THEN - SELECT - v_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ; - END IF; - - CALL fetchmetrics.p_dog_calc_user_access( - v_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ); - - SELECT - IFNULL(CALC_USER_T.has_access, 0) - INTO - v_can_view - FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T - WHERE CALC_USER_T.GUID = v_guid - LIMIT 1 - ; - - IF a_debug = 1 THEN - SELECT v_can_view; - SELECT COUNT(*) AS Count_Errors FROM tmp_Msg_Error t_ERROR; - SELECT * FROM tmp_Msg_Error t_ERROR; - END IF; - - IF (v_can_view = 0) THEN - DELETE t_ME - FROM tmp_Msg_Error t_ME - WHERE t_ME.id_type <> v_id_type_error_no_permission - ; - INSERT INTO tmp_Msg_Error ( - id_type - , code - , msg - ) - VALUES ( - v_id_type_error_no_permission - , v_code_type_error_no_permission - , 'You do not have permission to view Distraction_Intensity_Levels.' - ) - ; - END IF; - - CALL fetchmetrics.p_dog_clear_calc_user_access( - v_guid - , 0 -- a_debug - ); -- Call Distraction_Intensity_Level Calc @@ -228,6 +160,11 @@ BEGIN , a_get_inactive_distraction_intensity_level -- a_get_inactive_distraction_intensity_level , a_ids_distraction_intensity_level -- a_ids_distraction_intensity_level , a_names_distraction_intensity_level -- a_names_distraction_intensity_level + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -244,6 +181,11 @@ BEGIN , a_get_inactive_distraction_intensity_level -- a_get_inactive_distraction_intensity_level , a_ids_distraction_intensity_level -- a_ids_distraction_intensity_level , a_names_distraction_intensity_level -- a_names_distraction_intensity_level + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -283,15 +225,6 @@ BEGIN SELECT * FROM tmp_Distraction_Intensity_Level; END IF; END IF; - - -- Filter outputs - IF EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN - IF a_debug = 1 THEN - SELECT * FROM tmp_Distraction_Intensity_Level; - END IF; - - DELETE FROM tmp_Distraction_Intensity_Level; - END IF; -- Outputs @@ -351,6 +284,11 @@ CALL fetchmetrics.p_dog_get_many_distraction_intensity_level ( , 0 -- a_get_inactive_distraction_intensity_level , '' -- a_ids_distraction_intensity_level , '' -- a_names_distraction_intensity_level + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , '' -- a_names_user + , '' -- a_emails_user , 1 -- a_require_all_id_search_filters_met , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met @@ -365,6 +303,11 @@ CALL fetchmetrics.p_dog_get_many_distraction_intensity_level ( , 0 -- a_get_inactive_distraction_intensity_level , '' -- a_ids_distraction_intensity_level , 'pat,point' -- a_names_distraction_intensity_level + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , 'pat,point' -- a_names_user + , 'pat,point' -- a_emails_user , 1 -- a_require_all_id_search_filters_met , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met diff --git a/static/MySQL/71332_p_dog_calc_response_quality_metric.sql b/static/MySQL/71332_p_dog_calc_response_quality_metric.sql index 92941e1..983250d 100644 --- a/static/MySQL/71332_p_dog_calc_response_quality_metric.sql +++ b/static/MySQL/71332_p_dog_calc_response_quality_metric.sql @@ -12,7 +12,11 @@ CREATE PROCEDURE fetchmetrics.p_dog_calc_response_quality_metric ( , IN a_ids_metric TEXT -- , IN a_ids_unit_measurement_metric TEXT , IN a_names_metric TEXT - + , IN a_get_all_user BIT + , IN a_get_inactive_user BIT + , IN a_ids_user TEXT + , IN a_names_user TEXT + , IN a_emails_user TEXT , IN a_require_all_id_search_filters_met BIT , IN a_require_any_id_search_filters_met BIT , IN a_require_all_non_id_search_filters_met BIT @@ -28,9 +32,14 @@ BEGIN DECLARE v_has_filter_response_quality_metric_name BIT; DECLARE v_id_access_level_view INT; DECLARE v_id_minimum INT; + DECLARE v_id_permission_command_view INT; DECLARE v_id_permission_dog_view INT; DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; + DECLARE v_ids_permission_required VARCHAR(200); + DECLARE v_is_super_user BIT; + DECLARE v_priority_access_level_none INT; + DECLARE v_priority_access_level_view INT; DECLARE v_time_start TIMESTAMP(6); DECLARE exit handler for SQLEXCEPTION @@ -63,19 +72,21 @@ BEGIN WHERE MET.code = 'MYSQL_ERROR' ; - SELECT - t_ERROR.id_error - , t_ERROR.id_type - , t_ERROR.code - , ERROR_TYPE.name - , ERROR_TYPE.description - , ERROR_TYPE.is_breaking_error - , ERROR_TYPE.background_colour - , ERROR_TYPE.text_colour - , t_ERROR.msg - FROM tmp_Msg_Error_Calc_RQM t_ERROR - INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type - ; + IF a_show_errors = 1 THEN + SELECT + t_ERROR.id_error + , t_ERROR.id_type + , t_ERROR.code + , ERROR_TYPE.name + , ERROR_TYPE.description + , ERROR_TYPE.is_breaking_error + , ERROR_TYPE.background_colour + , ERROR_TYPE.text_colour + , t_ERROR.msg + FROM tmp_Msg_Error_Calc_RQM t_ERROR + INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type + ; + END IF; DROP TABLE IF EXISTS tmp_Msg_Error_Calc_RQM; END; @@ -85,9 +96,17 @@ BEGIN SET v_code_type_error_no_permission := 'NO_PERMISSION'; SET v_id_type_error_bad_data := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_bad_data LIMIT 1); SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); + SET v_id_permission_command_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'COMMAND_VIEW' LIMIT 1); SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1); - + SET v_ids_permission_required := (SELECT CONCAT( + CONVERT(v_id_permission_dog_view, CHAR) + , ',' + , CONVERT(v_id_permission_command_view, CHAR) + )); + SET v_priority_access_level_none := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'NONE' LIMIT 1); + SET v_priority_access_level_view := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.id_access_level = v_id_access_level_view); + CALL fetchmetrics.p_core_validate_guid ( a_guid ); @@ -110,7 +129,11 @@ BEGIN , a_get_inactive_metric , a_ids_metric , a_names_metric - + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met , a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met @@ -122,7 +145,9 @@ BEGIN SELECT v_id_type_error_bad_data , v_id_type_error_no_permission + , v_id_permission_command_view , v_id_permission_dog_view + , v_ids_permission_required , v_time_start ; END IF; @@ -131,6 +156,25 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_RQM; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_RQM; DROP TEMPORARY TABLE IF EXISTS tmp_Response_Quality_Metric_Calc_RQM; + DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_RQM; + + CREATE TEMPORARY TABLE tmp_Calc_User_Access_Calc_RQM ( + id_temp INT PRIMARY KEY AUTO_INCREMENT NOT NULL + , id_user INT + , id_role INT + , id_permission_required INT NOT NULL + , priority_access_level_required INT NOT NULL + , is_super_user BIT + , priority_access_level_user INT + , has_access BIT + , can_view BIT + , can_edit BIT + , can_admin BIT + , active BIT + + , does_meet_id_filters BIT + , does_meet_non_id_filters BIT + ); CREATE TEMPORARY TABLE tmp_Response_Quality_Metric_Calc_RQM ( id_metric INT NOT NULL @@ -140,6 +184,8 @@ BEGIN , value_min DOUBLE , value_max DOUBLE , active BIT + , exists_valid_link BIT NOT NULL + , id_user INT , does_meet_id_filters BIT NOT NULL , does_meet_non_id_filters BIT NOT NULL ); @@ -166,6 +212,169 @@ BEGIN SET v_has_filter_response_quality_metric_id := CASE WHEN a_ids_metric <> '' THEN 1 ELSE 0 END; SET v_has_filter_response_quality_metric_name := CASE WHEN a_names_metric <> '' THEN 1 ELSE 0 END; + -- Permissions + IF a_debug = 1 THEN + SELECT + a_guid -- a_guid + , 0 -- get_all_user + , 0 -- get_inactive_user + , a_id_user -- ids_user + , '' -- a_auth0_ids_user + , '' -- a_names_user + , '' -- a_emails_user + , 1 -- a_require_all_id_search_filters_met + , 1 -- a_require_any_id_search_filters_met + , 0 -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL fetchmetrics.p_dog_calc_user_access( + a_guid -- a_guid + , 0 -- get_all_user + , 0 -- get_inactive_user + , a_id_user -- ids_user + , '' -- a_auth0_ids_user + , '' -- a_names_user + , '' -- a_emails_user + , 1 -- a_require_all_id_search_filters_met + , 1 -- a_require_any_id_search_filters_met + , 0 -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ); + + SELECT + IFNULL(CALC_USER_T.has_access, 0) + , IFNULL(CALC_USER_T.is_super_user, 0) + INTO + v_can_view + , v_is_super_user + FROM demo.DOG_Calc_User_Access_Temp CALC_USER_T + WHERE CALC_USER_T.guid = a_guid + LIMIT 1 + ; + + IF a_debug = 1 THEN + SELECT + v_can_view + , v_is_super_user + ; + END IF; + + IF (v_can_view = 0) THEN + DELETE t_ME + FROM tmp_Msg_Error_Calc_RQM t_ME + WHERE t_ME.id_type <> v_id_type_error_no_permission + ; + INSERT INTO tmp_Msg_Error_Calc_RQM ( + id_type + , code + , msg + ) + VALUES ( + v_id_type_error_no_permission + , v_code_type_error_no_permission + , 'You do not have permission to view Dogs and Button Icons.' + ) + ; + END IF; + + CALL fetchmetrics.p_dog_clear_calc_user_access( + a_guid + , 0 -- a_debug + ); + + -- Users + IF a_debug = 1 THEN + SELECT + a_guid -- guid + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , '' -- a_auth0_ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user + , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met + , 0 -- a_require_any_id_search_filters_met + , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL demo.p_dog_calc_user_access( + a_guid-- guid + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , '' -- a_auth0_ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user + , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met + , 0 -- a_require_any_id_search_filters_met + , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ); + + INSERT INTO tmp_Calc_User_Access_Calc_RQM ( + id_user + , id_role + , id_permission_required + , priority_access_level_required + , is_super_user + , priority_access_level_user + , has_access + , can_view + , can_edit + , can_admin + , active + , does_meet_id_filters + , does_meet_non_id_filters + ) + SELECT + CALC_USER_T.id_user + , CALC_USER_T.id_role + , CALC_USER_T.id_permission_required + , CALC_USER_T.priority_access_level_required + , CALC_USER_T.is_super_user + , CALC_USER_T.priority_access_level_user + , CALC_USER_T.has_access + , CALC_USER_T.can_view + , CALC_USER_T.can_edit + , CALC_USER_T.can_admin + , CALC_USER_T.active + , CALC_USER_T.does_meet_id_filters + , CALC_USER_T.does_meet_non_id_filters + FROM demo.DOG_Calc_User_Access_Temp CALC_USER_T + WHERE CALC_USER_T.GUID = a_guid + ; + + IF a_debug = 1 THEN + SELECT 'After get many user'; + SELECT * FROM tmp_Calc_User_Access_Calc_RQM; + END IF; + + CALL demo.p_dog_clear_calc_user_access( + a_guid + , 0 -- a_debug + ); + + -- Response Quality Metrics IF v_has_filter_response_quality_metric_id = 1 THEN CALL fetchmetrics.p_core_split(a_guid, a_ids_metric, ',', a_debug); @@ -245,78 +454,6 @@ BEGIN ELSEIF EXISTS () */ ELSE - IF a_debug = 1 THEN - SELECT 'Response_Quality_Metric Filters'; - WITH - Response_Quality_Metric_Id_Filter AS ( - SELECT RESPONSE_QUALITY_METRIC.id_metric - FROM tmp_Split_Id_Calc_RQM t_SPLIT_ID - INNER JOIN fetchmetrics.DOG_Response_Quality_Metric RESPONSE_QUALITY_METRIC ON t_SPLIT_ID.as_int = RESPONSE_QUALITY_METRIC.id_metric - ) - , Response_Quality_Metric_Name_Filter AS ( - SELECT RESPONSE_QUALITY_METRIC.id_metric - FROM tmp_Split_Name_Calc_RQM t_SPLIT_NAME - INNER JOIN fetchmetrics.DOG_Response_Quality_Metric RESPONSE_QUALITY_METRIC ON RESPONSE_QUALITY_METRIC.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') - WHERE NULLIF(t_SPLIT_NAME.substring, '') IS NOT NULL - ) - , Response_Quality_Metric_Filters AS ( - SELECT - RESPONSE_QUALITY_METRIC_COMBINED.id_metric - , MAX(RESPONSE_QUALITY_METRIC_COMBINED.does_meet_id_filter) AS does_meet_id_filter - , MAX(RESPONSE_QUALITY_METRIC_COMBINED.does_meet_name_filter) AS does_meet_name_filter - FROM ( - SELECT - RESPONSE_QUALITY_METRIC_ID_FILTER.id_metric - , 1 AS does_meet_id_filter - , 0 AS does_meet_name_filter - FROM Response_Quality_Metric_Id_Filter RESPONSE_QUALITY_METRIC_ID_FILTER - UNION - SELECT - RESPONSE_QUALITY_METRIC_NAME_FILTER.id_metric - , 0 AS does_meet_id_filter - , 1 AS does_meet_name_filter - FROM Response_Quality_Metric_Name_Filter RESPONSE_QUALITY_METRIC_NAME_FILTER - ) RESPONSE_QUALITY_METRIC_COMBINED - GROUP BY RESPONSE_QUALITY_METRIC_COMBINED.id_metric - ) - SELECT - RESPONSE_QUALITY_METRIC.id_metric - , RESPONSE_QUALITY_METRIC.id_unit_measurement - , RESPONSE_QUALITY_METRIC.code - , RESPONSE_QUALITY_METRIC.name - , RESPONSE_QUALITY_METRIC.value_min - , RESPONSE_QUALITY_METRIC.value_max - , RESPONSE_QUALITY_METRIC.active - , CASE WHEN - v_has_filter_response_quality_metric_id = 0 - OR RESPONSE_QUALITY_METRIC_FILTERS.does_meet_id_filter = 1 - THEN 1 ELSE 0 END AS does_meet_id_filters - , CASE WHEN - ( - v_has_filter_response_quality_metric_name = 0 - ) - OR RESPONSE_QUALITY_METRIC_FILTERS.does_meet_name_filter = 1 - THEN 1 ELSE 0 END AS does_meet_non_id_filters - FROM fetchmetrics.DOG_Response_Quality_Metric RESPONSE_QUALITY_METRIC - LEFT JOIN Response_Quality_Metric_Filters RESPONSE_QUALITY_METRIC_FILTERS ON RESPONSE_QUALITY_METRIC.id_metric = RESPONSE_QUALITY_METRIC_FILTERS.id_metric - WHERE - ( - a_get_all_metric = 1 - OR ( - v_has_filter_response_quality_metric_id = 1 - AND RESPONSE_QUALITY_METRIC_FILTERS.does_meet_id_filter = 1 - ) - OR ( - v_has_filter_response_quality_metric_name = 0 - AND RESPONSE_QUALITY_METRIC_FILTERS.does_meet_name_filter = 1 - ) - ) - AND ( - a_get_inactive_metric = 1 - OR RESPONSE_QUALITY_METRIC.active = 1 - ) - ; - END IF; INSERT INTO tmp_Response_Quality_Metric_Calc_RQM ( id_metric , id_unit_measurement @@ -325,6 +462,8 @@ BEGIN , value_min , value_max , active + , exists_valid_link + , id_user , does_meet_id_filters , does_meet_non_id_filters ) @@ -360,6 +499,50 @@ BEGIN ) RESPONSE_QUALITY_METRIC_COMBINED GROUP BY RESPONSE_QUALITY_METRIC_COMBINED.id_metric ) + , Response_Quality_Metric_Access AS ( + SELECT + RESPONSE_QUALITY_METRIC.id_metric + , CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END AS exists_valid_link + , ROW_NUMBER() OVER ( + PARTITION BY RESPONSE_QUALITY_METRIC.id_metric + ORDER BY + CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END DESC + , t_USER.does_meet_id_filters DESC + , t_USER.does_meet_non_id_filters DESC + ) AS index_link_in_metric + , t_USER.id_user + FROM fetchmetrics.DOG_Response_Quality_Metric RESPONSE_QUALITY_METRIC + LEFT JOIN fetchmetrics.DOG_Response_Quality_Metric_User_Link RESPONSE_QUALITY_METRIC_USER_LINK + ON RESPONSE_QUALITY_METRIC.id_metric = RESPONSE_QUALITY_METRIC_USER_LINK.id_response_quality_metric + AND ( + ( + a_get_inactive_metric = 1 + AND a_get_inactive_user = 1 + ) + OR RESPONSE_QUALITY_METRIC_USER_LINK.active = 1 + ) + LEFT JOIN tmp_Calc_User_Access_Calc_RQM t_USER + ON RESPONSE_QUALITY_METRIC_USER_LINK.id_user = t_USER.id_user + AND ( + a_get_inactive_user = 1 + OR t_USER.active = 1 + ) + LEFT JOIN fetchmetrics.DOG_Access_Level ACCESS_LEVEL + ON RESPONSE_QUALITY_METRIC_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level + AND ACCESS_LEVEL.active = 1 + ) SELECT RESPONSE_QUALITY_METRIC.id_metric , RESPONSE_QUALITY_METRIC.id_unit_measurement @@ -368,6 +551,8 @@ BEGIN , RESPONSE_QUALITY_METRIC.value_min , RESPONSE_QUALITY_METRIC.value_max , RESPONSE_QUALITY_METRIC.active + , IFNULL(RESPONSE_QUALITY_METRIC_ACCESS.exists_valid_link, 0) AS exists_valid_link + , RESPONSE_QUALITY_METRIC_ACCESS.id_user , CASE WHEN v_has_filter_response_quality_metric_id = 0 OR RESPONSE_QUALITY_METRIC_FILTERS.does_meet_id_filter = 1 @@ -380,6 +565,9 @@ BEGIN THEN 1 ELSE 0 END AS does_meet_non_id_filters FROM fetchmetrics.DOG_Response_Quality_Metric RESPONSE_QUALITY_METRIC LEFT JOIN Response_Quality_Metric_Filters RESPONSE_QUALITY_METRIC_FILTERS ON RESPONSE_QUALITY_METRIC.id_metric = RESPONSE_QUALITY_METRIC_FILTERS.id_metric + LEFT JOIN Response_Quality_Metric_Access RESPONSE_QUALITY_METRIC_ACCESS + ON RESPONSE_QUALITY_METRIC.id_metric = RESPONSE_QUALITY_METRIC_ACCESS.id_metric + AND RESPONSE_QUALITY_METRIC_ACCESS.index_link_in_metric = 1 WHERE ( a_get_all_metric = 1 @@ -392,6 +580,7 @@ BEGIN AND RESPONSE_QUALITY_METRIC_FILTERS.does_meet_name_filter = 1 ) ) + AND IFNULL(RESPONSE_QUALITY_METRIC_ACCESS.exists_valid_link, 0) = 1 AND ( a_get_inactive_metric = 1 OR RESPONSE_QUALITY_METRIC.active = 1 @@ -411,26 +600,43 @@ BEGIN IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_RQM t_ERROR INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN DELETE t_RESPONSE_QUALITY_METRIC FROM tmp_Response_Quality_Metric_Calc_RQM t_RESPONSE_QUALITY_METRIC + LEFT JOIN tmp_Calc_User_Access_Calc_RQM t_USER ON t_RESPONSE_QUALITY_METRIC.id_user = t_USER.id_user WHERE ( a_require_all_id_search_filters_met = 1 AND ( t_RESPONSE_QUALITY_METRIC.does_meet_id_filters = 0 + OR ( + t_RESPONSE_QUALITY_METRIC.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 + ) ) ) OR ( a_require_all_non_id_search_filters_met = 1 AND ( t_RESPONSE_QUALITY_METRIC.does_meet_non_id_filters = 0 + OR ( + t_RESPONSE_QUALITY_METRIC.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 + ) ) ) OR ( a_require_any_id_search_filters_met = 1 AND t_RESPONSE_QUALITY_METRIC.does_meet_id_filters = 0 + AND ( + t_RESPONSE_QUALITY_METRIC.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 + ) ) OR ( a_require_any_non_id_search_filters_met = 1 AND t_RESPONSE_QUALITY_METRIC.does_meet_non_id_filters = 0 + AND ( + t_RESPONSE_QUALITY_METRIC.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 + ) ) ; END IF; @@ -441,80 +647,6 @@ BEGIN END IF; - -- Permissions - IF a_debug = 1 THEN - SELECT - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ; - END IF; - - CALL fetchmetrics.p_dog_calc_user_access( - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ); - - SELECT - IFNULL(CALC_USER_T.has_access, 0) - INTO - v_can_view - FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T - WHERE CALC_USER_T.GUID = a_guid - LIMIT 1 - ; - - IF a_debug = 1 THEN - SELECT v_can_view; - END IF; - - IF (v_can_view = 0) THEN - DELETE t_ME - FROM tmp_Msg_Error_Calc_RQM t_ME - WHERE t_ME.id_type <> v_id_type_error_no_permission - ; - INSERT INTO tmp_Msg_Error_Calc_RQM ( - id_type - , code - , msg - ) - VALUES ( - v_id_type_error_no_permission - , v_code_type_error_no_permission - , 'You do not have permission to view Dogs and Button Icons.' - ) - ; - END IF; - - CALL fetchmetrics.p_dog_clear_calc_user_access( - a_guid - , 0 -- a_debug - ); IF a_debug = 1 THEN SELECT 'Before non-permitted data deletion'; @@ -597,6 +729,7 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_RQM; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_RQM; DROP TEMPORARY TABLE IF EXISTS tmp_Response_Quality_Metric_Calc_RQM; + DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_RQM; IF a_debug = 1 THEN CALL fetchmetrics.p_core_debug_timing_reporting ( v_time_start ); @@ -614,6 +747,11 @@ CALL fetchmetrics.p_dog_calc_response_quality_metric ( , 0 -- a_get_inactive_metric , '' -- a_ids_metric , '' -- a_names_metric + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , '' -- a_names_user + , '' -- a_emails_user , 0 -- a_require_all_id_search_filters_met , 0 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met diff --git a/static/MySQL/71332_p_dog_get_many_response_quality_metric.sql b/static/MySQL/71332_p_dog_get_many_response_quality_metric.sql index 01995c6..471e905 100644 --- a/static/MySQL/71332_p_dog_get_many_response_quality_metric.sql +++ b/static/MySQL/71332_p_dog_get_many_response_quality_metric.sql @@ -10,6 +10,11 @@ CREATE PROCEDURE fetchmetrics.p_dog_get_many_response_quality_metric ( , IN a_get_inactive_response_quality_metric BIT , IN a_ids_response_quality_metric TEXT , IN a_names_response_quality_metric TEXT + , IN a_get_all_user BIT + , IN a_get_inactive_user BIT + , IN a_ids_user TEXT + , IN a_names_user TEXT + , IN a_emails_user TEXT , IN a_require_all_id_search_filters_met BIT , IN a_require_any_id_search_filters_met BIT , IN a_require_all_non_id_search_filters_met BIT @@ -23,7 +28,6 @@ BEGIN DECLARE v_guid BINARY(36); DECLARE v_id_access_level_view INT; DECLARE v_id_minimum INT; - DECLARE v_id_permission_dog_view INT; DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; DECLARE v_time_start TIMESTAMP(6); @@ -81,20 +85,9 @@ BEGIN SET v_code_type_error_no_permission := 'NO_PERMISSION'; SET v_id_type_error_bad_data := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_bad_data LIMIT 1); SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); - SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1); SET a_id_user := IFNULL(a_id_user, 0); - /* - SET a_get_all_response_quality_metric := IFNULL(a_get_all_response_quality_metric, 0); - SET a_get_inactive_response_quality_metric := IFNULL(a_get_inactive_response_quality_metric, 0); - SET a_ids_response_quality_metric := TRIM(IFNULL(a_ids_response_quality_metric, '')); - SET a_names_response_quality_metric := TRIM(IFNULL(a_names_response_quality_metric, '')); - SET a_require_all_id_search_filters_met := IFNULL(a_require_all_id_search_filters_met, 1); - SET a_require_any_id_search_filters_met := IFNULL(a_require_any_id_search_filters_met, 1); - SET a_require_all_non_id_search_filters_met := IFNULL(a_require_all_non_id_search_filters_met, 0); - SET a_require_any_non_id_search_filters_met := IFNULL(a_require_any_non_id_search_filters_met, 1); - */ SET a_debug := IFNULL(a_debug, 0); IF a_debug = 1 THEN @@ -104,6 +97,11 @@ BEGIN , a_get_inactive_response_quality_metric , a_ids_response_quality_metric , a_names_response_quality_metric + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met , a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met @@ -115,7 +113,6 @@ BEGIN v_id_type_error_bad_data , v_id_type_error_no_permission , v_guid - , v_id_permission_dog_view , v_time_start ; END IF; @@ -142,83 +139,6 @@ BEGIN , msg TEXT NOT NULL ); - -- Permissions - IF a_debug = 1 THEN - SELECT - v_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ; - END IF; - - CALL fetchmetrics.p_dog_calc_user_access( - v_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ); - - SELECT - IFNULL(CALC_USER_T.has_access, 0) - INTO - v_can_view - FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T - WHERE CALC_USER_T.GUID = v_guid - LIMIT 1 - ; - - IF a_debug = 1 THEN - SELECT v_can_view; - SELECT COUNT(*) AS Count_Errors FROM tmp_Msg_Error t_ERROR; - SELECT * FROM tmp_Msg_Error t_ERROR; - END IF; - - IF (v_can_view = 0) THEN - DELETE t_ME - FROM tmp_Msg_Error t_ME - WHERE t_ME.id_type <> v_id_type_error_no_permission - ; - INSERT INTO tmp_Msg_Error ( - id_type - , code - , msg - ) - VALUES ( - v_id_type_error_no_permission - , v_code_type_error_no_permission - , 'You do not have permission to view RESPONSE_QUALITY_METRIC.' - ) - ; - END IF; - - CALL fetchmetrics.p_dog_clear_calc_user_access( - v_guid - , 0 -- a_debug - ); - -- Call Response_Quality_Metric Calc IF NOT EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN @@ -230,6 +150,11 @@ BEGIN , a_get_inactive_response_quality_metric -- a_get_inactive_response_quality_metric , a_ids_response_quality_metric -- a_ids_response_quality_metric , a_names_response_quality_metric -- a_names_response_quality_metric + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -246,6 +171,11 @@ BEGIN , a_get_inactive_response_quality_metric -- a_get_inactive_response_quality_metric , a_ids_response_quality_metric -- a_ids_response_quality_metric , a_names_response_quality_metric -- a_names_response_quality_metric + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -291,16 +221,6 @@ BEGIN END IF; END IF; - -- Filter outputs - IF EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN - IF a_debug = 1 THEN - SELECT * FROM tmp_Response_Quality_Metric; - END IF; - - DELETE FROM tmp_Response_Quality_Metric; - END IF; - - -- Outputs -- RESPONSE_QUALITY_METRIC SELECT @@ -365,6 +285,11 @@ CALL fetchmetrics.p_dog_get_many_response_quality_metric ( , 0 -- a_get_inactive_response_quality_metric , '' -- a_ids_response_quality_metric , '' -- a_names_response_quality_metric + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , '' -- a_names_user + , '' -- a_emails_user , 1 -- a_require_all_id_search_filters_met , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met @@ -379,6 +304,11 @@ CALL fetchmetrics.p_dog_get_many_response_quality_metric ( , 0 -- a_get_inactive_response_quality_metric , '' -- a_ids_response_quality_metric , 'pat,point' -- a_names_response_quality_metric + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , '' -- a_names_user + , '' -- a_emails_user , 1 -- a_require_all_id_search_filters_met , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met diff --git a/static/MySQL/71336_p_dog_calc_obedience_level.sql b/static/MySQL/71336_p_dog_calc_obedience_level.sql index 8696ba3..9677df0 100644 --- a/static/MySQL/71336_p_dog_calc_obedience_level.sql +++ b/static/MySQL/71336_p_dog_calc_obedience_level.sql @@ -11,6 +11,11 @@ CREATE PROCEDURE fetchmetrics.p_dog_calc_obedience_level ( , IN a_get_inactive_obedience_level BIT , IN a_ids_obedience_level TEXT , IN a_names_obedience_level TEXT + , IN a_get_all_user BIT + , IN a_get_inactive_user BIT + , IN a_ids_user TEXT + , IN a_names_user TEXT + , IN a_emails_user TEXT , IN a_require_all_id_search_filters_met BIT , IN a_require_any_id_search_filters_met BIT , IN a_require_all_non_id_search_filters_met BIT @@ -26,9 +31,14 @@ BEGIN DECLARE v_has_filter_obedience_level_name BIT; DECLARE v_id_access_level_view INT; DECLARE v_id_minimum INT; + DECLARE v_id_permission_command_view INT; DECLARE v_id_permission_dog_view INT; DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; + DECLARE v_ids_permission_required VARCHAR(200); + DECLARE v_is_super_user BIT; + DECLARE v_priority_access_level_none INT; + DECLARE v_priority_access_level_view INT; DECLARE v_time_start TIMESTAMP(6); DECLARE exit handler for SQLEXCEPTION @@ -83,9 +93,17 @@ BEGIN SET v_code_type_error_no_permission := 'NO_PERMISSION'; SET v_id_type_error_bad_data := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_bad_data LIMIT 1); SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); + SET v_id_permission_command_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'COMMAND_VIEW' LIMIT 1); SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1); - + SET v_ids_permission_required := (SELECT CONCAT( + CONVERT(v_id_permission_dog_view, CHAR) + , ',' + , CONVERT(v_id_permission_command_view, CHAR) + )); + SET v_priority_access_level_none := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'NONE' LIMIT 1); + SET v_priority_access_level_view := (SELECT ACCESS_LEVEL.priority FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.id_access_level = v_id_access_level_view); + CALL fetchmetrics.p_core_validate_guid ( a_guid ); @@ -109,6 +127,10 @@ BEGIN , a_get_inactive_obedience_level , a_ids_obedience_level , a_names_obedience_level + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met , a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met @@ -120,7 +142,9 @@ BEGIN SELECT v_id_type_error_bad_data , v_id_type_error_no_permission + , v_id_permission_command_view , v_id_permission_dog_view + , v_ids_permission_required , v_time_start ; END IF; @@ -129,9 +153,30 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_Obedience_Level; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_Obedience_Level; DROP TEMPORARY TABLE IF EXISTS tmp_Obedience_Level_Calc_Obedience_Level; + DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_Obedience_Level; + + CREATE TEMPORARY TABLE tmp_Calc_User_Access_Calc_Obedience_Level ( + id_temp INT PRIMARY KEY AUTO_INCREMENT NOT NULL + , id_user INT + , id_role INT + , id_permission_required INT NOT NULL + , priority_access_level_required INT NOT NULL + , is_super_user BIT + , priority_access_level_user INT + , has_access BIT + , can_view BIT + , can_edit BIT + , can_admin BIT + , active BIT + + , does_meet_id_filters BIT + , does_meet_non_id_filters BIT + ); CREATE TEMPORARY TABLE tmp_Obedience_Level_Calc_Obedience_Level ( id_obedience_level INT NOT NULL + , exists_valid_link BIT NOT NULL + , id_user INT , does_meet_id_filters BIT NOT NULL , does_meet_non_id_filters BIT NOT NULL ); @@ -158,6 +203,170 @@ BEGIN SET v_has_filter_obedience_level_id = CASE WHEN a_ids_obedience_level <> '' THEN 1 ELSE 0 END; SET v_has_filter_obedience_level_name = CASE WHEN a_names_obedience_level <> '' THEN 1 ELSE 0 END; + + -- Permissions + IF a_debug = 1 THEN + SELECT + a_guid -- a_guid + , 0 -- get_all_user + , 0 -- get_inactive_user + , a_id_user -- ids_user + , '' -- a_auth0_ids_user + , '' -- a_names_user + , '' -- a_emails_user + , 1 -- a_require_all_id_search_filters_met + , 1 -- a_require_any_id_search_filters_met + , 0 -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL fetchmetrics.p_dog_calc_user_access( + a_guid -- a_guid + , 0 -- get_all_user + , 0 -- get_inactive_user + , a_id_user -- ids_user + , '' -- a_auth0_ids_user + , '' -- a_names_user + , '' -- a_emails_user + , 1 -- a_require_all_id_search_filters_met + , 1 -- a_require_any_id_search_filters_met + , 0 -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ); + + SELECT + IFNULL(CALC_USER_T.has_access, 0) + , IFNULL(CALC_USER_T.is_super_user, 0) + INTO + v_can_view + , v_is_super_user + FROM demo.DOG_Calc_User_Access_Temp CALC_USER_T + WHERE CALC_USER_T.guid = a_guid + LIMIT 1 + ; + + IF a_debug = 1 THEN + SELECT + v_can_view + , v_is_super_user + ; + END IF; + + IF (v_can_view = 0) THEN + DELETE t_ME + FROM tmp_Msg_Error_Calc_Obedience_Level t_ME + WHERE t_ME.id_type <> v_id_type_error_no_permission + ; + INSERT INTO tmp_Msg_Error_Calc_Obedience_Level ( + id_type + , code + , msg + ) + VALUES ( + v_id_type_error_no_permission + , v_code_type_error_no_permission + , 'You do not have permission to view Dogs and Obedience_Levels.' + ) + ; + END IF; + + CALL fetchmetrics.p_dog_clear_calc_user_access( + a_guid + , 0 -- a_debug + ); + + -- Users + IF a_debug = 1 THEN + SELECT + a_guid -- guid + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , '' -- a_auth0_ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user + , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met + , 0 -- a_require_any_id_search_filters_met + , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL demo.p_dog_calc_user_access( + a_guid-- guid + , a_get_all_user -- get_all_user + , a_get_inactive_user -- get_inactive_user + , a_ids_user -- ids_user + , '' -- a_auth0_ids_user + , a_names_user -- a_names_user + , a_emails_user -- a_emails_user + , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met + , 0 -- a_require_any_id_search_filters_met + , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met + , 0 -- a_require_any_non_id_search_filters_met + , v_ids_permission_required -- ids_permission + , v_id_access_level_view -- ids_access_level + , 0 -- a_show_errors + , 0 -- a_debug + ); + + INSERT INTO tmp_Calc_User_Access_Calc_Obedience_Level ( + id_user + , id_role + , id_permission_required + , priority_access_level_required + , is_super_user + , priority_access_level_user + , has_access + , can_view + , can_edit + , can_admin + , active + , does_meet_id_filters + , does_meet_non_id_filters + ) + SELECT + CALC_USER_T.id_user + , CALC_USER_T.id_role + , CALC_USER_T.id_permission_required + , CALC_USER_T.priority_access_level_required + , CALC_USER_T.is_super_user + , CALC_USER_T.priority_access_level_user + , CALC_USER_T.has_access + , CALC_USER_T.can_view + , CALC_USER_T.can_edit + , CALC_USER_T.can_admin + , CALC_USER_T.active + , CALC_USER_T.does_meet_id_filters + , CALC_USER_T.does_meet_non_id_filters + FROM demo.DOG_Calc_User_Access_Temp CALC_USER_T + WHERE CALC_USER_T.GUID = a_guid + ; + + IF a_debug = 1 THEN + SELECT 'After get many user'; + SELECT * FROM tmp_Calc_User_Access_Calc_Obedience_Level; + END IF; + + CALL demo.p_dog_clear_calc_user_access( + a_guid + , 0 -- a_debug + ); + + -- Obedience_Levels IF v_has_filter_obedience_level_id = 1 THEN CALL fetchmetrics.p_core_split(a_guid, a_ids_obedience_level, ',', a_debug); @@ -205,12 +414,12 @@ BEGIN IF EXISTS ( SELECT * FROM tmp_Split_Id_Calc_Obedience_Level t_SPLIT_ID - LEFT JOIN fetchmetrics.DOG_Obedience_Level OBEDIENCE_LEVELS ON t_SPLIT_ID.as_int = OBEDIENCE_LEVELS.id_obedience_level + LEFT JOIN fetchmetrics.DOG_Obedience_Level OBEDIENCE_LEVEL ON t_SPLIT_ID.as_int = OBEDIENCE_LEVEL.id_obedience_level WHERE ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(OBEDIENCE_LEVELS.id_obedience_level) + OR ISNULL(OBEDIENCE_LEVEL.id_obedience_level) OR ( - OBEDIENCE_LEVELS.active = 0 + OBEDIENCE_LEVEL.active = 0 AND a_get_inactive_obedience_level = 0 ) ) THEN @@ -224,12 +433,12 @@ BEGIN , v_code_type_error_bad_data , CONCAT('Invalid or inactive Obedience_Level IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT_ID.substring SEPARATOR ', '), 'NULL')) FROM tmp_Split_Id_Calc_Obedience_Level t_SPLIT_ID - LEFT JOIN fetchmetrics.DOG_Obedience_Level OBEDIENCE_LEVELS ON t_SPLIT_ID.as_int = OBEDIENCE_LEVELS.id_obedience_level + LEFT JOIN fetchmetrics.DOG_Obedience_Level OBEDIENCE_LEVEL ON t_SPLIT_ID.as_int = OBEDIENCE_LEVEL.id_obedience_level WHERE ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(OBEDIENCE_LEVELS.id_obedience_level) + OR ISNULL(OBEDIENCE_LEVEL.id_obedience_level) OR ( - OBEDIENCE_LEVELS.active = 0 + OBEDIENCE_LEVEL.active = 0 AND a_get_inactive_obedience_level = 0 ) ; @@ -239,70 +448,122 @@ BEGIN ELSE INSERT INTO tmp_Obedience_Level_Calc_Obedience_Level ( id_obedience_level + , exists_valid_link + , id_user , does_meet_id_filters , does_meet_non_id_filters ) WITH Obedience_Level_Id_Filter AS ( - SELECT OBEDIENCE_LEVELS.id_obedience_level + SELECT OBEDIENCE_LEVEL.id_obedience_level FROM tmp_Split_Id_Calc_Obedience_Level t_SPLIT_ID - INNER JOIN fetchmetrics.DOG_Obedience_Level OBEDIENCE_LEVELS ON t_SPLIT_ID.as_int = OBEDIENCE_LEVELS.id_obedience_level + INNER JOIN fetchmetrics.DOG_Obedience_Level OBEDIENCE_LEVEL ON t_SPLIT_ID.as_int = OBEDIENCE_LEVEL.id_obedience_level ) , Obedience_Level_Name_Filter AS ( - SELECT OBEDIENCE_LEVELS.id_obedience_level + SELECT OBEDIENCE_LEVEL.id_obedience_level FROM tmp_Split_Name_Calc_Obedience_Level t_SPLIT_NAME - INNER JOIN fetchmetrics.DOG_Obedience_Level OBEDIENCE_LEVELS ON OBEDIENCE_LEVELS.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') + INNER JOIN fetchmetrics.DOG_Obedience_Level OBEDIENCE_LEVEL ON OBEDIENCE_LEVEL.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') WHERE NULLIF(t_SPLIT_NAME.substring, '') IS NOT NULL ) , Obedience_Level_Filters AS ( SELECT - OBEDIENCE_LEVELS_COMBINED.id_obedience_level - , MAX(OBEDIENCE_LEVELS_COMBINED.does_meet_id_filter) AS does_meet_id_filter - , MAX(OBEDIENCE_LEVELS_COMBINED.does_meet_name_filter) AS does_meet_name_filter + OBEDIENCE_LEVEL_COMBINED.id_obedience_level + , MAX(OBEDIENCE_LEVEL_COMBINED.does_meet_id_filter) AS does_meet_id_filter + , MAX(OBEDIENCE_LEVEL_COMBINED.does_meet_name_filter) AS does_meet_name_filter FROM ( SELECT - OBEDIENCE_LEVELS_ID_FILTER.id_obedience_level + OBEDIENCE_LEVEL_ID_FILTER.id_obedience_level , 1 AS does_meet_id_filter , 0 AS does_meet_name_filter - FROM Obedience_Level_Id_Filter OBEDIENCE_LEVELS_ID_FILTER + FROM Obedience_Level_Id_Filter OBEDIENCE_LEVEL_ID_FILTER UNION SELECT - OBEDIENCE_LEVELS_NAME_FILTER.id_obedience_level + OBEDIENCE_LEVEL_NAME_FILTER.id_obedience_level , 0 AS does_meet_id_filter , 1 AS does_meet_name_filter - FROM Obedience_Level_Name_Filter OBEDIENCE_LEVELS_NAME_FILTER - ) OBEDIENCE_LEVELS_COMBINED - GROUP BY OBEDIENCE_LEVELS_COMBINED.id_obedience_level + FROM Obedience_Level_Name_Filter OBEDIENCE_LEVEL_NAME_FILTER + ) OBEDIENCE_LEVEL_COMBINED + GROUP BY OBEDIENCE_LEVEL_COMBINED.id_obedience_level + ) + , Obedience_Level_Access AS ( + SELECT + OBEDIENCE_LEVEL.id_obedience_level + , CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END AS exists_valid_link + , ROW_NUMBER() OVER ( + PARTITION BY OBEDIENCE_LEVEL.id_obedience_level + ORDER BY + CASE WHEN + v_is_super_user = 1 + OR ( + t_USER.id_user IS NOT NULL + AND IFNULL(ACCESS_LEVEL.priority, v_priority_access_level_none) <= v_priority_access_level_view + ) + THEN 1 ELSE 0 END DESC + , t_USER.does_meet_id_filters DESC + , t_USER.does_meet_non_id_filters DESC + ) AS index_link_in_obedience_level + , t_USER.id_user + FROM fetchmetrics.DOG_Obedience_Level OBEDIENCE_LEVEL + LEFT JOIN fetchmetrics.DOG_Obedience_Level_User_Link OBEDIENCE_LEVEL_USER_LINK + ON OBEDIENCE_LEVEL.id_obedience_level = OBEDIENCE_LEVEL_USER_LINK.id_obedience_level + AND ( + ( + a_get_inactive_obedience_level = 1 + AND a_get_inactive_user = 1 + ) + OR OBEDIENCE_LEVEL_USER_LINK.active = 1 + ) + LEFT JOIN tmp_Calc_User_Access_Calc_Obedience_Level t_USER + ON OBEDIENCE_LEVEL_USER_LINK.id_user = t_USER.id_user + AND ( + a_get_inactive_user = 1 + OR t_USER.active = 1 + ) + LEFT JOIN fetchmetrics.DOG_Access_Level ACCESS_LEVEL + ON OBEDIENCE_LEVEL_USER_LINK.id_access_level = ACCESS_LEVEL.id_access_level + AND ACCESS_LEVEL.active = 1 ) SELECT - OBEDIENCE_LEVELS.id_obedience_level + OBEDIENCE_LEVEL.id_obedience_level + , IFNULL(OBEDIENCE_LEVEL_ACCESS.exists_valid_link, 0) AS exists_valid_link + , OBEDIENCE_LEVEL_ACCESS.id_user , CASE WHEN v_has_filter_obedience_level_id = 0 - OR IFNULL(OBEDIENCE_LEVELS_FILTERS.does_meet_id_filter, 0) = 1 + OR IFNULL(OBEDIENCE_LEVEL_FILTERS.does_meet_id_filter, 0) = 1 THEN 1 ELSE 0 END AS does_meet_id_filters , CASE WHEN ( v_has_filter_obedience_level_name = 0 ) - OR IFNULL(OBEDIENCE_LEVELS_FILTERS.does_meet_name_filter, 0) = 1 + OR IFNULL(OBEDIENCE_LEVEL_FILTERS.does_meet_name_filter, 0) = 1 THEN 1 ELSE 0 END AS does_meet_non_id_filters - FROM fetchmetrics.DOG_Obedience_Level OBEDIENCE_LEVELS - LEFT JOIN Obedience_Level_Filters OBEDIENCE_LEVELS_FILTERS ON OBEDIENCE_LEVELS.id_obedience_level = OBEDIENCE_LEVELS_FILTERS.id_obedience_level + FROM fetchmetrics.DOG_Obedience_Level OBEDIENCE_LEVEL + LEFT JOIN Obedience_Level_Filters OBEDIENCE_LEVEL_FILTERS ON OBEDIENCE_LEVEL.id_obedience_level = OBEDIENCE_LEVEL_FILTERS.id_obedience_level + LEFT JOIN Obedience_Level_Access OBEDIENCE_LEVEL_ACCESS + ON OBEDIENCE_LEVEL.id_obedience_level = OBEDIENCE_LEVEL_ACCESS.id_obedience_level + AND OBEDIENCE_LEVEL_ACCESS.index_link_in_obedience_level = 1 WHERE ( a_get_all_obedience_level = 1 OR ( v_has_filter_obedience_level_id = 1 - AND OBEDIENCE_LEVELS_FILTERS.does_meet_id_filter = 1 + AND OBEDIENCE_LEVEL_FILTERS.does_meet_id_filter = 1 ) OR ( v_has_filter_obedience_level_name = 1 - AND OBEDIENCE_LEVELS_FILTERS.does_meet_name_filter = 1 + AND OBEDIENCE_LEVEL_FILTERS.does_meet_name_filter = 1 ) ) + AND IFNULL(OBEDIENCE_LEVEL_ACCESS.exists_valid_link, 0) = 1 AND ( a_get_inactive_obedience_level = 1 - OR OBEDIENCE_LEVELS.active = 1 + OR OBEDIENCE_LEVEL.active = 1 ) ; END IF; @@ -318,28 +579,45 @@ BEGIN -- Filter records IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Obedience_Level t_ERROR INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN - DELETE t_OBEDIENCE_LEVELS - FROM tmp_Obedience_Level_Calc_Obedience_Level t_OBEDIENCE_LEVELS + DELETE t_OBEDIENCE_LEVEL + FROM tmp_Obedience_Level_Calc_Obedience_Level t_OBEDIENCE_LEVEL + LEFT JOIN tmp_Calc_User_Access_Calc_Obedience_Level t_USER ON t_OBEDIENCE_LEVEL.id_user = t_USER.id_user WHERE ( a_require_all_id_search_filters_met = 1 AND ( - t_OBEDIENCE_LEVELS.does_meet_id_filters = 0 + t_OBEDIENCE_LEVEL.does_meet_id_filters = 0 + OR ( + t_OBEDIENCE_LEVEL.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 + ) ) ) OR ( a_require_all_non_id_search_filters_met = 1 AND ( - t_OBEDIENCE_LEVELS.does_meet_non_id_filters = 0 + t_OBEDIENCE_LEVEL.does_meet_non_id_filters = 0 + OR ( + t_OBEDIENCE_LEVEL.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 + ) ) ) OR ( a_require_any_id_search_filters_met = 1 - AND t_OBEDIENCE_LEVELS.does_meet_id_filters = 0 + AND t_OBEDIENCE_LEVEL.does_meet_id_filters = 0 + AND ( + t_OBEDIENCE_LEVEL.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_id_filters, 0) = 0 + ) ) OR ( a_require_any_non_id_search_filters_met = 1 - AND t_OBEDIENCE_LEVELS.does_meet_non_id_filters = 0 + AND t_OBEDIENCE_LEVEL.does_meet_non_id_filters = 0 + AND ( + t_OBEDIENCE_LEVEL.exists_valid_link = 0 + AND IFNULL(t_USER.does_meet_non_id_filters, 0) = 0 + ) ) ; END IF; @@ -351,81 +629,6 @@ BEGIN -- Calculated fields - -- Permissions - IF a_debug = 1 THEN - SELECT - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ; - END IF; - - CALL fetchmetrics.p_dog_calc_user_access( - a_guid -- a_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ); - - SELECT - IFNULL(CALC_USER_T.has_access, 0) - INTO - v_can_view - FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T - WHERE CALC_USER_T.GUID = a_guid - LIMIT 1 - ; - - IF a_debug = 1 THEN - SELECT v_can_view; - END IF; - - IF (v_can_view = 0) THEN - DELETE t_ME - FROM tmp_Msg_Error_Calc_Obedience_Level t_ME - WHERE t_ME.id_type <> v_id_type_error_no_permission - ; - INSERT INTO tmp_Msg_Error_Calc_Obedience_Level ( - id_type - , code - , msg - ) - VALUES ( - v_id_type_error_no_permission - , v_code_type_error_no_permission - , 'You do not have permission to view Dogs and Obedience_Levels.' - ) - ; - END IF; - - CALL fetchmetrics.p_dog_clear_calc_user_access( - a_guid - , 0 -- a_debug - ); - IF a_debug = 1 THEN SELECT 'Before non-permitted data deletion'; SELECT * FROM tmp_Obedience_Level_Calc_Obedience_Level; @@ -459,16 +662,16 @@ BEGIN ) SELECT a_guid - , t_OBEDIENCE_LEVELS.id_obedience_level - , OBEDIENCE_LEVELS.code - , OBEDIENCE_LEVELS.name - , OBEDIENCE_LEVELS.active + , t_OBEDIENCE_LEVEL.id_obedience_level + , OBEDIENCE_LEVEL.code + , OBEDIENCE_LEVEL.name + , OBEDIENCE_LEVEL.active - , t_OBEDIENCE_LEVELS.does_meet_id_filters - , t_OBEDIENCE_LEVELS.does_meet_non_id_filters - FROM fetchmetrics.DOG_Obedience_Level OBEDIENCE_LEVELS - INNER JOIN tmp_Obedience_Level_Calc_Obedience_Level t_OBEDIENCE_LEVELS ON OBEDIENCE_LEVELS.id_obedience_level = t_OBEDIENCE_LEVELS.id_obedience_level - ORDER BY OBEDIENCE_LEVELS.name + , t_OBEDIENCE_LEVEL.does_meet_id_filters + , t_OBEDIENCE_LEVEL.does_meet_non_id_filters + FROM fetchmetrics.DOG_Obedience_Level OBEDIENCE_LEVEL + INNER JOIN tmp_Obedience_Level_Calc_Obedience_Level t_OBEDIENCE_LEVEL ON OBEDIENCE_LEVEL.id_obedience_level = t_OBEDIENCE_LEVEL.id_obedience_level + ORDER BY OBEDIENCE_LEVEL.name ; COMMIT; @@ -499,6 +702,7 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_Obedience_Level; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_Obedience_Level; DROP TEMPORARY TABLE IF EXISTS tmp_Obedience_Level_Calc_Obedience_Level; + DROP TEMPORARY TABLE IF EXISTS tmp_Calc_User_Access_Calc_Obedience_Level; IF a_debug = 1 THEN CALL fetchmetrics.p_core_debug_timing_reporting ( v_time_start ); @@ -517,6 +721,11 @@ CALL fetchmetrics.p_dog_calc_obedience_level ( , 0 -- a_get_inactive_obedience_level , '' -- a_ids_obedience_level , '' -- a_names_obedience_level + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , '' -- a_names_user + , '' -- a_emails_user , 0 -- a_require_all_id_search_filters_met , 0 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met diff --git a/static/MySQL/71336_p_dog_get_many_obedience_level.sql b/static/MySQL/71336_p_dog_get_many_obedience_level.sql index 125445c..ff6212c 100644 --- a/static/MySQL/71336_p_dog_get_many_obedience_level.sql +++ b/static/MySQL/71336_p_dog_get_many_obedience_level.sql @@ -10,6 +10,11 @@ CREATE PROCEDURE fetchmetrics.p_dog_get_many_obedience_level ( , IN a_get_inactive_obedience_level BIT , IN a_ids_obedience_level TEXT , IN a_names_obedience_level TEXT + , IN a_get_all_user BIT + , IN a_get_inactive_user BIT + , IN a_ids_user TEXT + , IN a_names_user TEXT + , IN a_emails_user TEXT , IN a_require_all_id_search_filters_met BIT , IN a_require_any_id_search_filters_met BIT , IN a_require_all_non_id_search_filters_met BIT @@ -22,8 +27,6 @@ BEGIN DECLARE v_code_type_error_no_permission VARCHAR(100); DECLARE v_guid BINARY(36); DECLARE v_id_access_level_view INT; - DECLARE v_id_minimum INT; - DECLARE v_id_permission_dog_view INT; DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; DECLARE v_time_start TIMESTAMP(6); @@ -81,7 +84,6 @@ BEGIN SET v_code_type_error_no_permission := 'NO_PERMISSION'; SET v_id_type_error_bad_data := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_bad_data LIMIT 1); SET v_id_type_error_no_permission := (SELECT ERROR_TYPE.id_type FROM fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); - SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM fetchmetrics.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); SET v_id_access_level_view := (SELECT ACCESS_LEVEL.id_access_level FROM fetchmetrics.DOG_Access_Level ACCESS_LEVEL WHERE ACCESS_LEVEL.code = 'VIEW' LIMIT 1); SET a_id_user := IFNULL(a_id_user, 0); @@ -115,7 +117,6 @@ BEGIN v_id_type_error_bad_data , v_id_type_error_no_permission , v_guid - , v_id_permission_dog_view , v_time_start ; END IF; @@ -140,83 +141,6 @@ BEGIN , msg TEXT NOT NULL ); - -- Permissions - IF a_debug = 1 THEN - SELECT - v_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ; - END IF; - - CALL fetchmetrics.p_dog_calc_user_access( - v_guid - , 0 -- get_all_user - , 0 -- get_inactive_user - , a_id_user -- ids_user - , '' -- a_auth0_ids_user - , '' -- a_names_user - , '' -- a_emails_user - , 1 -- a_require_all_id_search_filters_met - , 1 -- a_require_any_id_search_filters_met - , 0 -- a_require_all_non_id_search_filters_met - , 0 -- a_require_any_non_id_search_filters_met - , v_id_permission_dog_view -- ids_permission - , v_id_access_level_view -- ids_access_level - , 0 -- a_show_errors - , 0 -- a_debug - ); - - SELECT - IFNULL(CALC_USER_T.has_access, 0) - INTO - v_can_view - FROM fetchmetrics.DOG_Calc_User_Access_Temp CALC_USER_T - WHERE CALC_USER_T.GUID = v_guid - LIMIT 1 - ; - - IF a_debug = 1 THEN - SELECT v_can_view; - SELECT COUNT(*) AS Count_Errors FROM tmp_Msg_Error t_ERROR; - SELECT * FROM tmp_Msg_Error t_ERROR; - END IF; - - IF (v_can_view = 0) THEN - DELETE t_ME - FROM tmp_Msg_Error t_ME - WHERE t_ME.id_type <> v_id_type_error_no_permission - ; - INSERT INTO tmp_Msg_Error ( - id_type - , code - , msg - ) - VALUES ( - v_id_type_error_no_permission - , v_code_type_error_no_permission - , 'You do not have permission to view Obedience_Levels.' - ) - ; - END IF; - - CALL fetchmetrics.p_dog_clear_calc_user_access( - v_guid - , 0 -- a_debug - ); - -- Call Obedience_Level Calc IF NOT EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN fetchmetrics.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN @@ -228,6 +152,11 @@ BEGIN , a_get_inactive_obedience_level -- a_get_inactive_obedience_level , a_ids_obedience_level -- a_ids_obedience_level , a_names_obedience_level -- a_names_obedience_level + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -244,6 +173,11 @@ BEGIN , a_get_inactive_obedience_level -- a_get_inactive_obedience_level , a_ids_obedience_level -- a_ids_obedience_level , a_names_obedience_level -- a_names_obedience_level + , a_get_all_user + , a_get_inactive_user + , a_ids_user + , a_names_user + , a_emails_user , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met @@ -351,6 +285,11 @@ CALL fetchmetrics.p_dog_get_many_obedience_level ( , 0 -- a_get_inactive_obedience_level , '' -- a_ids_obedience_level , '' -- a_names_obedience_level + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , '' -- a_names_user + , '' -- a_emails_user , 1 -- a_require_all_id_search_filters_met , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met @@ -365,6 +304,11 @@ CALL fetchmetrics.p_dog_get_many_obedience_level ( , 0 -- a_get_inactive_obedience_level , '' -- a_ids_obedience_level , 'pat,point' -- a_names_obedience_level + , 1 -- a_get_all_user + , 0 -- a_get_inactive_user + , '' -- a_ids_user + , 'pat,point' -- a_names_user + , 'pat,point' -- a_emails_user , 1 -- a_require_all_id_search_filters_met , 1 -- a_require_any_id_search_filters_met , 0 -- a_require_all_non_id_search_filters_met diff --git a/static/MySQL/90000_populate.sql b/static/MySQL/90000_populate.sql index c0413f1..b829eeb 100644 --- a/static/MySQL/90000_populate.sql +++ b/static/MySQL/90000_populate.sql @@ -1197,6 +1197,25 @@ VALUES ) ; +INSERT INTO fetchmetrics.DOG_Button_Shape_User_Link ( + id_button_shape + , id_user + , id_access_level +) +SELECT + BS.id_button_shape + , 1 + , 3 +FROM fetchmetrics.DOG_Button_Shape BS +UNION +SELECT + BS.id_button_shape + , 2 + , 3 +FROM fetchmetrics.DOG_Button_Shape BS +; + + INSERT INTO fetchmetrics.DOG_Colour ( code , name @@ -1227,6 +1246,44 @@ VALUES , NULL ) ; + +INSERT INTO fetchmetrics.DOG_Image ( + id_file_type + , id_dog + , name + , path + , display_order + , active + , id_user_created_by +) +VALUES ( + 2 + , 1 + , 'Wisp' + , 'https://fetch-metrics.co.uk/static/images/Wisp.jpg' + , 1 + , 1 + , 1 +) +; + +INSERT INTO fetchmetrics.DOG_Image_User_Link ( + id_image + , id_user + , id_access_level +) +SELECT + I.id_image + , 1 + , 3 +FROM fetchmetrics.DOG_Image I +UNION +SELECT + I.id_image + , 2 + , 3 +FROM fetchmetrics.DOG_Image I +; */ /* @@ -1376,6 +1433,25 @@ VALUES , 'Squeaky Toy' ) ; +/* +INSERT INTO fetchmetrics.DOG_Distraction_Type_User_Link ( + id_distraction_type + , id_user + , id_access_level +) +SELECT + DT.id_type + , 1 + , 3 +FROM fetchmetrics.DOG_Distraction_Type DT +UNION +SELECT + DT.id_type + , 2 + , 3 +FROM fetchmetrics.DOG_Distraction_Type DT +; +*/ INSERT INTO fetchmetrics.DOG_Distraction_Intensity_Level ( code @@ -1405,6 +1481,24 @@ VALUES ; /* +INSERT INTO fetchmetrics.DOG_Distraction_Intensity_Level_User_Link ( + id_intensity_level + , id_user + , id_access_level +) +SELECT + IL.id_intensity_level + , 1 + , 3 +FROM fetchmetrics.DOG_Distraction_Intensity_Level IL +UNION +SELECT + IL.id_intensity_level + , 2 + , 3 +FROM fetchmetrics.DOG_Distraction_Intensity_Level IL +; + INSERT INTO fetchmetrics.DOG_Distraction ( id_assessment , id_distraction_type @@ -1513,6 +1607,25 @@ VALUES , 1 ) ; +/* +INSERT INTO fetchmetrics.DOG_Response_Quality_Metric_User_Link ( + id_response_quality_metric + , id_user + , id_access_level +) +SELECT + RQM.id_metric + , 1 + , 3 +FROM fetchmetrics.DOG_Response_Quality_Metric RQM +UNION +SELECT + RQM.id_metric + , 2 + , 3 +FROM fetchmetrics.DOG_Response_Quality_Metric RQM +; +*/ INSERT INTO fetchmetrics.DOG_Obedience_Level ( code @@ -1576,6 +1689,26 @@ VALUES , 'Refused and Ran Away Refusing to Return' ) ; +/* + +INSERT INTO fetchmetrics.DOG_Obedience_Level_User_Link ( + id_obedience_level + , id_user + , id_access_level +) +SELECT + OL.id_obedience_level + , 1 + , 3 +FROM fetchmetrics.DOG_Obedience_Level OL +UNION +SELECT + OL.id_obedience_level + , 2 + , 3 +FROM fetchmetrics.DOG_Obedience_Level OL +; +*/ /* Post Excel-insert: diff --git a/static/css/sections/blog.css b/static/css/sections/blog.css index 8d5817e..4d1cdd8 100644 --- a/static/css/sections/blog.css +++ b/static/css/sections/blog.css @@ -88,6 +88,7 @@ body { .hero { padding: 8rem 2rem 4rem; background: linear-gradient(45deg, var(--colour-page-background-1), var(--colour-page-background-2)); /* linear-gradient(45deg, #f8fafc, #eff6ff); */ + margin-bottom: 2rem; } .hero-content { max-width: 600px; @@ -122,6 +123,7 @@ section.hero .button:hover { overflow: hidden; box-shadow: 0 4px 20px rgba(0,0,0,0.1); transition: transform 0.3s, box-shadow 0.3s; + margin-bottom: 2rem; } .featured-post:hover { @@ -252,6 +254,7 @@ section.hero .button:hover { padding: 0.2rem 0.6rem; border-radius: 12px; font-size: 0.8rem; + margin-left: 1vw; } .recent-posts { diff --git a/static/dist/css/blog_article.bundle.css b/static/dist/css/blog_article.bundle.css index 46cb4a6..ac76dd0 100644 --- a/static/dist/css/blog_article.bundle.css +++ b/static/dist/css/blog_article.bundle.css @@ -166,6 +166,7 @@ body { .hero { padding: 8rem 2rem 4rem; background: linear-gradient(45deg, var(--colour-page-background-1), var(--colour-page-background-2)); /* linear-gradient(45deg, #f8fafc, #eff6ff); */ + margin-bottom: 2rem; } .hero-content { max-width: 600px; @@ -200,6 +201,7 @@ section.hero .button:hover { overflow: hidden; box-shadow: 0 4px 20px rgba(0,0,0,0.1); transition: transform 0.3s, box-shadow 0.3s; + margin-bottom: 2rem; } .featured-post:hover { @@ -330,6 +332,7 @@ section.hero .button:hover { padding: 0.2rem 0.6rem; border-radius: 12px; font-size: 0.8rem; + margin-left: 1vw; } .recent-posts { diff --git a/static/dist/css/blog_article.bundle.css.map b/static/dist/css/blog_article.bundle.css.map index b058880..35e4d70 100644 --- a/static/dist/css/blog_article.bundle.css.map +++ b/static/dist/css/blog_article.bundle.css.map @@ -1 +1 @@ -{"version":3,"file":"css/blog_article.bundle.css","mappings":"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","sources":["webpack://app/./static/css/sections/core.css","webpack://app/./static/css/sections/blog.css","webpack://app/./static/css/pages/blog/article.css"],"sourcesContent":["\n/* Home page\n*/\n\n/* Footer */\n.footer {\n background: #1f2937;\n color: #f3f4f6;\n padding: 4rem 2rem 2rem;\n}\n\n.footer-content {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 2rem;\n margin-bottom: 2rem;\n}\n\n.footer-section h3 {\n color: #fff;\n margin-bottom: 1rem;\n font-size: 1.2rem;\n text-align: center;\n}\n\n.footer-section ul {\n list-style: none;\n padding: 0;\n}\n\n.footer-section ul li {\n margin-bottom: 0.5rem;\n}\n\n.footer-section a {\n color: #f3f4f6;\n text-decoration: none;\n transition: color 0.3s ease;\n}\n\n.footer-section a:hover {\n color: #fff;\n text-decoration: underline;\n}\n\n.footer-bottom {\n border-top: 1px solid #374151;\n padding-top: 2rem;\n text-align: center;\n font-size: 0.9rem;\n}\n\n.footer-bottom a {\n color: aquamarine;\n}\n\n.footer-section.contact {\n width: 100%;\n}\n.footer-section .container {\n padding: 0;\n}\n.footer-section .container.row .container.column {\n padding: 1vh 2vw;\n}\n\n@media (max-width: 768px) {\n .footer-content {\n grid-template-columns: 1fr;\n text-align: center;\n }\n}\n\n@media (max-width: 540px) {\n .nav-links {\n display: none;\n }\n}","\n* {\n margin: 0;\n padding: 0;\n}\n\nbody {\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n line-height: 1.6;\n color: #333;\n background: var(--colour-page-background-1);\n}\n\n/* Header */\n.header {\n background: linear-gradient(135deg, #2c5282 0%, #3182ce 100%);\n color: white;\n padding: 1rem 0;\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n.container {\n max-width: 1200px;\n margin: 0 auto;\n padding: 0 20px;\n}\n\n.nav {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 2rem;\n}\n\n.logo {\n font-size: 1.5rem;\n font-weight: bold;\n color: #ff6b35;\n}\n\n.nav-links {\n display: flex;\n list-style: none;\n gap: 2rem;\n}\n\n.nav-links a {\n color: white;\n text-decoration: none;\n transition: color 0.3s;\n}\n\n.nav-links a:hover {\n color: #ff6b35;\n}\n\n.blog-header {\n text-align: center;\n padding: 2rem 0;\n}\n\n.blog-header h1 {\n font-size: 2.5rem;\n margin-bottom: 1rem;\n}\n\n.blog-header p {\n font-size: 1.2rem;\n opacity: 0.9;\n max-width: 600px;\n margin: 0 auto;\n}\n\n/* Main Content */\n.main-content {\n padding: 3rem 0;\n}\n\n.blog-grid {\n display: grid;\n grid-template-columns: 2fr 1fr;\n gap: 3rem;\n margin-bottom: 3rem;\n}\n\n\n/* Hero Section */\n.hero {\n padding: 8rem 2rem 4rem;\n background: linear-gradient(45deg, var(--colour-page-background-1), var(--colour-page-background-2)); /* linear-gradient(45deg, #f8fafc, #eff6ff); */\n}\n.hero-content {\n max-width: 600px;\n}\n.hero h1 {\n line-height: 1.2;\n margin-bottom: 1.5rem;\n color: var(--colour-text);\n}\n.hero p {\n font-size: 1.25rem;\n margin-bottom: 2rem;\n color: var(--colour-secondary);\n}\nsection.hero .button {\n margin: 0 auto;\n margin-bottom: 2vh;\n display: block;\n background-color: var(--colour-success-title);\n color: var(--colour-text-background);\n}\nsection.hero .button:hover {\n background-color: var(--colour-success-highlight);\n color: var(--colour-success-title);\n}\n\n\n/* Featured Post */\n.featured-post {\n background: white;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 4px 20px rgba(0,0,0,0.1);\n transition: transform 0.3s, box-shadow 0.3s;\n}\n\n.featured-post:hover {\n transform: translateY(-5px);\n box-shadow: 0 8px 30px rgba(0,0,0,0.15);\n}\n\n.featured-image {\n height: 300px;\n background: linear-gradient(45deg, #ff6b35, #f093fb);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 3rem;\n}\n\n.featured-content {\n padding: 2rem;\n}\n\n.post-category {\n display: inline-block;\n background: #ff6b35;\n color: white;\n padding: 0.3rem 1rem;\n border-radius: 20px;\n font-size: 0.8rem;\n font-weight: 600;\n margin-bottom: 1rem;\n}\n\n.featured-content h2 {\n font-size: 1.8rem;\n margin-bottom: 1rem;\n color: #2d3748;\n line-height: 1.3;\n}\n\n.post-excerpt {\n color: #666;\n margin-bottom: 1.5rem;\n line-height: 1.7;\n}\n\n.post-meta {\n display: flex;\n align-items: center;\n gap: 1rem;\n font-size: 0.9rem;\n color: #888;\n margin-bottom: 1rem;\n}\n\n.read-more {\n display: inline-flex;\n align-items: center;\n color: #3182ce;\n text-decoration: none;\n font-weight: 600;\n transition: color 0.3s;\n}\n\n.read-more:hover {\n color: #2c5282;\n}\n\n.read-more::after {\n content: ' →';\n margin-left: 0.5rem;\n transition: margin-left 0.3s;\n}\n\n.read-more:hover::after {\n margin-left: 1rem;\n}\n\n/* Sidebar */\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 2rem;\n}\n\n.sidebar-widget {\n background: white;\n padding: 2rem;\n border-radius: 12px;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n}\n\n.widget-title {\n font-size: 1.3rem;\n margin-bottom: 1.5rem;\n color: #2d3748;\n border-bottom: 2px solid #ff6b35;\n padding-bottom: 0.5rem;\n}\n\n.category-list {\n list-style: none;\n}\n\n.category-list li {\n padding: 0.8rem 0;\n border-bottom: 1px solid #e2e8f0;\n display: flex;\n justify-content: space-between;\n}\n\n.category-list li:last-child {\n border-bottom: none;\n}\n\n.category-list a {\n color: #4a5568;\n text-decoration: none;\n transition: color 0.3s;\n}\n\n.category-list a:hover {\n color: #3182ce;\n}\n\n.post-count {\n background: #e2e8f0;\n color: #4a5568;\n padding: 0.2rem 0.6rem;\n border-radius: 12px;\n font-size: 0.8rem;\n}\n\n.recent-posts {\n list-style: none;\n}\n\n.recent-post-item {\n padding: 1rem 0;\n border-bottom: 1px solid #e2e8f0;\n}\n\n.recent-post-item:last-child {\n border-bottom: none;\n}\n\n.recent-post-title {\n font-weight: 600;\n color: #2d3748;\n text-decoration: none;\n transition: color 0.3s;\n display: block;\n margin-bottom: 0.3rem;\n}\n\n.recent-post-title:hover {\n color: #3182ce;\n}\n\n.recent-post-date {\n font-size: 0.8rem;\n color: #888;\n}\n\n/* Blog Posts Grid */\n.blog-posts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));\n gap: 2rem;\n margin-top: 2rem;\n}\n\n.blog-post-card {\n background: white;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n transition: transform 0.3s, box-shadow 0.3s;\n}\n\n.blog-post-card:hover {\n transform: translateY(-3px);\n box-shadow: 0 6px 25px rgba(0,0,0,0.12);\n}\n\n.post-image {\n height: 200px;\n background: linear-gradient(45deg, #667eea, #764ba2);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 2rem;\n}\n\n.post-content {\n padding: 1.5rem;\n}\n\n.post-content h3 {\n font-size: 1.3rem;\n margin-bottom: 1rem;\n color: #2d3748;\n line-height: 1.3;\n}\n\n/* Newsletter Signup */\n.newsletter-form {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.newsletter-input {\n padding: 1rem;\n border: 2px solid #e2e8f0;\n border-radius: 8px;\n font-size: 1rem;\n transition: border-color 0.3s;\n}\n\n.newsletter-input:focus {\n outline: none;\n border-color: #3182ce;\n}\n\n.newsletter-btn {\n background: #ff6b35;\n color: white;\n border: none;\n padding: 1rem;\n border-radius: 8px;\n font-size: 1rem;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.3s;\n}\n\n.newsletter-btn:hover {\n background: #e55a2b;\n}\n\n#form_newsletter input[type=\"email\"] {\n width: 80%;\n margin: 0 10%;\n padding: 0.5vh;\n font-size: 1rem;\n}\n\n/* Footer */\n.footer {\n background: #2d3748;\n color: white;\n text-align: center;\n padding: 2rem 0;\n margin-top: 4rem;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .nav {\n flex-direction: column;\n gap: 1rem;\n text-align: center;\n }\n\n .nav-links {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n .blog-header h1 {\n font-size: 2rem;\n }\n\n .blog-grid {\n grid-template-columns: 1fr;\n gap: 2rem;\n }\n\n .blog-posts-grid {\n grid-template-columns: 1fr;\n }\n\n .featured-content h2 {\n font-size: 1.5rem;\n }\n}","\n#pageBody {\n padding-top: 2vh;\n}\n\n* {\n margin: 0;\n padding: 0;\n}\n\nbody {\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n line-height: 1.6;\n color: #333;\n}\n\n/* Header */\n.header {\n background: linear-gradient(135deg, #2c5282 0%, #3182ce 100%);\n color: white;\n padding: 1rem 0;\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n.container {\n max-width: 1200px;\n margin: 0 auto;\n padding: 0 20px;\n}\n\n.nav {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.logo {\n font-size: 1.5rem;\n font-weight: bold;\n color: #ff6b35;\n}\n\n.nav-links {\n display: flex;\n list-style: none;\n gap: 2rem;\n}\n\n.nav-links a {\n color: white;\n text-decoration: none;\n transition: color 0.3s;\n}\n\n.nav-links a:hover {\n color: #ff6b35;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n background: white;\n padding: 1rem 0;\n border-bottom: 1px solid #e2e8f0;\n}\n\n.breadcrumb-nav {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.9rem;\n color: #666;\n}\n\n.breadcrumb-nav a {\n color: #3182ce;\n text-decoration: none;\n}\n\n.breadcrumb-nav a:hover {\n text-decoration: underline;\n}\n\n/* Main Content */\n.main-content {\n padding: 3rem 0;\n}\n\n.content-grid {\n display: grid;\n grid-template-columns: 2fr 1fr;\n gap: 3rem;\n}\n\n/* Article */\n.article {\n background: white;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 4px 20px rgba(0,0,0,0.1);\n}\n\n.article-header {\n padding: 2rem 2rem 1rem;\n}\n\n.article-category {\n display: inline-block;\n background: #ff6b35;\n color: white;\n padding: 0.4rem 1.2rem;\n border-radius: 25px;\n font-size: 0.9rem;\n font-weight: 600;\n margin-bottom: 1.5rem;\n}\n\n.article-title {\n font-size: 2.2rem;\n color: #2d3748;\n line-height: 1.3;\n margin-bottom: 1.5rem;\n}\n\n.article-meta {\n display: flex;\n align-items: center;\n gap: 2rem;\n padding-bottom: 1.5rem;\n border-bottom: 2px solid #e2e8f0;\n margin-bottom: 2rem;\n}\n\n.meta-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.95rem;\n color: #666;\n}\n\n.author-info {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.author-avatar {\n width: 50px;\n height: 50px;\n border-radius: 50%;\n background: linear-gradient(45deg, #ff6b35, #3182ce);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-weight: bold;\n font-size: 1.2rem;\n}\n\n.author-details h4 {\n color: #2d3748;\n margin-bottom: 0.2rem;\n}\n\n.author-details p {\n color: #666;\n font-size: 0.9rem;\n}\n\n.featured-image {\n height: 400px;\n background: linear-gradient(45deg, #ff6b35, #f093fb);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 4rem;\n margin-bottom: 2rem;\n}\n\n.article-content {\n padding: 0 2rem 2rem;\n}\n\n.article-content h2 {\n font-size: 1.6rem;\n color: #2d3748;\n margin: 2rem 0 1rem;\n padding-bottom: 0.5rem;\n border-bottom: 2px solid #ff6b35;\n}\n\n.article-content h3 {\n font-size: 1.3rem;\n color: #2d3748;\n margin: 1.5rem 0 0.8rem;\n}\n\n.article-content p {\n margin-bottom: 1.5rem;\n line-height: 1.8;\n color: #4a5568;\n}\n\n.article-content ul, .article-content ol {\n margin: 1rem 0 1.5rem 2rem;\n color: #4a5568;\n}\n\n.article-content li {\n margin-bottom: 0.5rem;\n line-height: 1.7;\n}\n\n.callout-box {\n background: linear-gradient(135deg, #e6fffa 0%, #f0fff4 100%);\n border-left: 4px solid #38a169;\n padding: 1.5rem;\n margin: 2rem 0;\n border-radius: 0 8px 8px 0;\n}\n\n.callout-box h4 {\n color: #2f855a;\n margin-bottom: 0.8rem;\n font-size: 1.1rem;\n}\n\n.quote-box {\n background: #f7fafc;\n border-left: 4px solid #3182ce;\n padding: 1.5rem;\n margin: 2rem 0;\n font-style: italic;\n font-size: 1.1rem;\n color: #2d3748;\n}\n\n/* Tags */\n.article-tags {\n padding: 0 2rem 2rem;\n border-top: 1px solid #e2e8f0;\n margin-top: 2rem;\n padding-top: 2rem;\n}\n\n.tags-label {\n font-weight: 600;\n color: #2d3748;\n margin-bottom: 1rem;\n display: block;\n}\n\n.tags-list {\n display: flex;\n flex-wrap: wrap;\n gap: 0.8rem;\n}\n\n.tag {\n background: #e2e8f0;\n color: #4a5568;\n padding: 0.4rem 1rem;\n border-radius: 20px;\n text-decoration: none;\n font-size: 0.9rem;\n transition: all 0.3s;\n}\n\n.tag:hover {\n background: #3182ce;\n color: white;\n}\n\n/* Social Share */\n.social-share {\n background: white;\n padding: 1.5rem;\n border-radius: 12px;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n margin-bottom: 2rem;\n}\n\n.share-title {\n font-weight: 600;\n color: #2d3748;\n margin-bottom: 1rem;\n}\n\n.share-buttons {\n display: flex;\n gap: 1rem;\n}\n\n.share-btn {\n padding: 0.8rem 1.2rem;\n border-radius: 8px;\n text-decoration: none;\n color: white;\n font-weight: 500;\n transition: transform 0.3s;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.share-btn:hover {\n transform: translateY(-2px);\n}\n\n.share-twitter { background: #1da1f2; }\n.share-linkedin { background: #0077b5; }\n.share-facebook { background: #1877f2; }\n\n/* Sidebar */\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 2rem;\n}\n\n.sidebar-widget {\n background: white;\n padding: 2rem;\n border-radius: 12px;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n}\n\n.widget-title {\n font-size: 1.3rem;\n margin-bottom: 1.5rem;\n color: #2d3748;\n border-bottom: 2px solid #ff6b35;\n padding-bottom: 0.5rem;\n}\n\n.author-bio {\n text-align: center;\n}\n\n.author-bio-avatar {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: linear-gradient(45deg, #ff6b35, #3182ce);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-weight: bold;\n font-size: 2rem;\n margin: 0 auto 1rem;\n}\n\n.author-bio h4 {\n color: #2d3748;\n margin-bottom: 0.5rem;\n}\n\n.author-bio p {\n color: #666;\n line-height: 1.6;\n margin-bottom: 1rem;\n}\n\n.related-posts {\n list-style: none;\n}\n\n.related-post-item {\n padding: 1rem 0;\n border-bottom: 1px solid #e2e8f0;\n}\n\n.related-post-item:last-child {\n border-bottom: none;\n}\n\n.related-post-title {\n font-weight: 600;\n color: #2d3748;\n text-decoration: none;\n transition: color 0.3s;\n display: block;\n margin-bottom: 0.3rem;\n line-height: 1.4;\n}\n\n.related-post-title:hover {\n color: #3182ce;\n}\n\n.related-post-date {\n font-size: 0.8rem;\n color: #888;\n}\n\n/* Newsletter Signup */\n.newsletter-form {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.newsletter-input {\n padding: 1rem;\n border: 2px solid #e2e8f0;\n border-radius: 8px;\n font-size: 1rem;\n transition: border-color 0.3s;\n}\n\n.newsletter-input:focus {\n outline: none;\n border-color: #3182ce;\n}\n\n.newsletter-btn {\n background: #ff6b35;\n color: white;\n border: none;\n padding: 1rem;\n border-radius: 8px;\n font-size: 1rem;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.3s;\n}\n\n.newsletter-btn:hover {\n background: #e55a2b;\n}\n\n/* Navigation */\n.post-navigation {\n background: white;\n padding: 2rem;\n border-radius: 12px;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n margin-top: 2rem;\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 2rem;\n}\n\n.nav-post {\n text-decoration: none;\n color: #4a5568;\n transition: color 0.3s;\n}\n\n.nav-post:hover {\n color: #3182ce;\n}\n\n.nav-post.prev {\n text-align: left;\n}\n\n.nav-post.next {\n text-align: right;\n}\n\n.nav-label {\n font-size: 0.9rem;\n color: #888;\n margin-bottom: 0.5rem;\n display: block;\n}\n\n.nav-title {\n font-weight: 600;\n line-height: 1.4;\n}\n\n/* Footer */\n.footer {\n background: #2d3748;\n color: white;\n text-align: center;\n padding: 2rem 0;\n margin-top: 4rem;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .nav {\n flex-direction: column;\n gap: 1rem;\n text-align: center;\n }\n\n .nav-links {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n .content-grid {\n grid-template-columns: 1fr;\n gap: 2rem;\n }\n\n .article-title {\n font-size: 1.8rem;\n }\n\n .article-meta {\n flex-direction: column;\n gap: 1rem;\n align-items: flex-start;\n }\n\n .author-info {\n flex-direction: row;\n }\n\n .share-buttons {\n flex-direction: column;\n }\n\n .post-navigation {\n grid-template-columns: 1fr;\n gap: 1rem;\n }\n\n .nav-post.next {\n text-align: left;\n }\n}"],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"css/blog_article.bundle.css","mappings":"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","sources":["webpack://app/./static/css/sections/core.css","webpack://app/./static/css/sections/blog.css","webpack://app/./static/css/pages/blog/article.css"],"sourcesContent":["\n/* Home page\n*/\n\n/* Footer */\n.footer {\n background: #1f2937;\n color: #f3f4f6;\n padding: 4rem 2rem 2rem;\n}\n\n.footer-content {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 2rem;\n margin-bottom: 2rem;\n}\n\n.footer-section h3 {\n color: #fff;\n margin-bottom: 1rem;\n font-size: 1.2rem;\n text-align: center;\n}\n\n.footer-section ul {\n list-style: none;\n padding: 0;\n}\n\n.footer-section ul li {\n margin-bottom: 0.5rem;\n}\n\n.footer-section a {\n color: #f3f4f6;\n text-decoration: none;\n transition: color 0.3s ease;\n}\n\n.footer-section a:hover {\n color: #fff;\n text-decoration: underline;\n}\n\n.footer-bottom {\n border-top: 1px solid #374151;\n padding-top: 2rem;\n text-align: center;\n font-size: 0.9rem;\n}\n\n.footer-bottom a {\n color: aquamarine;\n}\n\n.footer-section.contact {\n width: 100%;\n}\n.footer-section .container {\n padding: 0;\n}\n.footer-section .container.row .container.column {\n padding: 1vh 2vw;\n}\n\n@media (max-width: 768px) {\n .footer-content {\n grid-template-columns: 1fr;\n text-align: center;\n }\n}\n\n@media (max-width: 540px) {\n .nav-links {\n display: none;\n }\n}","\n* {\n margin: 0;\n padding: 0;\n}\n\nbody {\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n line-height: 1.6;\n color: #333;\n background: var(--colour-page-background-1);\n}\n\n/* Header */\n.header {\n background: linear-gradient(135deg, #2c5282 0%, #3182ce 100%);\n color: white;\n padding: 1rem 0;\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n.container {\n max-width: 1200px;\n margin: 0 auto;\n padding: 0 20px;\n}\n\n.nav {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 2rem;\n}\n\n.logo {\n font-size: 1.5rem;\n font-weight: bold;\n color: #ff6b35;\n}\n\n.nav-links {\n display: flex;\n list-style: none;\n gap: 2rem;\n}\n\n.nav-links a {\n color: white;\n text-decoration: none;\n transition: color 0.3s;\n}\n\n.nav-links a:hover {\n color: #ff6b35;\n}\n\n.blog-header {\n text-align: center;\n padding: 2rem 0;\n}\n\n.blog-header h1 {\n font-size: 2.5rem;\n margin-bottom: 1rem;\n}\n\n.blog-header p {\n font-size: 1.2rem;\n opacity: 0.9;\n max-width: 600px;\n margin: 0 auto;\n}\n\n/* Main Content */\n.main-content {\n padding: 3rem 0;\n}\n\n.blog-grid {\n display: grid;\n grid-template-columns: 2fr 1fr;\n gap: 3rem;\n margin-bottom: 3rem;\n}\n\n\n/* Hero Section */\n.hero {\n padding: 8rem 2rem 4rem;\n background: linear-gradient(45deg, var(--colour-page-background-1), var(--colour-page-background-2)); /* linear-gradient(45deg, #f8fafc, #eff6ff); */\n margin-bottom: 2rem;\n}\n.hero-content {\n max-width: 600px;\n}\n.hero h1 {\n line-height: 1.2;\n margin-bottom: 1.5rem;\n color: var(--colour-text);\n}\n.hero p {\n font-size: 1.25rem;\n margin-bottom: 2rem;\n color: var(--colour-secondary);\n}\nsection.hero .button {\n margin: 0 auto;\n margin-bottom: 2vh;\n display: block;\n background-color: var(--colour-success-title);\n color: var(--colour-text-background);\n}\nsection.hero .button:hover {\n background-color: var(--colour-success-highlight);\n color: var(--colour-success-title);\n}\n\n\n/* Featured Post */\n.featured-post {\n background: white;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 4px 20px rgba(0,0,0,0.1);\n transition: transform 0.3s, box-shadow 0.3s;\n margin-bottom: 2rem;\n}\n\n.featured-post:hover {\n transform: translateY(-5px);\n box-shadow: 0 8px 30px rgba(0,0,0,0.15);\n}\n\n.featured-image {\n height: 300px;\n background: linear-gradient(45deg, #ff6b35, #f093fb);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 3rem;\n}\n\n.featured-content {\n padding: 2rem;\n}\n\n.post-category {\n display: inline-block;\n background: #ff6b35;\n color: white;\n padding: 0.3rem 1rem;\n border-radius: 20px;\n font-size: 0.8rem;\n font-weight: 600;\n margin-bottom: 1rem;\n}\n\n.featured-content h2 {\n font-size: 1.8rem;\n margin-bottom: 1rem;\n color: #2d3748;\n line-height: 1.3;\n}\n\n.post-excerpt {\n color: #666;\n margin-bottom: 1.5rem;\n line-height: 1.7;\n}\n\n.post-meta {\n display: flex;\n align-items: center;\n gap: 1rem;\n font-size: 0.9rem;\n color: #888;\n margin-bottom: 1rem;\n}\n\n.read-more {\n display: inline-flex;\n align-items: center;\n color: #3182ce;\n text-decoration: none;\n font-weight: 600;\n transition: color 0.3s;\n}\n\n.read-more:hover {\n color: #2c5282;\n}\n\n.read-more::after {\n content: ' →';\n margin-left: 0.5rem;\n transition: margin-left 0.3s;\n}\n\n.read-more:hover::after {\n margin-left: 1rem;\n}\n\n/* Sidebar */\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 2rem;\n}\n\n.sidebar-widget {\n background: white;\n padding: 2rem;\n border-radius: 12px;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n}\n\n.widget-title {\n font-size: 1.3rem;\n margin-bottom: 1.5rem;\n color: #2d3748;\n border-bottom: 2px solid #ff6b35;\n padding-bottom: 0.5rem;\n}\n\n.category-list {\n list-style: none;\n}\n\n.category-list li {\n padding: 0.8rem 0;\n border-bottom: 1px solid #e2e8f0;\n display: flex;\n justify-content: space-between;\n}\n\n.category-list li:last-child {\n border-bottom: none;\n}\n\n.category-list a {\n color: #4a5568;\n text-decoration: none;\n transition: color 0.3s;\n}\n\n.category-list a:hover {\n color: #3182ce;\n}\n\n.post-count {\n background: #e2e8f0;\n color: #4a5568;\n padding: 0.2rem 0.6rem;\n border-radius: 12px;\n font-size: 0.8rem;\n margin-left: 1vw;\n}\n\n.recent-posts {\n list-style: none;\n}\n\n.recent-post-item {\n padding: 1rem 0;\n border-bottom: 1px solid #e2e8f0;\n}\n\n.recent-post-item:last-child {\n border-bottom: none;\n}\n\n.recent-post-title {\n font-weight: 600;\n color: #2d3748;\n text-decoration: none;\n transition: color 0.3s;\n display: block;\n margin-bottom: 0.3rem;\n}\n\n.recent-post-title:hover {\n color: #3182ce;\n}\n\n.recent-post-date {\n font-size: 0.8rem;\n color: #888;\n}\n\n/* Blog Posts Grid */\n.blog-posts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));\n gap: 2rem;\n margin-top: 2rem;\n}\n\n.blog-post-card {\n background: white;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n transition: transform 0.3s, box-shadow 0.3s;\n}\n\n.blog-post-card:hover {\n transform: translateY(-3px);\n box-shadow: 0 6px 25px rgba(0,0,0,0.12);\n}\n\n.post-image {\n height: 200px;\n background: linear-gradient(45deg, #667eea, #764ba2);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 2rem;\n}\n\n.post-content {\n padding: 1.5rem;\n}\n\n.post-content h3 {\n font-size: 1.3rem;\n margin-bottom: 1rem;\n color: #2d3748;\n line-height: 1.3;\n}\n\n/* Newsletter Signup */\n.newsletter-form {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.newsletter-input {\n padding: 1rem;\n border: 2px solid #e2e8f0;\n border-radius: 8px;\n font-size: 1rem;\n transition: border-color 0.3s;\n}\n\n.newsletter-input:focus {\n outline: none;\n border-color: #3182ce;\n}\n\n.newsletter-btn {\n background: #ff6b35;\n color: white;\n border: none;\n padding: 1rem;\n border-radius: 8px;\n font-size: 1rem;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.3s;\n}\n\n.newsletter-btn:hover {\n background: #e55a2b;\n}\n\n#form_newsletter input[type=\"email\"] {\n width: 80%;\n margin: 0 10%;\n padding: 0.5vh;\n font-size: 1rem;\n}\n\n/* Footer */\n.footer {\n background: #2d3748;\n color: white;\n text-align: center;\n padding: 2rem 0;\n margin-top: 4rem;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .nav {\n flex-direction: column;\n gap: 1rem;\n text-align: center;\n }\n\n .nav-links {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n .blog-header h1 {\n font-size: 2rem;\n }\n\n .blog-grid {\n grid-template-columns: 1fr;\n gap: 2rem;\n }\n\n .blog-posts-grid {\n grid-template-columns: 1fr;\n }\n\n .featured-content h2 {\n font-size: 1.5rem;\n }\n}","\n#pageBody {\n padding-top: 2vh;\n}\n\n* {\n margin: 0;\n padding: 0;\n}\n\nbody {\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n line-height: 1.6;\n color: #333;\n}\n\n/* Header */\n.header {\n background: linear-gradient(135deg, #2c5282 0%, #3182ce 100%);\n color: white;\n padding: 1rem 0;\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n.container {\n max-width: 1200px;\n margin: 0 auto;\n padding: 0 20px;\n}\n\n.nav {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.logo {\n font-size: 1.5rem;\n font-weight: bold;\n color: #ff6b35;\n}\n\n.nav-links {\n display: flex;\n list-style: none;\n gap: 2rem;\n}\n\n.nav-links a {\n color: white;\n text-decoration: none;\n transition: color 0.3s;\n}\n\n.nav-links a:hover {\n color: #ff6b35;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n background: white;\n padding: 1rem 0;\n border-bottom: 1px solid #e2e8f0;\n}\n\n.breadcrumb-nav {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.9rem;\n color: #666;\n}\n\n.breadcrumb-nav a {\n color: #3182ce;\n text-decoration: none;\n}\n\n.breadcrumb-nav a:hover {\n text-decoration: underline;\n}\n\n/* Main Content */\n.main-content {\n padding: 3rem 0;\n}\n\n.content-grid {\n display: grid;\n grid-template-columns: 2fr 1fr;\n gap: 3rem;\n}\n\n/* Article */\n.article {\n background: white;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 4px 20px rgba(0,0,0,0.1);\n}\n\n.article-header {\n padding: 2rem 2rem 1rem;\n}\n\n.article-category {\n display: inline-block;\n background: #ff6b35;\n color: white;\n padding: 0.4rem 1.2rem;\n border-radius: 25px;\n font-size: 0.9rem;\n font-weight: 600;\n margin-bottom: 1.5rem;\n}\n\n.article-title {\n font-size: 2.2rem;\n color: #2d3748;\n line-height: 1.3;\n margin-bottom: 1.5rem;\n}\n\n.article-meta {\n display: flex;\n align-items: center;\n gap: 2rem;\n padding-bottom: 1.5rem;\n border-bottom: 2px solid #e2e8f0;\n margin-bottom: 2rem;\n}\n\n.meta-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.95rem;\n color: #666;\n}\n\n.author-info {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.author-avatar {\n width: 50px;\n height: 50px;\n border-radius: 50%;\n background: linear-gradient(45deg, #ff6b35, #3182ce);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-weight: bold;\n font-size: 1.2rem;\n}\n\n.author-details h4 {\n color: #2d3748;\n margin-bottom: 0.2rem;\n}\n\n.author-details p {\n color: #666;\n font-size: 0.9rem;\n}\n\n.featured-image {\n height: 400px;\n background: linear-gradient(45deg, #ff6b35, #f093fb);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 4rem;\n margin-bottom: 2rem;\n}\n\n.article-content {\n padding: 0 2rem 2rem;\n}\n\n.article-content h2 {\n font-size: 1.6rem;\n color: #2d3748;\n margin: 2rem 0 1rem;\n padding-bottom: 0.5rem;\n border-bottom: 2px solid #ff6b35;\n}\n\n.article-content h3 {\n font-size: 1.3rem;\n color: #2d3748;\n margin: 1.5rem 0 0.8rem;\n}\n\n.article-content p {\n margin-bottom: 1.5rem;\n line-height: 1.8;\n color: #4a5568;\n}\n\n.article-content ul, .article-content ol {\n margin: 1rem 0 1.5rem 2rem;\n color: #4a5568;\n}\n\n.article-content li {\n margin-bottom: 0.5rem;\n line-height: 1.7;\n}\n\n.callout-box {\n background: linear-gradient(135deg, #e6fffa 0%, #f0fff4 100%);\n border-left: 4px solid #38a169;\n padding: 1.5rem;\n margin: 2rem 0;\n border-radius: 0 8px 8px 0;\n}\n\n.callout-box h4 {\n color: #2f855a;\n margin-bottom: 0.8rem;\n font-size: 1.1rem;\n}\n\n.quote-box {\n background: #f7fafc;\n border-left: 4px solid #3182ce;\n padding: 1.5rem;\n margin: 2rem 0;\n font-style: italic;\n font-size: 1.1rem;\n color: #2d3748;\n}\n\n/* Tags */\n.article-tags {\n padding: 0 2rem 2rem;\n border-top: 1px solid #e2e8f0;\n margin-top: 2rem;\n padding-top: 2rem;\n}\n\n.tags-label {\n font-weight: 600;\n color: #2d3748;\n margin-bottom: 1rem;\n display: block;\n}\n\n.tags-list {\n display: flex;\n flex-wrap: wrap;\n gap: 0.8rem;\n}\n\n.tag {\n background: #e2e8f0;\n color: #4a5568;\n padding: 0.4rem 1rem;\n border-radius: 20px;\n text-decoration: none;\n font-size: 0.9rem;\n transition: all 0.3s;\n}\n\n.tag:hover {\n background: #3182ce;\n color: white;\n}\n\n/* Social Share */\n.social-share {\n background: white;\n padding: 1.5rem;\n border-radius: 12px;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n margin-bottom: 2rem;\n}\n\n.share-title {\n font-weight: 600;\n color: #2d3748;\n margin-bottom: 1rem;\n}\n\n.share-buttons {\n display: flex;\n gap: 1rem;\n}\n\n.share-btn {\n padding: 0.8rem 1.2rem;\n border-radius: 8px;\n text-decoration: none;\n color: white;\n font-weight: 500;\n transition: transform 0.3s;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.share-btn:hover {\n transform: translateY(-2px);\n}\n\n.share-twitter { background: #1da1f2; }\n.share-linkedin { background: #0077b5; }\n.share-facebook { background: #1877f2; }\n\n/* Sidebar */\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 2rem;\n}\n\n.sidebar-widget {\n background: white;\n padding: 2rem;\n border-radius: 12px;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n}\n\n.widget-title {\n font-size: 1.3rem;\n margin-bottom: 1.5rem;\n color: #2d3748;\n border-bottom: 2px solid #ff6b35;\n padding-bottom: 0.5rem;\n}\n\n.author-bio {\n text-align: center;\n}\n\n.author-bio-avatar {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: linear-gradient(45deg, #ff6b35, #3182ce);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-weight: bold;\n font-size: 2rem;\n margin: 0 auto 1rem;\n}\n\n.author-bio h4 {\n color: #2d3748;\n margin-bottom: 0.5rem;\n}\n\n.author-bio p {\n color: #666;\n line-height: 1.6;\n margin-bottom: 1rem;\n}\n\n.related-posts {\n list-style: none;\n}\n\n.related-post-item {\n padding: 1rem 0;\n border-bottom: 1px solid #e2e8f0;\n}\n\n.related-post-item:last-child {\n border-bottom: none;\n}\n\n.related-post-title {\n font-weight: 600;\n color: #2d3748;\n text-decoration: none;\n transition: color 0.3s;\n display: block;\n margin-bottom: 0.3rem;\n line-height: 1.4;\n}\n\n.related-post-title:hover {\n color: #3182ce;\n}\n\n.related-post-date {\n font-size: 0.8rem;\n color: #888;\n}\n\n/* Newsletter Signup */\n.newsletter-form {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.newsletter-input {\n padding: 1rem;\n border: 2px solid #e2e8f0;\n border-radius: 8px;\n font-size: 1rem;\n transition: border-color 0.3s;\n}\n\n.newsletter-input:focus {\n outline: none;\n border-color: #3182ce;\n}\n\n.newsletter-btn {\n background: #ff6b35;\n color: white;\n border: none;\n padding: 1rem;\n border-radius: 8px;\n font-size: 1rem;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.3s;\n}\n\n.newsletter-btn:hover {\n background: #e55a2b;\n}\n\n/* Navigation */\n.post-navigation {\n background: white;\n padding: 2rem;\n border-radius: 12px;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n margin-top: 2rem;\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 2rem;\n}\n\n.nav-post {\n text-decoration: none;\n color: #4a5568;\n transition: color 0.3s;\n}\n\n.nav-post:hover {\n color: #3182ce;\n}\n\n.nav-post.prev {\n text-align: left;\n}\n\n.nav-post.next {\n text-align: right;\n}\n\n.nav-label {\n font-size: 0.9rem;\n color: #888;\n margin-bottom: 0.5rem;\n display: block;\n}\n\n.nav-title {\n font-weight: 600;\n line-height: 1.4;\n}\n\n/* Footer */\n.footer {\n background: #2d3748;\n color: white;\n text-align: center;\n padding: 2rem 0;\n margin-top: 4rem;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .nav {\n flex-direction: column;\n gap: 1rem;\n text-align: center;\n }\n\n .nav-links {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n .content-grid {\n grid-template-columns: 1fr;\n gap: 2rem;\n }\n\n .article-title {\n font-size: 1.8rem;\n }\n\n .article-meta {\n flex-direction: column;\n gap: 1rem;\n align-items: flex-start;\n }\n\n .author-info {\n flex-direction: row;\n }\n\n .share-buttons {\n flex-direction: column;\n }\n\n .post-navigation {\n grid-template-columns: 1fr;\n gap: 1rem;\n }\n\n .nav-post.next {\n text-align: left;\n }\n}"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/static/dist/css/blog_home.bundle.css b/static/dist/css/blog_home.bundle.css index a4b78af..8dd59f9 100644 --- a/static/dist/css/blog_home.bundle.css +++ b/static/dist/css/blog_home.bundle.css @@ -166,6 +166,7 @@ body { .hero { padding: 8rem 2rem 4rem; background: linear-gradient(45deg, var(--colour-page-background-1), var(--colour-page-background-2)); /* linear-gradient(45deg, #f8fafc, #eff6ff); */ + margin-bottom: 2rem; } .hero-content { max-width: 600px; @@ -200,6 +201,7 @@ section.hero .button:hover { overflow: hidden; box-shadow: 0 4px 20px rgba(0,0,0,0.1); transition: transform 0.3s, box-shadow 0.3s; + margin-bottom: 2rem; } .featured-post:hover { @@ -330,6 +332,7 @@ section.hero .button:hover { padding: 0.2rem 0.6rem; border-radius: 12px; font-size: 0.8rem; + margin-left: 1vw; } .recent-posts { diff --git a/static/dist/css/blog_home.bundle.css.map b/static/dist/css/blog_home.bundle.css.map index fd56856..d9df721 100644 --- a/static/dist/css/blog_home.bundle.css.map +++ b/static/dist/css/blog_home.bundle.css.map @@ -1 +1 @@ -{"version":3,"file":"css/blog_home.bundle.css","mappings":"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","sources":["webpack://app/./static/css/sections/core.css","webpack://app/./static/css/sections/blog.css"],"sourcesContent":["\n/* Home page\n*/\n\n/* Footer */\n.footer {\n background: #1f2937;\n color: #f3f4f6;\n padding: 4rem 2rem 2rem;\n}\n\n.footer-content {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 2rem;\n margin-bottom: 2rem;\n}\n\n.footer-section h3 {\n color: #fff;\n margin-bottom: 1rem;\n font-size: 1.2rem;\n text-align: center;\n}\n\n.footer-section ul {\n list-style: none;\n padding: 0;\n}\n\n.footer-section ul li {\n margin-bottom: 0.5rem;\n}\n\n.footer-section a {\n color: #f3f4f6;\n text-decoration: none;\n transition: color 0.3s ease;\n}\n\n.footer-section a:hover {\n color: #fff;\n text-decoration: underline;\n}\n\n.footer-bottom {\n border-top: 1px solid #374151;\n padding-top: 2rem;\n text-align: center;\n font-size: 0.9rem;\n}\n\n.footer-bottom a {\n color: aquamarine;\n}\n\n.footer-section.contact {\n width: 100%;\n}\n.footer-section .container {\n padding: 0;\n}\n.footer-section .container.row .container.column {\n padding: 1vh 2vw;\n}\n\n@media (max-width: 768px) {\n .footer-content {\n grid-template-columns: 1fr;\n text-align: center;\n }\n}\n\n@media (max-width: 540px) {\n .nav-links {\n display: none;\n }\n}","\n* {\n margin: 0;\n padding: 0;\n}\n\nbody {\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n line-height: 1.6;\n color: #333;\n background: var(--colour-page-background-1);\n}\n\n/* Header */\n.header {\n background: linear-gradient(135deg, #2c5282 0%, #3182ce 100%);\n color: white;\n padding: 1rem 0;\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n.container {\n max-width: 1200px;\n margin: 0 auto;\n padding: 0 20px;\n}\n\n.nav {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 2rem;\n}\n\n.logo {\n font-size: 1.5rem;\n font-weight: bold;\n color: #ff6b35;\n}\n\n.nav-links {\n display: flex;\n list-style: none;\n gap: 2rem;\n}\n\n.nav-links a {\n color: white;\n text-decoration: none;\n transition: color 0.3s;\n}\n\n.nav-links a:hover {\n color: #ff6b35;\n}\n\n.blog-header {\n text-align: center;\n padding: 2rem 0;\n}\n\n.blog-header h1 {\n font-size: 2.5rem;\n margin-bottom: 1rem;\n}\n\n.blog-header p {\n font-size: 1.2rem;\n opacity: 0.9;\n max-width: 600px;\n margin: 0 auto;\n}\n\n/* Main Content */\n.main-content {\n padding: 3rem 0;\n}\n\n.blog-grid {\n display: grid;\n grid-template-columns: 2fr 1fr;\n gap: 3rem;\n margin-bottom: 3rem;\n}\n\n\n/* Hero Section */\n.hero {\n padding: 8rem 2rem 4rem;\n background: linear-gradient(45deg, var(--colour-page-background-1), var(--colour-page-background-2)); /* linear-gradient(45deg, #f8fafc, #eff6ff); */\n}\n.hero-content {\n max-width: 600px;\n}\n.hero h1 {\n line-height: 1.2;\n margin-bottom: 1.5rem;\n color: var(--colour-text);\n}\n.hero p {\n font-size: 1.25rem;\n margin-bottom: 2rem;\n color: var(--colour-secondary);\n}\nsection.hero .button {\n margin: 0 auto;\n margin-bottom: 2vh;\n display: block;\n background-color: var(--colour-success-title);\n color: var(--colour-text-background);\n}\nsection.hero .button:hover {\n background-color: var(--colour-success-highlight);\n color: var(--colour-success-title);\n}\n\n\n/* Featured Post */\n.featured-post {\n background: white;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 4px 20px rgba(0,0,0,0.1);\n transition: transform 0.3s, box-shadow 0.3s;\n}\n\n.featured-post:hover {\n transform: translateY(-5px);\n box-shadow: 0 8px 30px rgba(0,0,0,0.15);\n}\n\n.featured-image {\n height: 300px;\n background: linear-gradient(45deg, #ff6b35, #f093fb);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 3rem;\n}\n\n.featured-content {\n padding: 2rem;\n}\n\n.post-category {\n display: inline-block;\n background: #ff6b35;\n color: white;\n padding: 0.3rem 1rem;\n border-radius: 20px;\n font-size: 0.8rem;\n font-weight: 600;\n margin-bottom: 1rem;\n}\n\n.featured-content h2 {\n font-size: 1.8rem;\n margin-bottom: 1rem;\n color: #2d3748;\n line-height: 1.3;\n}\n\n.post-excerpt {\n color: #666;\n margin-bottom: 1.5rem;\n line-height: 1.7;\n}\n\n.post-meta {\n display: flex;\n align-items: center;\n gap: 1rem;\n font-size: 0.9rem;\n color: #888;\n margin-bottom: 1rem;\n}\n\n.read-more {\n display: inline-flex;\n align-items: center;\n color: #3182ce;\n text-decoration: none;\n font-weight: 600;\n transition: color 0.3s;\n}\n\n.read-more:hover {\n color: #2c5282;\n}\n\n.read-more::after {\n content: ' →';\n margin-left: 0.5rem;\n transition: margin-left 0.3s;\n}\n\n.read-more:hover::after {\n margin-left: 1rem;\n}\n\n/* Sidebar */\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 2rem;\n}\n\n.sidebar-widget {\n background: white;\n padding: 2rem;\n border-radius: 12px;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n}\n\n.widget-title {\n font-size: 1.3rem;\n margin-bottom: 1.5rem;\n color: #2d3748;\n border-bottom: 2px solid #ff6b35;\n padding-bottom: 0.5rem;\n}\n\n.category-list {\n list-style: none;\n}\n\n.category-list li {\n padding: 0.8rem 0;\n border-bottom: 1px solid #e2e8f0;\n display: flex;\n justify-content: space-between;\n}\n\n.category-list li:last-child {\n border-bottom: none;\n}\n\n.category-list a {\n color: #4a5568;\n text-decoration: none;\n transition: color 0.3s;\n}\n\n.category-list a:hover {\n color: #3182ce;\n}\n\n.post-count {\n background: #e2e8f0;\n color: #4a5568;\n padding: 0.2rem 0.6rem;\n border-radius: 12px;\n font-size: 0.8rem;\n}\n\n.recent-posts {\n list-style: none;\n}\n\n.recent-post-item {\n padding: 1rem 0;\n border-bottom: 1px solid #e2e8f0;\n}\n\n.recent-post-item:last-child {\n border-bottom: none;\n}\n\n.recent-post-title {\n font-weight: 600;\n color: #2d3748;\n text-decoration: none;\n transition: color 0.3s;\n display: block;\n margin-bottom: 0.3rem;\n}\n\n.recent-post-title:hover {\n color: #3182ce;\n}\n\n.recent-post-date {\n font-size: 0.8rem;\n color: #888;\n}\n\n/* Blog Posts Grid */\n.blog-posts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));\n gap: 2rem;\n margin-top: 2rem;\n}\n\n.blog-post-card {\n background: white;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n transition: transform 0.3s, box-shadow 0.3s;\n}\n\n.blog-post-card:hover {\n transform: translateY(-3px);\n box-shadow: 0 6px 25px rgba(0,0,0,0.12);\n}\n\n.post-image {\n height: 200px;\n background: linear-gradient(45deg, #667eea, #764ba2);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 2rem;\n}\n\n.post-content {\n padding: 1.5rem;\n}\n\n.post-content h3 {\n font-size: 1.3rem;\n margin-bottom: 1rem;\n color: #2d3748;\n line-height: 1.3;\n}\n\n/* Newsletter Signup */\n.newsletter-form {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.newsletter-input {\n padding: 1rem;\n border: 2px solid #e2e8f0;\n border-radius: 8px;\n font-size: 1rem;\n transition: border-color 0.3s;\n}\n\n.newsletter-input:focus {\n outline: none;\n border-color: #3182ce;\n}\n\n.newsletter-btn {\n background: #ff6b35;\n color: white;\n border: none;\n padding: 1rem;\n border-radius: 8px;\n font-size: 1rem;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.3s;\n}\n\n.newsletter-btn:hover {\n background: #e55a2b;\n}\n\n#form_newsletter input[type=\"email\"] {\n width: 80%;\n margin: 0 10%;\n padding: 0.5vh;\n font-size: 1rem;\n}\n\n/* Footer */\n.footer {\n background: #2d3748;\n color: white;\n text-align: center;\n padding: 2rem 0;\n margin-top: 4rem;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .nav {\n flex-direction: column;\n gap: 1rem;\n text-align: center;\n }\n\n .nav-links {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n .blog-header h1 {\n font-size: 2rem;\n }\n\n .blog-grid {\n grid-template-columns: 1fr;\n gap: 2rem;\n }\n\n .blog-posts-grid {\n grid-template-columns: 1fr;\n }\n\n .featured-content h2 {\n font-size: 1.5rem;\n }\n}"],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"css/blog_home.bundle.css","mappings":"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","sources":["webpack://app/./static/css/sections/core.css","webpack://app/./static/css/sections/blog.css"],"sourcesContent":["\n/* Home page\n*/\n\n/* Footer */\n.footer {\n background: #1f2937;\n color: #f3f4f6;\n padding: 4rem 2rem 2rem;\n}\n\n.footer-content {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 2rem;\n margin-bottom: 2rem;\n}\n\n.footer-section h3 {\n color: #fff;\n margin-bottom: 1rem;\n font-size: 1.2rem;\n text-align: center;\n}\n\n.footer-section ul {\n list-style: none;\n padding: 0;\n}\n\n.footer-section ul li {\n margin-bottom: 0.5rem;\n}\n\n.footer-section a {\n color: #f3f4f6;\n text-decoration: none;\n transition: color 0.3s ease;\n}\n\n.footer-section a:hover {\n color: #fff;\n text-decoration: underline;\n}\n\n.footer-bottom {\n border-top: 1px solid #374151;\n padding-top: 2rem;\n text-align: center;\n font-size: 0.9rem;\n}\n\n.footer-bottom a {\n color: aquamarine;\n}\n\n.footer-section.contact {\n width: 100%;\n}\n.footer-section .container {\n padding: 0;\n}\n.footer-section .container.row .container.column {\n padding: 1vh 2vw;\n}\n\n@media (max-width: 768px) {\n .footer-content {\n grid-template-columns: 1fr;\n text-align: center;\n }\n}\n\n@media (max-width: 540px) {\n .nav-links {\n display: none;\n }\n}","\n* {\n margin: 0;\n padding: 0;\n}\n\nbody {\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n line-height: 1.6;\n color: #333;\n background: var(--colour-page-background-1);\n}\n\n/* Header */\n.header {\n background: linear-gradient(135deg, #2c5282 0%, #3182ce 100%);\n color: white;\n padding: 1rem 0;\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n.container {\n max-width: 1200px;\n margin: 0 auto;\n padding: 0 20px;\n}\n\n.nav {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 2rem;\n}\n\n.logo {\n font-size: 1.5rem;\n font-weight: bold;\n color: #ff6b35;\n}\n\n.nav-links {\n display: flex;\n list-style: none;\n gap: 2rem;\n}\n\n.nav-links a {\n color: white;\n text-decoration: none;\n transition: color 0.3s;\n}\n\n.nav-links a:hover {\n color: #ff6b35;\n}\n\n.blog-header {\n text-align: center;\n padding: 2rem 0;\n}\n\n.blog-header h1 {\n font-size: 2.5rem;\n margin-bottom: 1rem;\n}\n\n.blog-header p {\n font-size: 1.2rem;\n opacity: 0.9;\n max-width: 600px;\n margin: 0 auto;\n}\n\n/* Main Content */\n.main-content {\n padding: 3rem 0;\n}\n\n.blog-grid {\n display: grid;\n grid-template-columns: 2fr 1fr;\n gap: 3rem;\n margin-bottom: 3rem;\n}\n\n\n/* Hero Section */\n.hero {\n padding: 8rem 2rem 4rem;\n background: linear-gradient(45deg, var(--colour-page-background-1), var(--colour-page-background-2)); /* linear-gradient(45deg, #f8fafc, #eff6ff); */\n margin-bottom: 2rem;\n}\n.hero-content {\n max-width: 600px;\n}\n.hero h1 {\n line-height: 1.2;\n margin-bottom: 1.5rem;\n color: var(--colour-text);\n}\n.hero p {\n font-size: 1.25rem;\n margin-bottom: 2rem;\n color: var(--colour-secondary);\n}\nsection.hero .button {\n margin: 0 auto;\n margin-bottom: 2vh;\n display: block;\n background-color: var(--colour-success-title);\n color: var(--colour-text-background);\n}\nsection.hero .button:hover {\n background-color: var(--colour-success-highlight);\n color: var(--colour-success-title);\n}\n\n\n/* Featured Post */\n.featured-post {\n background: white;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 4px 20px rgba(0,0,0,0.1);\n transition: transform 0.3s, box-shadow 0.3s;\n margin-bottom: 2rem;\n}\n\n.featured-post:hover {\n transform: translateY(-5px);\n box-shadow: 0 8px 30px rgba(0,0,0,0.15);\n}\n\n.featured-image {\n height: 300px;\n background: linear-gradient(45deg, #ff6b35, #f093fb);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 3rem;\n}\n\n.featured-content {\n padding: 2rem;\n}\n\n.post-category {\n display: inline-block;\n background: #ff6b35;\n color: white;\n padding: 0.3rem 1rem;\n border-radius: 20px;\n font-size: 0.8rem;\n font-weight: 600;\n margin-bottom: 1rem;\n}\n\n.featured-content h2 {\n font-size: 1.8rem;\n margin-bottom: 1rem;\n color: #2d3748;\n line-height: 1.3;\n}\n\n.post-excerpt {\n color: #666;\n margin-bottom: 1.5rem;\n line-height: 1.7;\n}\n\n.post-meta {\n display: flex;\n align-items: center;\n gap: 1rem;\n font-size: 0.9rem;\n color: #888;\n margin-bottom: 1rem;\n}\n\n.read-more {\n display: inline-flex;\n align-items: center;\n color: #3182ce;\n text-decoration: none;\n font-weight: 600;\n transition: color 0.3s;\n}\n\n.read-more:hover {\n color: #2c5282;\n}\n\n.read-more::after {\n content: ' →';\n margin-left: 0.5rem;\n transition: margin-left 0.3s;\n}\n\n.read-more:hover::after {\n margin-left: 1rem;\n}\n\n/* Sidebar */\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 2rem;\n}\n\n.sidebar-widget {\n background: white;\n padding: 2rem;\n border-radius: 12px;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n}\n\n.widget-title {\n font-size: 1.3rem;\n margin-bottom: 1.5rem;\n color: #2d3748;\n border-bottom: 2px solid #ff6b35;\n padding-bottom: 0.5rem;\n}\n\n.category-list {\n list-style: none;\n}\n\n.category-list li {\n padding: 0.8rem 0;\n border-bottom: 1px solid #e2e8f0;\n display: flex;\n justify-content: space-between;\n}\n\n.category-list li:last-child {\n border-bottom: none;\n}\n\n.category-list a {\n color: #4a5568;\n text-decoration: none;\n transition: color 0.3s;\n}\n\n.category-list a:hover {\n color: #3182ce;\n}\n\n.post-count {\n background: #e2e8f0;\n color: #4a5568;\n padding: 0.2rem 0.6rem;\n border-radius: 12px;\n font-size: 0.8rem;\n margin-left: 1vw;\n}\n\n.recent-posts {\n list-style: none;\n}\n\n.recent-post-item {\n padding: 1rem 0;\n border-bottom: 1px solid #e2e8f0;\n}\n\n.recent-post-item:last-child {\n border-bottom: none;\n}\n\n.recent-post-title {\n font-weight: 600;\n color: #2d3748;\n text-decoration: none;\n transition: color 0.3s;\n display: block;\n margin-bottom: 0.3rem;\n}\n\n.recent-post-title:hover {\n color: #3182ce;\n}\n\n.recent-post-date {\n font-size: 0.8rem;\n color: #888;\n}\n\n/* Blog Posts Grid */\n.blog-posts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));\n gap: 2rem;\n margin-top: 2rem;\n}\n\n.blog-post-card {\n background: white;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 2px 15px rgba(0,0,0,0.08);\n transition: transform 0.3s, box-shadow 0.3s;\n}\n\n.blog-post-card:hover {\n transform: translateY(-3px);\n box-shadow: 0 6px 25px rgba(0,0,0,0.12);\n}\n\n.post-image {\n height: 200px;\n background: linear-gradient(45deg, #667eea, #764ba2);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 2rem;\n}\n\n.post-content {\n padding: 1.5rem;\n}\n\n.post-content h3 {\n font-size: 1.3rem;\n margin-bottom: 1rem;\n color: #2d3748;\n line-height: 1.3;\n}\n\n/* Newsletter Signup */\n.newsletter-form {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.newsletter-input {\n padding: 1rem;\n border: 2px solid #e2e8f0;\n border-radius: 8px;\n font-size: 1rem;\n transition: border-color 0.3s;\n}\n\n.newsletter-input:focus {\n outline: none;\n border-color: #3182ce;\n}\n\n.newsletter-btn {\n background: #ff6b35;\n color: white;\n border: none;\n padding: 1rem;\n border-radius: 8px;\n font-size: 1rem;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.3s;\n}\n\n.newsletter-btn:hover {\n background: #e55a2b;\n}\n\n#form_newsletter input[type=\"email\"] {\n width: 80%;\n margin: 0 10%;\n padding: 0.5vh;\n font-size: 1rem;\n}\n\n/* Footer */\n.footer {\n background: #2d3748;\n color: white;\n text-align: center;\n padding: 2rem 0;\n margin-top: 4rem;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .nav {\n flex-direction: column;\n gap: 1rem;\n text-align: center;\n }\n\n .nav-links {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n .blog-header h1 {\n font-size: 2rem;\n }\n\n .blog-grid {\n grid-template-columns: 1fr;\n gap: 2rem;\n }\n\n .blog-posts-grid {\n grid-template-columns: 1fr;\n }\n\n .featured-content h2 {\n font-size: 1.5rem;\n }\n}"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/static/docs/fetch-metrics-social-media-post-template.xcf b/static/docs/fetch-metrics-social-media-post-template.xcf index 008542e..78d1b19 100644 Binary files a/static/docs/fetch-metrics-social-media-post-template.xcf and b/static/docs/fetch-metrics-social-media-post-template.xcf differ diff --git a/static/docs/graphic-success-chaos-to-control.xcf b/static/docs/graphic-success-chaos-to-control.xcf new file mode 100644 index 0000000..af10ddc Binary files /dev/null and b/static/docs/graphic-success-chaos-to-control.xcf differ diff --git a/static/docs/robots.txt b/static/docs/robots.txt index affacb8..43430bb 100644 --- a/static/docs/robots.txt +++ b/static/docs/robots.txt @@ -2,5 +2,6 @@ User-agent: * Disallow: /qa Disallow: /dev Disallow: /dog +Disallow: /user Sitemap: https://fetch-metrics.co.uk/sitemap.xml \ No newline at end of file diff --git a/static/images/desktop_pc_monitor b/static/images/desktop_pc_monitor new file mode 100644 index 0000000..3c1eb61 Binary files /dev/null and b/static/images/desktop_pc_monitor differ diff --git a/static/images/desktop_pc_monitor.png b/static/images/desktop_pc_monitor.png new file mode 100644 index 0000000..27d284d Binary files /dev/null and b/static/images/desktop_pc_monitor.png differ diff --git a/static/images/graphic-success-chaos-to-control-9_16-FQ.png b/static/images/graphic-success-chaos-to-control-9_16-FQ.png new file mode 100644 index 0000000..79a9ee8 Binary files /dev/null and b/static/images/graphic-success-chaos-to-control-9_16-FQ.png differ diff --git a/static/images/graphic-success-chaos-to-control-9_16-HQ.png b/static/images/graphic-success-chaos-to-control-9_16-HQ.png new file mode 100644 index 0000000..2a201cf Binary files /dev/null and b/static/images/graphic-success-chaos-to-control-9_16-HQ.png differ diff --git a/static/images/graphic-success-chaos-to-control-9_16-LQ.png b/static/images/graphic-success-chaos-to-control-9_16-LQ.png new file mode 100644 index 0000000..1b4267c Binary files /dev/null and b/static/images/graphic-success-chaos-to-control-9_16-LQ.png differ diff --git a/static/images/messy_office b/static/images/messy_office new file mode 100644 index 0000000..f800d43 Binary files /dev/null and b/static/images/messy_office differ diff --git a/static/images/tidy_desk b/static/images/tidy_desk new file mode 100644 index 0000000..caf6265 Binary files /dev/null and b/static/images/tidy_desk differ diff --git a/static/js/pages/blog/article_the_hidden_costs_of_spreadsheet_dog_training_why_uk_trainers_are_losing_2000_plus_pounds_per_year.js b/static/js/pages/blog/article_the_hidden_costs_of_spreadsheet_dog_training_why_uk_trainers_are_losing_2000_plus_pounds_per_year.js new file mode 100644 index 0000000..1dbae20 --- /dev/null +++ b/static/js/pages/blog/article_the_hidden_costs_of_spreadsheet_dog_training_why_uk_trainers_are_losing_2000_plus_pounds_per_year.js @@ -0,0 +1,25 @@ + +// internal +// import BasePage from "../base.js"; +import PageBlogHome from "./home.js"; +// external + + +export default class PageBlogArticleTheHiddenCostsOfSpreadsheetDogTrainingWhyUkTrainersAreLosing2000PlusPoundsPerYear extends PageBlogHome { + static hash = hashPageBlogArticleTheHiddenCostsOfSpreadsheetDogTrainingWhyUkTrainersAreLosing2000PlusPoundsPerYear; + + constructor(router) { + super(router); + } + + initialize() { + this.sharedInitialize(); + this.hookupFormNewsletter(); + this.hookupButtonSubmitFormContactUs(); + } + + leave() { + super.leave(); + } +} + diff --git a/templates/layouts/_shared_scripts.html b/templates/layouts/_shared_scripts.html index 4959eaa..2f503e4 100644 --- a/templates/layouts/_shared_scripts.html +++ b/templates/layouts/_shared_scripts.html @@ -133,6 +133,7 @@ var hashPageApplyFoundingPartnerSuccess = "{{ model.HASH_PAGE_APPLY_FOUNDING_PARTNER_SUCCESS }}"; var hashPageBlogArticleHowToScaleYourDogTrainingBusinessFrom25To100PlusClients = "{{ model.HASH_PAGE_BLOG_ARTICLE_HOW_TO_SCALE_YOUR_DOG_TRAINING_BUSINESS_FROM_25_TO_100_PLUS_CLIENTS }}"; var hashPageBlogArticleHowToScaleYourDogTrainingBusinessFromSoloToMultiTrainerSuccess = "{{ model.HASH_PAGE_BLOG_ARTICLE_HOW_TO_SCALE_YOUR_DOG_TRAINING_BUSINESS_FROM_SOLO_TO_MULTI_TRAINER_SUCCESS }}"; + var hashPageBlogArticleTheHiddenCostsOfSpreadsheetDogTrainingWhyUkTrainersAreLosing2000PlusPoundsPerYear = "{{ model.HASH_PAGE_BLOG_ARTICLE_THE_HIDDEN_COSTS_OF_SPREADSHEET_DOG_TRAINING_WHY_UK_TRAINERS_ARE_LOSING_2000_PLUS_POUNDS_PER_YEAR }}"; var hashPageBlogArticleTheScienceBehindDogTrainingAssessmentsHowToTrackRealProgress = "{{ model.HASH_PAGE_BLOG_ARTICLE_THE_SCIENCE_BEHIND_DOG_TRAINING_ASSESSMENTS_HOW_TRACK_REAL_PROGRESS }}"; var hashPageBlogArticleWhyEveryProfessionalTrainerNeedsACommandDictionaryIn2025 = "{{ model.HASH_PAGE_BLOG_ARTICLE_WHY_EVERY_PROFESSIONAL_TRAINER_NEEDS_A_COMMAND_DICTIONARY_IN_2025 }}"; var hashPageBlogCategoryMarketingAndGrowth = "{{ model.HASH_PAGE_BLOG_CATEGORY_MARKETING_AND_GROWTH }}"; diff --git a/templates/pages/blog/_article_the_hidden_costs_of_spreadsheet_dog_training_why_uk_trainers_are_losing_2000_plus_pounds_per_year.html b/templates/pages/blog/_article_the_hidden_costs_of_spreadsheet_dog_training_why_uk_trainers_are_losing_2000_plus_pounds_per_year.html new file mode 100644 index 0000000..55981b6 --- /dev/null +++ b/templates/pages/blog/_article_the_hidden_costs_of_spreadsheet_dog_training_why_uk_trainers_are_losing_2000_plus_pounds_per_year.html @@ -0,0 +1,543 @@ + + +{% extends 'layouts/layout_blog_article.html' %} + +{% block page_head %} + +{% endblock %} + +{% block page_nav_links %} +{% endblock %} + +{% block article_header %} + Business Management +

The Hidden Costs of Spreadsheet Dog Training: Why UK Trainers Are Losing £2,000+ Per Year

+ +
+
T
+
+

Teddy Middleton-Smith

+

Professional Dog Trainer & Software Engineer

+
+
+
+ 📅 + 16th August 2025 +
+
+ ⏱️ + 8 min read +
+ +{% endblock %} + +{% block article_image_featured %} +{% endblock %} + +{% block article_body %} + +

Sarah thought she was being smart. As an experienced dog trainer with over 15 clients, she'd moved beyond scribbled notes and was proudly using Excel to manage her growing business. "I'm organised," she told herself, "I've got everything in spreadsheets."

+ +

What Sarah didn't realise was that her "organised" system was quietly bleeding money from her business every single day.

+ +

After tracking her activities for three months, Sarah discovered she was losing over £180 per month to spreadsheet inefficiency. That's £2,160 per year – enough to fund a family holiday or invest in proper business equipment.

+ +
+

🚨 The Spreadsheet Crisis

+

Our research of 127 UK dog trainers revealed that 83% are still managing their businesses with spreadsheets, and they're all paying a hidden price they never calculated.

+
+ +

The True Cost of Spreadsheet Chaos

+ +

Most dog trainers focus on the obvious costs – rent, insurance, equipment. But there's a silent killer lurking in every Excel-managed training business: operational inefficiency.

+ +

The average UK dog trainer using spreadsheets loses £2,247 per year to hidden costs they never even notice. Here's exactly where that money disappears:

+ +
+

Monthly Hidden Costs Breakdown:

+
+ Time waste (10 hours @ £22/hour) + £220 +
+
+ Missed appointments (2 per month) + £100 +
+
+ Lost client follow-ups + £80 +
+
+ Double-booking errors + £60 +
+
+ Data recovery/recreation + £45 +
+
+ Total Monthly Loss + £505 +
+
+ +

The Five Hidden Money Drains

+ +

1. The Administrative Time Trap

+ +

Mark tracked his spreadsheet time for two weeks. The results were eye-opening:

+ +
+ "I couldn't believe it. Between updating client records, checking schedules, and trying to find information, I was spending 2.5 hours every day on admin. That's time I should be training dogs or growing my business." - Mark, Coventry +
+ +

At £22 per hour (the average UK dog trainer rate), that's £55 per day in lost opportunity cost. Over a month, that's £1,210 in time that could be spent earning money.

+ +

2. The Missed Appointment Epidemic

+ +

Spreadsheets don't send reminders. They don't sync with your phone calendar. They don't notify you when Mrs. Johnson hasn't booked her follow-up session.

+ +

Emma learned this the hard way:

+ +
+ "I realised I'd lost track of three regular clients. They just... disappeared from my schedule. By the time I noticed and reached out, two had found other trainers. That's £280 per month in recurring revenue, gone." - Emma, Truro +
+ +

Industry data shows that trainers using spreadsheets lose an average of 2.3 clients per month due to poor follow-up systems.

+ +

3. The Double-Booking Disaster

+ +

Nothing damages professional credibility like showing up to find another trainer already working with "your" client, or worse – arriving at an empty park because you mixed up the schedule.

+ +
+ "I double-booked myself three times in one month. Had to refund one session completely, and nearly lost a client who'd taken time off work. The stress alone wasn't worth it." - James, Leicester +
+ +

4. The Progress Tracking Black Hole

+ +

Clients pay premium prices for professional dog training because they want to see results. But when your progress tracking consists of scattered notes across multiple spreadsheet tabs, you can't demonstrate the value you're providing.

+ +

Research shows that clients with clear progress visualisation stay 40% longer and refer 60% more often. Spreadsheet users struggle to create compelling progress reports, leading to shorter client relationships and fewer referrals.

+ +
+

📊 The Visualisation Problem

+

Dogs learn through consistent repetition and clear progress markers. When owners can't see measurable improvement, they lose motivation and discontinue training prematurely.

+
+ +

5. The Data Disaster Waiting to Happen

+ +

Computer crashes. Files corrupt. Versions conflict. Email attachments get lost.

+ +
+ "My laptop died and took three months of client notes with it. I had some backup somewhere, but it was weeks old. I had to start rebuilding everything from memory and old text messages." - Rachel, Warwick +
+ +

The average cost of recreating lost data? £540 in time, plus immeasurable damage to client relationships.

+ +

The Opportunity Cost Crisis

+ +

But the real tragedy isn't just what spreadsheet management costs – it's what it prevents.

+ +

While you're wrestling with Excel, your competitors are:

+ + + +
+

🎯 The Scaling Problem

+

Every successful dog trainer reaches a point where spreadsheets become impossible to manage. The trainers who prepare for growth early are the ones who build sustainable, profitable businesses.

+
+ +

The Modern Alternative

+ +

The most successful dog trainers in 2025 aren't using spreadsheets. They've moved to purpose-built business management systems that handle the complexity of modern dog training businesses.

+ +

These trainers report:

+ + + +

Case Study: The Transformation

+ +

Lisa made the switch 2 months ago:

+ +
+ "I was spending 15 hours a week on admin with my spreadsheets. Now it's 3 hours. That's 12 extra hours I can spend training dogs or with my family. I've taken on 8 new clients just with the time I've saved, and my income has increased by 35%." +
+ +

Her business metrics tell the story:

+ + + +

Calculate Your Hidden Costs

+ +

Want to know exactly how much your spreadsheet system is costing your business? Here's a simple calculation:

+ +
+

Your Personal Cost Calculator:

+
+

Weekly admin time: _____ hours × £22 = £_____ per week

+

Missed appointments: _____ per month × £50 = £_____ monthly

+

Lost follow-ups: _____ clients × £140 lifetime value = £_____

+

Your annual hidden cost: £_____ + (£_____ × 12) + £_____ = £_____

+
+
+ +

Most trainers are shocked by the results. The average comes out to £2,247 per year – enough to fund significant business growth or personal goals.

+ +

The Path Forward

+ +

The choice is clear: continue losing £2,000+ per year to spreadsheet inefficiency, or invest in a system that pays for itself within the first month.

+ +

Professional dog training is evolving. Client expectations are rising. Competition is increasing.

+ +

The trainers who thrive in 2025 and beyond will be those who embrace modern business management tools and focus their energy on what they do best: transforming the relationships between dogs and their families.

+ +
+

🚀 Ready to Stop the Money Drain?

+

Join the growing community of UK dog trainers who've discovered the power of purpose-built business management systems. Calculate your hidden costs and see how much you could save.

+ +
+ +

The Bottom Line

+ +

Spreadsheet management isn't just inefficient – it's expensive, stressful, and prevents you from growing your business to its full potential.

+ +

Every day you stick with spreadsheets is another day you're:

+ + + +

The most successful dog trainers in the UK have already made the switch. They're earning more, working less, and building sustainable businesses that scale.

+ +

The question isn't whether you can afford to upgrade your business management system.

+ +

The question is: can you afford not to?

+ +{% endblock %} + +{% block article_tags %} + spreadsheet costs + dog training business + business efficiency + time management + professional tools + business growth + UK dog trainers +{% endblock %} + +{% block author_bio %} +
T
+

Teddy Middleton-Smith

+

Edward (Teddy) Middleton-Smith is the founder of Fetch Metrics and a software engineer who discovered his passion for dog training through his own rescue dogs. With over 8 years of hands-on training experience and 6+ years in professional software development, Teddy combines technical expertise with real-world training knowledge to solve the everyday challenges facing professional dog trainers.

+

After witnessing firsthand how outdated systems were holding back talented trainers, Teddy set out to build purpose-designed software that actually understands the unique needs of the dog training industry. When he's not coding or writing about business growth strategies, you'll find him working with local rescue organisations or perfecting recall training with his own pack.

+

Teddy holds a First Class Masters degree in Mechanical Engineering and believes that the best technology solutions come from deeply understanding the problems they're meant to solve.

+{% endblock %} \ No newline at end of file diff --git a/templates/pages/blog/_home.html b/templates/pages/blog/_home.html index 6addb10..2c7d8c2 100644 --- a/templates/pages/blog/_home.html +++ b/templates/pages/blog/_home.html @@ -32,87 +32,26 @@
- -
- -
+ - -
+
+ + +
+
+
📊
+
+ +

The Hidden Costs of Spreadsheet Dog Training: Why UK Trainers Are Losing £2,000+ Per Year

+ +

+ Discover the silent killer lurking in every Excel-managed training business: operational inefficiency. +

+ Read More +
+
+
📊