diff --git a/README.md b/README.md index 4be183b..7a20369 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -Precision and Research Technology Systems Limited -Website with online store +Dog training management web app Powered by flask diff --git a/app.py b/app.py index 8eb2306..11f940a 100644 --- a/app.py +++ b/app.py @@ -19,6 +19,7 @@ Initializes the Flask application, sets the configuration based on the environme from config import app_config, Config from dog_training.controllers.dog.dog import routes_dog from dog_training.controllers.dog.dog_command_link import routes_dog_dog_command_link +from dog_training.controllers.dog.home import routes_dog_home from controllers.core.home import routes_core_home from controllers.legal.legal import routes_legal from controllers.user.user import routes_user @@ -112,6 +113,7 @@ with app.app_context(): app.register_blueprint(routes_core_home) app.register_blueprint(routes_dog) +app.register_blueprint(routes_dog_home) app.register_blueprint(routes_dog_dog_command_link) app.register_blueprint(routes_legal) app.register_blueprint(routes_user) diff --git a/business_objects/base.py b/business_objects/base.py index fc912e7..6899d13 100644 --- a/business_objects/base.py +++ b/business_objects/base.py @@ -27,6 +27,7 @@ class Base(): ATTR_ID_USER_MANAGER: ClassVar[str] = 'id_user_manager' FLAG_ACCESS_LEVEL_REQUIRED: ClassVar[str] = 'access_level_required' FLAG_ACTIVE: ClassVar[str] = 'active' + FLAG_ACTIVE_ONLY: ClassVar[str] = 'active_only' FLAG_ADDRESS: ClassVar[str] = 'address' FLAG_ADDRESS_LINE_1: ClassVar[str] = 'address_line_1' FLAG_ADDRESS_LINE_2: ClassVar[str] = 'address_line_2' @@ -62,6 +63,7 @@ class Base(): FLAG_PRIORITY: ClassVar[str] = 'priority' FLAG_REGION: ClassVar[str] = 'region' FLAG_ROWS: ClassVar[str] = 'rows' + FLAG_SEARCH_TEXT: ClassVar[str] = 'search_text' FLAG_SYMBOL: ClassVar[str] = 'symbol' FLAG_URL: ClassVar[str] = 'url' FLAG_USER: ClassVar[str] = 'authorisedUser' # 'user' already used diff --git a/business_objects/dog/command.py b/business_objects/dog/command.py index 54602b5..55e6ad7 100644 --- a/business_objects/dog/command.py +++ b/business_objects/dog/command.py @@ -24,7 +24,7 @@ class Command(SQLAlchemy_ABC, Base): FLAG_COMMAND: ClassVar[str] = 'command' FLAG_HAND_SIGNAL_DEFAULT_DESCRIPTION: ClassVar[str] = 'hand-signal-default-description' FLAG_CAN_HAVE_BUTTON: ClassVar[str] = 'can-have-button' - NAME_ATTR_OPTION_VALUE: ClassVar[str] = FLAG_COMMAND + NAME_ATTR_OPTION_VALUE: ClassVar[str] = ATTR_ID_COMMAND NAME_ATTR_OPTION_TEXT: ClassVar[str] = Base.FLAG_NAME __tablename__ = 'DOG_Command' @@ -78,7 +78,7 @@ class Command(SQLAlchemy_ABC, Base): _m = 'Command.from_json' command = cls() if json is None: return Command - Helper_App.console_log(f'{_m}\njson: {json}') + # Helper_App.console_log(f'{_m}\njson: {json}') command.id_command = -1 command.id_command_category = json[Command_Category.FLAG_COMMAND_CATEGORY] command.name = json[cls.FLAG_NAME] @@ -87,12 +87,13 @@ class Command(SQLAlchemy_ABC, Base): command.notes = json[cls.FLAG_NOTES] command.active = json[cls.FLAG_ACTIVE] command.created_on = json.get(cls.FLAG_CREATED_ON, None) - Helper_App.console_log(f'Command: {command}') + # Helper_App.console_log(f'Command: {command}') return command def to_json(self): as_json = { - self.FLAG_COMMAND: self.id_command + **self.get_shared_json_attributes(self) + , self.ATTR_ID_COMMAND: self.id_command , Command_Category.FLAG_COMMAND_CATEGORY: self.id_command_category , self.FLAG_NAME: self.name , self.FLAG_HAND_SIGNAL_DEFAULT_DESCRIPTION: self.hand_signal_default_description @@ -101,7 +102,7 @@ class Command(SQLAlchemy_ABC, Base): , self.FLAG_ACTIVE: self.active , self.FLAG_CREATED_ON: self.created_on } - Helper_App.console_log(f'as_json: {as_json}') + # Helper_App.console_log(f'as_json: {as_json}') return as_json def __repr__(self): diff --git a/business_objects/dog/command_category.py b/business_objects/dog/command_category.py index 89bdd9e..0aa62d5 100644 --- a/business_objects/dog/command_category.py +++ b/business_objects/dog/command_category.py @@ -19,8 +19,9 @@ from typing import ClassVar class Command_Category(SQLAlchemy_ABC, Base): + ATTR_ID_COMMAND_CATEGORY: ClassVar[str] = 'id_command_category' FLAG_COMMAND_CATEGORY: ClassVar[str] = 'command-category' - NAME_ATTR_OPTION_VALUE: ClassVar[str] = FLAG_COMMAND_CATEGORY + NAME_ATTR_OPTION_VALUE: ClassVar[str] = ATTR_ID_COMMAND_CATEGORY NAME_ATTR_OPTION_TEXT: ClassVar[str] = Base.FLAG_NAME __tablename__ = 'DOG_Command_Category' @@ -50,23 +51,24 @@ class Command_Category(SQLAlchemy_ABC, Base): _m = 'Command_Category.from_json' command_category = cls() if json is None: return Command_Category - Helper_App.console_log(f'{_m}\njson: {json}') + # Helper_App.console_log(f'{_m}\njson: {json}') command_category.id_command_category = -1 command_category.code = json[cls.FLAG_CODE] command_category.name = json[cls.FLAG_NAME] command_category.active = json[cls.FLAG_ACTIVE] - Helper_App.console_log(f'Command_Category: {command_category}') + # Helper_App.console_log(f'Command_Category: {command_category}') return command_category def to_json(self): as_json = { - self.FLAG_COMMAND_CATEGORY: self.id_command_category + **self.get_shared_json_attributes(self) + , self.ATTR_ID_COMMAND_CATEGORY: self.id_command_category , self.FLAG_CODE: self.code , self.FLAG_NAME: self.name , self.FLAG_ACTIVE: self.active } - Helper_App.console_log(f'as_json: {as_json}') + # Helper_App.console_log(f'as_json: {as_json}') return as_json def __repr__(self): diff --git a/business_objects/dog/dog.py b/business_objects/dog/dog.py index 470986a..cb4610f 100644 --- a/business_objects/dog/dog.py +++ b/business_objects/dog/dog.py @@ -24,8 +24,8 @@ class Dog(SQLAlchemy_ABC, Base): FLAG_APPEARANCE: ClassVar[str] = 'appearance' FLAG_MASS_KG: ClassVar[str] = 'mass-kg' FLAG_NOTES: ClassVar[str] = 'notes' - NAME_ATTR_OPTION_VALUE: ClassVar[str] = FLAG_DOG - NAME_ATTR_OPTION_TEXT: ClassVar[str] = Base.FLAG_EMAIL + NAME_ATTR_OPTION_VALUE: ClassVar[str] = ATTR_ID_DOG + NAME_ATTR_OPTION_TEXT: ClassVar[str] = Base.FLAG_NAME __tablename__ = 'DOG_Dog' __table_args__ = { 'extend_existing': True } @@ -71,27 +71,28 @@ class Dog(SQLAlchemy_ABC, Base): _m = 'Dog.from_json' dog = cls() if json is None: return Dog - Helper_App.console_log(f'{_m}\njson: {json}') + # Helper_App.console_log(f'{_m}\njson: {json}') dog.id_dog = -1 dog.name = json[cls.FLAG_NAME] dog.appearance = json[cls.FLAG_APPEARANCE] dog.mass_kg = json[cls.FLAG_MASS_KG] dog.notes = json[cls.FLAG_NOTES] dog.active = json[cls.FLAG_ACTIVE] - Helper_App.console_log(f'Dog: {dog}') + # Helper_App.console_log(f'Dog: {dog}') return dog def to_json(self): as_json = { - self.FLAG_DOG: self.id_dog + **self.get_shared_json_attributes(self) + , self.ATTR_ID_DOG: self.id_dog , self.FLAG_NAME: self.name , self.FLAG_APPEARANCE: self.appearance , self.FLAG_MASS_KG: self.mass_kg , self.FLAG_NOTES: self.notes , self.FLAG_ACTIVE: self.active } - Helper_App.console_log(f'as_json: {as_json}') + # Helper_App.console_log(f'as_json: {as_json}') return as_json def __repr__(self): diff --git a/business_objects/dog/dog_command_link.py b/business_objects/dog/dog_command_link.py index 2e0268d..5ef93de 100644 --- a/business_objects/dog/dog_command_link.py +++ b/business_objects/dog/dog_command_link.py @@ -24,10 +24,11 @@ from typing import ClassVar class Dog_Command_Link(SQLAlchemy_ABC, Base): + ATTR_ID_DOG_COMMAND_LINK: ClassVar[str] = 'id_link' FLAG_DOG_COMMAND_LINK: ClassVar[str] = 'dog_command_link' FLAG_HAND_SIGNAL_DESCRIPTION: ClassVar[str] = 'hand-signal-description' - NAME_ATTR_OPTION_VALUE: ClassVar[str] = FLAG_DOG_COMMAND_LINK - NAME_ATTR_OPTION_TEXT: ClassVar[str] = Base.FLAG_NAME + NAME_ATTR_OPTION_VALUE: ClassVar[str] = ATTR_ID_DOG_COMMAND_LINK + NAME_ATTR_OPTION_TEXT: ClassVar[str] = FLAG_HAND_SIGNAL_DESCRIPTION __tablename__ = 'DOG_Dog_Command_Link' __table_args__ = { 'extend_existing': True } @@ -67,7 +68,7 @@ class Dog_Command_Link(SQLAlchemy_ABC, Base): _m = 'Dog_Command_Link.from_json' dog_command_link = cls() if json is None: return dog_command_link - Helper_App.console_log(f'{_m}\njson: {json}') + # Helper_App.console_log(f'{_m}\njson: {json}') dog_command_link.id_link = -1 dog_command_link.id_dog = json[Dog.FLAG_DOG] dog_command_link.id_command = json[Command.FLAG_COMMAND] @@ -76,12 +77,13 @@ class Dog_Command_Link(SQLAlchemy_ABC, Base): dog_command_link.active = json[cls.FLAG_ACTIVE] dog_command_link.created_on = json.get(cls.FLAG_CREATED_ON, None) # dog_command_link.id_command_category = json[Command_Category.FLAG_COMMAND_CATEGORY] - Helper_App.console_log(f'Dog Command Link: {dog_command_link}') + # Helper_App.console_log(f'Dog Command Link: {dog_command_link}') return dog_command_link def to_json(self): as_json = { - self.FLAG_DOG_COMMAND_LINK: self.id_link + **self.get_shared_json_attributes(self) + , self.ATTR_ID_DOG_COMMAND_LINK: self.id_link , Dog.FLAG_DOG: self.id_dog , Command.FLAG_COMMAND: self.id_command , self.FLAG_HAND_SIGNAL_DESCRIPTION: self.hand_signal_description @@ -90,7 +92,7 @@ class Dog_Command_Link(SQLAlchemy_ABC, Base): , self.FLAG_CREATED_ON: self.created_on } # , Command_Category.FLAG_COMMAND_CATEGORY: self.id_command_category - Helper_App.console_log(f'as_json: {as_json}') + # Helper_App.console_log(f'as_json: {as_json}') return as_json def __repr__(self): @@ -170,16 +172,17 @@ class Parameters_Dog_Command_Link(Get_Many_Parameters_Base): @classmethod def from_form_filters_dog_command_link(cls, form): av.val_instance(form, 'form', 'Parameters_Dog_Command_Link.from_form_filters_dog_command_link', Filters_Dog_Command_Link) - has_filter_dog = not (form.id_dog.data == '0' or form.id_dog.data == '' or form.id_dog.data is None) - has_filter_command = not (form.id_command.data == '0' or form.id_command.data == '' or form.id_command.data is None) - active_only = av.input_bool(form.active.data, "active", "Parameters_Dog_Command_Link.from_form_filters_dog_command_link") + has_filter_search_text = not (form.search.data == '' or form.search.data is None) + has_filter_dog = not (has_filter_search_text or form.id_dog.data == '0' or form.id_dog.data == '' or form.id_dog.data is None) + has_filter_command = not (has_filter_search_text or form.id_command.data == '0' or form.id_command.data == '' or form.id_command.data is None) + active_only = av.input_bool(form.active_only.data, "active", "Parameters_Dog_Command_Link.from_form_filters_dog_command_link") return cls( get_all_dog = not has_filter_dog , get_inactive_dog = not active_only - , ids_dog = form.id_dog.data if has_filter_dog else '' + , ids_dog = form.id_dog.data if has_filter_dog else form.search.data if has_filter_search_text else '' , get_all_command = not has_filter_command , get_inactive_command = not active_only - , ids_command = form.id_command.data if has_filter_command else '' + , ids_command = form.id_command.data if has_filter_command else form.search.data if has_filter_search_text else '' ) def to_json(self): diff --git a/business_objects/dog/obedience_level.py b/business_objects/dog/obedience_level.py index 0b12828..c034aa3 100644 --- a/business_objects/dog/obedience_level.py +++ b/business_objects/dog/obedience_level.py @@ -19,6 +19,7 @@ from typing import ClassVar class Obedience_Level(SQLAlchemy_ABC, Base): + ATTR_ID_OBEDIENCE_LEVEL: ClassVar[str] = "id_obedience_level" FLAG_OBEDIENCE_LEVEL: ClassVar[str] = 'obedience-level' NAME_ATTR_OPTION_VALUE: ClassVar[str] = FLAG_OBEDIENCE_LEVEL NAME_ATTR_OPTION_TEXT: ClassVar[str] = Base.FLAG_NAME @@ -61,7 +62,8 @@ class Obedience_Level(SQLAlchemy_ABC, Base): def to_json(self): as_json = { - self.FLAG_OBEDIENCE_LEVEL: self.id_obedience_level + **self.get_shared_json_attributes(self) + , self.ATTR_ID_OBEDIENCE_LEVEL: self.id_obedience_level , self.FLAG_CODE: self.code , self.FLAG_NAME: self.name , self.FLAG_ACTIVE: self.active diff --git a/business_objects/dog/user.py b/business_objects/dog/user.py index 2799f2d..ecec869 100644 --- a/business_objects/dog/user.py +++ b/business_objects/dog/user.py @@ -38,6 +38,7 @@ class User(SQLAlchemy_ABC, Base): def __init__(self): self.id_user = 0 self.is_new = False + self.can_admin_dog = False super().__init__() def from_DB_user(query_row): @@ -51,6 +52,8 @@ class User(SQLAlchemy_ABC, Base): user.is_email_verified = av.input_bool(query_row[5], 'is_email_verified', _m) user.is_super_user = av.input_bool(query_row[9], 'is_super_user', _m) user.is_new = av.input_bool(query_row[12], 'is_new', _m) + + user.can_admin_dog = user.is_super_user return user @staticmethod @@ -66,6 +69,9 @@ class User(SQLAlchemy_ABC, Base): user.email = json['email'] user.is_email_verified = av.input_bool(json['is_email_verified'], 'is_email_verified', _m) user.is_super_user = av.input_bool(json['is_super_user'], 'is_super_user', _m) + + user.can_admin_dog = user.is_super_user + Helper_App.console_log(f'user: {user}') return user @@ -83,11 +89,15 @@ class User(SQLAlchemy_ABC, Base): user.email = user_info['email'] user.is_email_verified = av.input_bool(user_info['email_verified'], 'is_email_verified', _m) user.is_super_user = None + + user.can_admin_dog = user.is_super_user + Helper_App.console_log(f'user: {user}') return user def to_json(self): as_json = { + **self.get_shared_json_attributes(self), 'id_user': self.id_user, 'id_user_auth0': self.id_user_auth0, 'firstname': self.firstname, diff --git a/controllers/dog/dog.py b/controllers/dog/dog.py index c6ebe55..804df5d 100644 --- a/controllers/dog/dog.py +++ b/controllers/dog/dog.py @@ -40,9 +40,9 @@ from altcha import ChallengeOptions, create_challenge, verify_solution routes_dog = Blueprint('routes_dog', __name__) -@routes_dog.route(Model_View_Dog_Base.HASH_DOG_SCRIPTS_SHARED, methods=['GET']) +@routes_dog.route(Model_View_Dog_Base.HASH_GET_DOG_SCRIPTS_SHARED, methods=['GET']) def scripts_section_dog(): - hash_page_current = request.args.get('hash_page_current', default = Model_View_Dog_Base.HASH_SCRIPTS_SECTION_STORE, type = str) + hash_page_current = request.args.get('hash_page_current', default = Model_View_Dog_Base.HASH_GET_DOG_SCRIPTS_SHARED, type = str) model = Model_View_Dog_Base(hash_page_current=hash_page_current) template = render_template('js/sections/dog.js', model = model) return Response(template, mimetype='application/javascript') \ No newline at end of file diff --git a/controllers/dog/dog_command_link.py b/controllers/dog/dog_command_link.py index 0f2f56e..f5a359b 100644 --- a/controllers/dog/dog_command_link.py +++ b/controllers/dog/dog_command_link.py @@ -53,6 +53,7 @@ def dog_command_links(): model = Model_View_Dog_Dog_Command_Link(form_filters_old = form_filters) if not model.is_user_logged_in: return redirect(url_for('routes_core_home.home')) + Helper_App.console_log(f'form_filters={form_filters}') return render_template('pages/dog/_dog_command_links.html', model = model) """ diff --git a/controllers/dog/home.py b/controllers/dog/home.py new file mode 100644 index 0000000..9cd8c79 --- /dev/null +++ b/controllers/dog/home.py @@ -0,0 +1,50 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: App Routing +Feature: Core - Contact Routes + +Description: +Contact Page Controller. +""" + +# IMPORTS +# internal +from dog_training.business_objects.api import API +from dog_training.business_objects.dog.command import Command +from dog_training.business_objects.dog.dog_command_link import Dog_Command_Link +from dog_training.datastores.datastore_dog import DataStore_Dog +from dog_training.forms.dog.dog_command_link import Filters_Dog_Command_Link +from dog_training.helpers.helper_app import Helper_App +from dog_training.models.model_view_dog_base import Model_View_Dog_Base +from dog_training.models.model_view_home import Model_View_Home +import dog_training.lib.argument_validation as av +# external +from flask import Flask, render_template, jsonify, request, render_template_string, send_from_directory, redirect, url_for, session, Blueprint, current_app, flash +from flask_mail import Mail, Message +from dog_training.extensions import db, oauth, mail +from urllib.parse import quote_plus, urlencode +from authlib.integrations.flask_client import OAuth +from authlib.integrations.base_client import OAuthError +from urllib.parse import quote, urlparse, parse_qs +import json +import base64 +import hmac +import hashlib +import datetime +from altcha import ChallengeOptions, create_challenge, verify_solution + + +routes_dog_home = Blueprint('routes_dog_home', __name__) + + +@routes_dog_home.route(Model_View_Dog_Base.HASH_PAGE_DOG_HOME, methods=['GET']) +def dog_command_links(): + Helper_App.console_log('DOG HOME') + model = Model_View_Dog_Base(hash_page_current = Model_View_Dog_Base.HASH_PAGE_DOG_HOME) + if not model.is_user_logged_in: + return redirect(url_for('routes_dog_home.home')) + return render_template('pages/dog/_home.html', model = model) + diff --git a/controllers/user/user.py b/controllers/user/user.py index 5dd3415..dfdccfd 100644 --- a/controllers/user/user.py +++ b/controllers/user/user.py @@ -55,8 +55,8 @@ def handle_db_disconnect(f): def login(): oauth = current_app.extensions['authlib.integrations.flask_client'] try: - Helper_App.console_log('login') - Helper_App.console_log(f'method={request.method}') + # Helper_App.console_log('login') + # Helper_App.console_log(f'method={request.method}') try: data = request.json try: @@ -65,34 +65,15 @@ def login(): data = {} except: data = {} - Helper_App.console_log(f'data={data}') + # Helper_App.console_log(f'data={data}') hash_callback = data.get(Model_View_Base.FLAG_CALLBACK, Model_View_Base.HASH_PAGE_HOME) - Helper_App.console_log(f'hash_callback: {hash_callback}') + # Helper_App.console_log(f'hash_callback: {hash_callback}') - """ - # Verify CSRF token manually - Helper_App.console_log(f'request headers={request.headers}') - token = request.headers.get(Model_View_Base.FLAG_CSRF_TOKEN) - Helper_App.console_log(f'token={token}') - Helper_App.console_log(f'session={session}') - Helper_App.console_log(f'session token={session.get('csrf_token')}') - if not token or token != session.get('csrf_token'): - token = data.get(Model_View_Base.FLAG_CSRF_TOKEN, None) - Helper_App.console_log(f'token={token}') - if not token or token != session.get('csrf_token'): - raise BadRequest('Invalid or missing CSRF token') - """ - # OAuth login - # callback_login = F'{Model_View_Base.HASH_CALLBACK_LOGIN}{data.get(Model_View_Base.FLAG_CALLBACK, Model_View_Base.HASH_PAGE_HOME)}' - - # encoded_path = quote(data.get(Model_View_Base.FLAG_CALLBACK, Model_View_Base.HASH_PAGE_HOME)) - uri_redirect = url_for('routes_user.login_callback', _external=True) # , subpath=encoded_path - - # uri_redirect = f'{current_app.URL_HOST}/login_callback?subpath={data.get(Model_View_Base.FLAG_CALLBACK, Model_View_Base.HASH_PAGE_HOME)}' - Helper_App.console_log(f'redirect uri: {uri_redirect}') + uri_redirect = url_for('routes_user.login_callback', _external=True) + # Helper_App.console_log(f'redirect uri: {uri_redirect}') - Helper_App.console_log(f'Before red') - Helper_App.console_log(f"Registered clients: {list(oauth._clients.keys())}") + # Helper_App.console_log(f'Before red') + # Helper_App.console_log(f"Registered clients: {list(oauth._clients.keys())}") try: with current_app.app_context(): red = oauth.auth0.authorize_redirect( @@ -101,9 +82,9 @@ def login(): ) except Exception as e: Helper_App.console_log(f"Error: {str(e)}") - Helper_App.console_log(f'redirect: {red}') + # Helper_App.console_log(f'redirect: {red}') headers = red.headers['Location'] - Helper_App.console_log(f'headers: {headers}') + # Helper_App.console_log(f'headers: {headers}') parsed_url = urlparse(headers) query_params = parse_qs(parsed_url.query) Helper_App.console_log(f""" @@ -125,9 +106,9 @@ def login(): @handle_db_disconnect def login_callback(): oauth = current_app.extensions['authlib.integrations.flask_client'] - Helper_App.console_log('login_callback') + # Helper_App.console_log('login_callback') try: - Helper_App.console_log(f'Redceived state: {request.args.get("state")}') + # Helper_App.console_log(f'Redceived state: {request.args.get("state")}') error_state = request.args.get(Model_View_User.FLAG_ERROR_OAUTH) has_error = error_state is not None if has_error: @@ -142,7 +123,7 @@ def login_callback(): Helper_App.console_log(f"Error: {str(e)}") session[current_app.config['ID_TOKEN_USER']] = token user = User.from_json_auth0(token) - Helper_App.console_log(f'user: {user}') + # Helper_App.console_log(f'user: {user}') filters = Parameters_User.from_user(user) datastore_user = DataStore_User() users, errors = datastore_user.get_many_user(filters, user) diff --git a/datastores/datastore_user.py b/datastores/datastore_user.py index 0d5cf78..dcee227 100644 --- a/datastores/datastore_user.py +++ b/datastores/datastore_user.py @@ -72,11 +72,11 @@ class DataStore_User(DataStore_Base): _m = 'DataStore_User.get_many_user' Helper_App.console_log(_m) Helper_App.console_log(f'user_filters: {user_filters}') - Helper_App.console_log(f"valid user_filters: {av.val_instance(user_filters, 'user_filters', _m, Parameters_User)}") - + # Helper_App.console_log(f"valid user_filters: {av.val_instance(user_filters, 'user_filters', _m, Parameters_User)}") + av.val_instance(user_filters, 'user_filters', _m, Parameters_User) # guid = Helper_DB_MySQL.create_guid() - Helper_App.console_log(f'user: {user}') + # Helper_App.console_log(f'user: {user}') if user is None: user = self.get_user_session() Helper_App.console_log(f'user: {user}') @@ -92,8 +92,6 @@ class DataStore_User(DataStore_Base): cursor = result.cursor result_set = cursor.fetchall() Helper_App.console_log(f'raw users: {result_set}') - Helper_App.console_log(f'type result set: {str(type(result_set))}') - Helper_App.console_log(f'len result set: {len(result_set)}') users = [] if len(result_set) > 0: for row in result_set: @@ -101,7 +99,7 @@ class DataStore_User(DataStore_Base): user = User.from_DB_user(row) users.append(user) Helper_App.console_log(f'user {str(type(user))}: {user}') - Helper_App.console_log(f'type users: {str(type(users))}\n type user 0: {str(type(None if len(users) == 0 else users[0]))}') + """ errors = [] cursor.nextset() diff --git a/forms/dog/dog_command_link.py b/forms/dog/dog_command_link.py index 406c3c7..b6a01d2 100644 --- a/forms/dog/dog_command_link.py +++ b/forms/dog/dog_command_link.py @@ -16,6 +16,7 @@ from dog_training.business_objects.base import Base from dog_training.business_objects.dog.command import Command from dog_training.business_objects.dog.dog import Dog from dog_training.business_objects.dog.obedience_level import Obedience_Level +from dog_training.helpers.helper_app import Helper_App # from dog_training.models.model_view_store import Model_View_Store # circular # from dog_training.models.model_view_base import Model_View_Base from dog_training.forms.base import Form_Base @@ -23,7 +24,7 @@ import dog_training.lib.argument_validation as av # external from flask import Flask, render_template, request, flash, redirect, url_for, current_app from flask_wtf import FlaskForm -from wtforms import SelectField, BooleanField, SubmitField +from wtforms import SelectField, BooleanField, StringField, SubmitField from wtforms.validators import DataRequired, Email, ValidationError import markupsafe from flask_wtf.recaptcha import RecaptchaField @@ -31,6 +32,9 @@ from abc import ABCMeta, abstractmethod import json class Filters_Dog_Command_Link(Form_Base): + search = StringField( + 'Search' + ) id_dog = SelectField( 'Dog' , choices = [Form_Base.get_select_option_all()] @@ -48,17 +52,22 @@ class Filters_Dog_Command_Link(Form_Base): @classmethod def from_json(cls, json): + _m = f'{cls.__qualname__}.from_json' + Helper_App.console_log(f'{_m}\njson: {json}') filters = cls() - filters.id_dog.choices = [(json[Dog.ATTR_ID_DOG], json[Dog.ATTR_ID_DOG])] + filters.search.data = json[Base.FLAG_SEARCH_TEXT] + # filters.id_dog.choices = [(json[Dog.ATTR_ID_DOG], json[Dog.ATTR_ID_DOG])] filters.id_dog.data = json[Dog.ATTR_ID_DOG] - filters.id_command.choices = [(json[Command.ATTR_ID_COMMAND], json[Command.ATTR_ID_COMMAND])] + # filters.id_command.choices = [(json[Command.ATTR_ID_COMMAND], json[Command.ATTR_ID_COMMAND])] filters.id_command.data = json[Command.ATTR_ID_COMMAND] - filters.active_only.data = av.input_bool(json[Base.FLAG_ACTIVE], Base.FLAG_ACTIVE, f'{cls.__name__}.from_json') + filters.active_only.data = av.input_bool(json[Base.FLAG_ACTIVE_ONLY], Base.FLAG_ACTIVE_ONLY, f'{cls.__name__}.from_json') + # Helper_App.console_log(f'Command: {command}') return filters def to_json(self): return { - Dog.FLAG_DOG: self.id_dog.data + Base.FLAG_SEARCH_TEXT: self.search.data + , Dog.FLAG_DOG: self.id_dog.data , Command.FLAG_COMMAND: self.id_command.data - , Base.FLAG_ACTIVE: self.active_only.data + , Base.FLAG_ACTIVE_ONLY: self.active_only.data } diff --git a/models/model_view_base.py b/models/model_view_base.py index a0fc5cb..ba91fb6 100644 --- a/models/model_view_base.py +++ b/models/model_view_base.py @@ -20,8 +20,11 @@ Base data model for views from dog_training.business_objects.base import Base from dog_training.business_objects.dog.user import User from dog_training.business_objects.dog.command import Command +from dog_training.business_objects.dog.dog import Dog +from dog_training.business_objects.dog.dog_command_link import Dog_Command_Link from dog_training.datastores.datastore_base import DataStore_Base from dog_training.datastores.datastore_dog import DataStore_Dog +from dog_training.datastores.datastore_user import DataStore_User from dog_training.helpers.helper_app import Helper_App import dog_training.lib.argument_validation as av # external @@ -33,10 +36,24 @@ from typing import ClassVar class Model_View_Base(BaseModel, ABC): + ATTR_ID_COMMAND: ClassVar[str] = Command.ATTR_ID_COMMAND + ATTR_ID_DOG: ClassVar[str] = Dog.ATTR_ID_DOG + ATTR_ID_DOG_COMMAND_LINK: ClassVar[str] = Dog_Command_Link.ATTR_ID_DOG_COMMAND_LINK ATTR_TEXT_COLLAPSED: ClassVar[str] = 'textCollapsed' ATTR_TEXT_EXPANDED: ClassVar[str] = 'textExpanded' ATTR_VALUE_CURRENT: ClassVar[str] = 'current-value' ATTR_VALUE_PREVIOUS: ClassVar[str] = 'previous-value' + COLOUR_ACCENT: ClassVar[str] = '#C77DFF' + COLOUR_ERROR: ClassVar[str] = 'red' + COLOUR_PAGE_BACKGROUND: ClassVar[str] = '#E0AAFF' + COLOUR_PAGE_BACKGROUND_1: ClassVar[str] = '#F5ECFE' + COLOUR_PAGE_BACKGROUND_2: ClassVar[str] = '#FAE0E2' + COLOUR_PRIMARY: ClassVar[str] = '#240046' + COLOUR_SECONDARY: ClassVar[str] = '#3C096C' + COLOUR_TEXT: ClassVar[str] = '#10002B' + COLOUR_TEXT_BACKGROUND: ClassVar[str] = 'white' + COLOUR_TEXT_LINK_UNVISITED: ClassVar[str] = '#0000EE' + COLOUR_TEXT_LINK_VISITED: ClassVar[str] = '#551A8B' COMPANY_ADDRESS_SHORT: ClassVar[str] = '53 Alfred Green Close, Rugby, United Kingdom, CV22 6DN' COMPANY_NUMBER: ClassVar[str] = '13587499' ENDPOINT_GET_ALTCHA_CHALLENGE: ClassVar[str] = 'routes_core_contact.create_altcha_challenge' @@ -66,6 +83,7 @@ class Model_View_Base(BaseModel, ABC): FLAG_CODE: ClassVar[str] = Base.FLAG_CODE FLAG_COLLAPSED: ClassVar[str] = 'collapsed' FLAG_COLLAPSIBLE: ClassVar[str] = 'collapsible' + FLAG_COMMAND: ClassVar[str] = Command.FLAG_COMMAND FLAG_COLUMN: ClassVar[str] = 'column' FLAG_COMMENT: ClassVar[str] = 'comment' FLAG_CONTAINER: ClassVar[str] = 'container' @@ -82,6 +100,8 @@ class Model_View_Base(BaseModel, ABC): FLAG_DIALOG: ClassVar[str] = 'dialog' FLAG_DIRTY: ClassVar[str] = 'dirty' FLAG_DISPLAY_ORDER: ClassVar[str] = Base.FLAG_DISPLAY_ORDER + FLAG_DOG: ClassVar[str] = Dog.FLAG_DOG + FLAG_DOG_COMMAND_LINK: ClassVar[str] = Dog_Command_Link.FLAG_DOG_COMMAND_LINK FLAG_EDIT: ClassVar[str] = 'edit' FLAG_EMAIL: ClassVar[str] = Base.FLAG_EMAIL FLAG_ERROR: ClassVar[str] = 'error' @@ -91,6 +111,7 @@ class Model_View_Base(BaseModel, ABC): FLAG_FORM: ClassVar[str] = 'form' FLAG_FORM_FILTERS: ClassVar[str] = 'form-filters' FLAG_HAMBURGER: ClassVar[str] = 'hamburger' + FLAG_ICON: ClassVar[str] = "icon" FLAG_IMAGE_LOGO: ClassVar[str] = 'image-logo' FLAG_INITIALISED: ClassVar[str] = 'initialised' FLAG_LEFT_HAND_STUB: ClassVar[str] = 'lhs' @@ -102,16 +123,19 @@ class Model_View_Base(BaseModel, ABC): FLAG_NAME_ATTR_OPTION_VALUE: ClassVar[str] = Base.FLAG_NAME_ATTR_OPTION_VALUE FLAG_NAME_PLURAL: ClassVar[str] = Base.FLAG_NAME_PLURAL # FLAG_NAME_SINGULAR: ClassVar[str] = Base.FLAG_NAME_SINGULAR + FLAG_SEARCH_TEXT: ClassVar[str] = Base.FLAG_SEARCH_TEXT FLAG_NAV_ADMIN_HOME: ClassVar[str] = 'navAdminHome' FLAG_NAV_CONTACT: ClassVar[str] = 'navContact' - FLAG_NAV_DOG_COMMAND: ClassVar[str] = 'navDogCommand' - FLAG_NAV_DOG_DOG: ClassVar[str] = 'navDogDog' - FLAG_NAV_DOG_DOG_COMMAND_LINK: ClassVar[str] = 'navDogDogCommandLink' + FLAG_NAV_DOG_COMMANDS: ClassVar[str] = 'navDogCommands' + FLAG_NAV_DOG_DOGS: ClassVar[str] = 'navDogDogs' + FLAG_NAV_DOG_DOG_COMMAND_LINKS: ClassVar[str] = 'navDogDogCommandLinks' + FLAG_NAV_DOG_HOME: ClassVar[str] = 'navDogHome' FLAG_NAV_HOME: ClassVar[str] = 'navHome' FLAG_NAV_USER_ACCOUNT: ClassVar[str] = 'navUserAccount' FLAG_NAV_USER_ADMIN: ClassVar[str] = 'navUserAdmin' FLAG_NAV_USER_LOGIN: ClassVar[str] = 'navUserLogin' FLAG_NAV_USER_LOGOUT: ClassVar[str] = 'navUserLogout' + FLAG_NOTES: ClassVar[str] = "notes" FLAG_OVERLAY: ClassVar[str] = 'overlay' FLAG_PAGE_BODY: ClassVar[str] = 'page-body' FLAG_RIGHT_HAND_SIDE: ClassVar[str] = 'rhs' @@ -128,12 +152,17 @@ class Model_View_Base(BaseModel, ABC): FLAG_USER: ClassVar[str] = User.FLAG_USER FLAG_WEBSITE: ClassVar[str] = Base.FLAG_WEBSITE HASH_GET_ALTCHA_CHALLENGE: ClassVar[str] = '/altcha/create-challenge' + HASH_GET_DOG_SCRIPTS_SHARED: ClassVar[str] = '/dog/scripts_shared' HASH_PAGE_ACCESSIBILITY_REPORT: ClassVar[str] = '/accessibility-report' HASH_PAGE_ACCESSIBILITY_STATEMENT: ClassVar[str] = '/accessibility-statement' HASH_PAGE_ADMIN_HOME: ClassVar[str] = '/admin' HASH_PAGE_CONTACT: ClassVar[str] = '/contact' HASH_PAGE_CONTACT_SUCCESS: ClassVar[str] = '/contact-success' HASH_PAGE_DATA_RETENTION_SCHEDULE: ClassVar[str] = '/retention-schedule' + HASH_PAGE_DOG_COMMANDS: ClassVar[str] = '/dog/commands' + HASH_PAGE_DOG_DOG_COMMAND_LINKS: ClassVar[str] = '/dog/dog_command_links' + HASH_PAGE_DOG_DOGS: ClassVar[str] = '/dog/dogs' + HASH_PAGE_DOG_HOME: ClassVar[str] = '/dog/home' HASH_PAGE_ERROR_NO_PERMISSION: ClassVar[str] = '/error' HASH_PAGE_HOME: ClassVar[str] = '/' HASH_PAGE_LICENSE: ClassVar[str] = '/license' @@ -165,7 +194,7 @@ class Model_View_Base(BaseModel, ABC): hash_page_current: str app: Flask = None session: None = None - is_page_store: bool = None + is_page_dog: bool = None is_user_logged_in: bool = None user: User = None access_levels: list = None @@ -182,7 +211,7 @@ class Model_View_Base(BaseModel, ABC): self.app = current_app with self.app.app_context(): self.session = session - self.is_page_store = False + self.is_page_dog = False Helper_App.console_log(f'session: {self.session}') datastore_base = DataStore_Base() diff --git a/models/model_view_dog_base.py b/models/model_view_dog_base.py index 4802bfc..5503f10 100644 --- a/models/model_view_dog_base.py +++ b/models/model_view_dog_base.py @@ -36,19 +36,19 @@ class Model_View_Dog_Base(Model_View_Base): # FLAG_UNIT_MEASUREMENT_INTERVAL_EXPIRATION_UNSEALED: ClassVar[str] = Product_Permutation.FLAG_UNIT_MEASUREMENT_INTERVAL_EXPIRATION_UNSEALED # HASH_GET_STORE_CUSTOMER_SALES_ORDER: ClassVar[str] = '/store/customer_sales_order_get' # HASH_GET_STORE_MANUFACTURING_PURCHASE_ORDER: ClassVar[str] = '/store/manufacturing_purchase_order_get' - HASH_DOG_SCRIPTS_SHARED: ClassVar[str] = '/dog/scripts_shared' - HASH_PAGE_DOG_DOG_COMMAND_LINKS: ClassVar[str] = '/dog/dog_command_links' @property def title(self): + if self.hash_page_current == Model_View_Base.HASH_PAGE_DOG_HOME: + return 'Dog Home' raise NotImplementedError('title must be implemented in child class') def __init__(self, hash_page_current, **kwargs): _m = 'Model_View_Dog_Base.__init__' Helper_App.console_log(f'{_m}\nstarting') super().__init__(hash_page_current=hash_page_current, **kwargs) - self.is_page_store = True + self.is_page_dog = True """ def get_many_dog(self, dog_filters): diff --git a/models/model_view_dog_dog_command_link.py b/models/model_view_dog_dog_command_link.py index 07d7aa4..5313b9f 100644 --- a/models/model_view_dog_dog_command_link.py +++ b/models/model_view_dog_dog_command_link.py @@ -27,6 +27,7 @@ from pydantic import BaseModel from typing import ClassVar class Model_View_Dog_Dog_Command_Link(Model_View_Dog_Base): + FLAG_HAND_SIGNAL_DESCRIPTION: ClassVar[str] = Dog_Command_Link.FLAG_HAND_SIGNAL_DESCRIPTION filter_dogs: list = None filter_commands: list = None dog_command_links: list = None @@ -49,12 +50,15 @@ class Model_View_Dog_Dog_Command_Link(Model_View_Dog_Base): parameters_filter_command = Parameters_Command.get_default() self.filter_commands, errors = datastore.get_many_command(parameters_filter_command) - parameters_filter_dog_command_link = Parameters_Dog_Command_Link.get_default() + parameters_filter_dog_command_link = Parameters_Dog_Command_Link.from_form_filters_dog_command_link(self.form_filters) self.dog_command_links, errors = datastore.get_many_dog_command_link(parameters_filter_dog_command_link) - Helper_App.console_log(f'dogs: {self.filter_dogs}') - Helper_App.console_log(f'commands: {self.filter_commands}') - Helper_App.console_log(f'links: {self.dog_command_links}') + # Helper_App.console_log(f'dogs: {self.filter_dogs}') + # Helper_App.console_log(f'commands: {self.filter_commands}') + # Helper_App.console_log(f'links: {self.dog_command_links}') + + self.form_filters.id_dog.choices += [(str(dog.id_dog), dog.name) for dog in self.filter_dogs] + self.form_filters.id_command.choices += [(str(command.id_command), command.name) for command in self.filter_commands] """ @classmethod diff --git a/package.json b/package.json index 3497ad3..584a8a2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "app", "version": "1.0.0", - "description": "Precision and Research Technology Systems Limited\r Website with online store", + "description": "Dog training management web app.", "main": "webpack.config.js", "directories": { "lib": "lib" @@ -13,15 +13,15 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/Teddy-1024/parts_website.git" + "url": "git+https://github.com/Teddy-1024/dog_training.git" }, "keywords": [], "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/Teddy-1024/parts_website/issues" + "url": "https://github.com/Teddy-1024/dog_training/issues" }, - "homepage": "https://github.com/Teddy-1024/parts_website#readme", + "homepage": "https://github.com/Teddy-1024/dog_training#readme", "devDependencies": { "@babel/core": "^7.25.2", "@babel/plugin-syntax-dynamic-import": "^7.8.3", diff --git a/static/MySQL/00000_combined.sql b/static/MySQL/00000_combined.sql index fd6bd65..02dc52f 100644 --- a/static/MySQL/00000_combined.sql +++ b/static/MySQL/00000_combined.sql @@ -1,24 +1,34 @@ USE demo; -DROP PROCEDURE IF EXISTS demo.p_DOG_get_many_dog; +DROP PROCEDURE IF EXISTS demo.p_dog_get_many_dog_command; +DROP PROCEDURE IF EXISTS demo.p_dog_get_many_dog_command_link; DELIMITER // -CREATE PROCEDURE demo.p_DOG_get_many_dog ( +CREATE PROCEDURE demo.p_dog_get_many_dog_command_link ( 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 + , IN a_get_all_command_category BIT + , IN a_get_inactive_command_category BIT + , IN a_ids_command_category TEXT + , IN a_names_command_category TEXT + , IN a_get_all_command BIT + , IN a_get_inactive_command BIT + , IN a_ids_command TEXT + , IN a_names_command TEXT , IN a_debug BIT ) BEGIN DECLARE v_code_type_error_bad_data VARCHAR(100); DECLARE v_code_type_error_no_permission VARCHAR(100); + DECLARE v_code_type_error_warning VARCHAR(100); DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; - DECLARE v_has_filter_dog_id BIT; - DECLARE v_has_filter_dog_name BIT; + DECLARE v_id_type_error_warning INT; + DECLARE v_has_filter_dog BIT; DECLARE v_guid BINARY(36); DECLARE v_id_permission_dog_view INT; DECLARE v_id_minimum INT; @@ -76,15 +86,22 @@ BEGIN SET v_guid := UUID(); SET v_code_type_error_bad_data := 'BAD_DATA'; SET v_code_type_error_no_permission := 'NO_PERMISSION'; + SET v_code_type_error_warning := 'WARNING'; 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_type_error_warning := (SELECT ERROR_TYPE.id_type FROM demo.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_warning 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 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, '')); + -- 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_get_all_command_category := IFNULL(a_get_all_command_category, 0); + -- SET a_get_inactive_command_category := IFNULL(a_get_inactive_command_category, 0); + -- SET a_ids_command_category := TRIM(IFNULL(a_ids_command_category, '')); + -- SET a_get_all_command := IFNULL(a_get_all_command, 0); + -- SET a_get_inactive_command := IFNULL(a_get_inactive_command, 0); + -- SET a_ids_command := TRIM(IFNULL(a_ids_command, '')); SET a_debug := IFNULL(a_debug, 0); IF a_debug = 1 THEN @@ -94,26 +111,57 @@ BEGIN , a_get_inactive_dog , a_ids_dog , a_names_dog + , a_get_all_command_category + , a_get_inactive_command_category + , a_ids_command_category + , a_names_command_category + , a_get_all_command + , a_get_inactive_command + , a_ids_command + , a_names_command , a_debug ; SELECT v_id_type_error_bad_data , v_id_type_error_no_permission + , v_id_type_error_warning , v_guid , v_id_permission_dog_view , v_time_start ; END IF; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id; + DROP TEMPORARY TABLE IF EXISTS tmp_Split; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; + DROP TEMPORARY TABLE IF EXISTS tmp_Command; + DROP TEMPORARY TABLE IF EXISTS tmp_Command_Category; DROP TEMPORARY TABLE IF EXISTS tmp_Dog; CREATE TEMPORARY TABLE tmp_Dog ( id_dog INT NOT NULL , name VARCHAR(250) + , appearance VARCHAR(1000) + , mass_kg DECIMAL(7, 3) + , notes TEXT + , active BIT + ); + + CREATE TEMPORARY TABLE tmp_Command_Category ( + id_command_category INT NOT NULL + , code VARCHAR(100) + , name VARCHAR(250) + , active BIT + ); + + CREATE TEMPORARY TABLE tmp_Command ( + id_command INT NOT NULL + , id_command_category INT NOT NULL + , name VARCHAR(250) + , hand_signal_default_description TEXT + , can_have_button BIT + , notes TEXT + , active BIT ); CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error ( @@ -123,157 +171,6 @@ BEGIN , msg VARCHAR(4000) NOT NULL ); - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Id ( - substring VARCHAR(4000) NOT NULL - , as_int INT NULL - ); - DELETE FROM tmp_Split_Id; - - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Name ( - substring VARCHAR(4000) NOT NULL - , as_int INT NULL - ); - DELETE FROM tmp_Split_Name; - - CALL demo.p_core_validate_guid ( v_guid ); - - SET v_has_filter_dog_id = CASE WHEN a_ids_dog = '' THEN 0 ELSE 1 END; - SET v_has_filter_dog_name = CASE WHEN a_names_dog = '' THEN 0 ELSE 1 END; - - -- Dogs - IF v_has_filter_dog_id = 1 THEN - CALL demo.p_split(v_guid, a_ids_dog, ',', a_debug); - - INSERT INTO tmp_Split_Id ( - substring - , as_int - ) - SELECT - SPLIT_T.substring - , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int - FROM demo.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = v_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; - - CALL demo.p_clear_split_temp( v_guid ); - END IF; - - IF v_has_filter_dog_name = 1 THEN - CALL demo.p_split(v_guid, a_names_dog, ',', a_debug); - - INSERT INTO tmp_Split_Name ( - substring - , as_int - ) - SELECT - SPLIT_T.substring - , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int - FROM demo.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = v_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; - - CALL demo.p_clear_split_temp( v_guid ); - END IF; - - 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 EXISTS ( - SELECT * - FROM tmp_Split_Id 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 ( - 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 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 ( - SELECT * - FROM tmp_Split t_SPLIT - LEFT JOIN demo.DOG_Dog DOG ON t_SPLIT.as_int = DOG.id_dog - WHERE - ISNULL(t_SPLIT.as_int) - OR ISNULL(DOG.id_dog) - OR ( - DOG.active = 0 - AND a_get_inactive_dog = 0 - ) - ) THEN - INSERT INTO tmp_Msg_Error ( - 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.substring SEPARATOR ', '), 'NULL')) - FROM tmp_Split t_SPLIT - LEFT JOIN demo.DOG_Dog DOG ON t_SPLIT.as_int = DOG.id_dog - WHERE - ISNULL(t_SPLIT.as_int) - OR ISNULL(DOG.id_dog) - OR ( - DOG.active = 0 - AND a_get_inactive_dog = 0 - ) - ; - */ - ELSE - INSERT INTO tmp_Dog ( - id_dog - , name - ) - SELECT - DOG.id_dog - , DOG.name - FROM demo.DOG_Dog DOG - LEFT JOIN tmp_Split_Id t_SPLIT_ID ON DOG.id_dog = t_SPLIT_ID.as_int - LEFT JOIN tmp_Split_Name t_SPLIT_NAME ON DOG.name = t_SPLIT_NAME.substring - WHERE - ( - a_get_all_dog = 1 - OR ( - v_has_filter_dog_id = 1 - OR v_has_filter_dog_name = 1 - ) - ) - AND ( - a_get_inactive_dog = 1 - OR DOG.active = 1 - ) - ; - END IF; - END IF; - - DELETE FROM tmp_Split_Id; - DELETE FROM tmp_Split_Name; - -- Permissions IF a_debug = 1 THEN @@ -286,11 +183,11 @@ BEGIN ; END IF; - CALL demo.p_DOG_calc_user( - v_guid - , a_id_user + CALL demo.p_dog_calc_user( + v_guid -- a_guid + , a_id_user -- a_ids_user , FALSE -- a_get_inactive_user - , v_id_permission_dog_view + , v_id_permission_dog_view -- a_ids_permission , 0 -- a_debug ); @@ -320,35 +217,175 @@ BEGIN VALUES ( v_id_type_error_no_permission , v_code_type_error_no_permission - , 'You do not have permission to view Commands.' + , 'You do not have permission to view Dogs and Commands.' ) ; END IF; - CALL demo.p_DOG_clear_calc_user( + CALL demo.p_dog_clear_calc_user( v_guid , 0 -- a_debug ); - 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 + -- Call Dog 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_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 + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL demo.p_dog_calc_dog( + v_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 + , 0 -- a_show_errors + , 0 -- a_debug + ); + + INSERT INTO tmp_Dog ( + id_dog + , name + , appearance + , mass_kg + , notes + , active + ) + SELECT + DOG_T.id_dog + , DOG_T.name + , DOG_T.appearance + , DOG_T.mass_kg + , DOG_T.notes + , DOG_T.active + FROM demo.DOG_Dog_Temp DOG_T + WHERE DOG_T.GUID = v_guid + ; + IF a_debug = 1 THEN SELECT * FROM tmp_Dog; END IF; + END IF; + + -- Call Command 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_command_category + , a_get_inactive_command_category + , a_ids_command_category + , a_names_command_category + , a_get_all_command -- a_get_all_command + , a_get_inactive_command -- a_get_inactive_command + , a_ids_command -- a_ids_command + , a_names_command -- a_names_command + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL demo.p_dog_calc_command ( + v_guid -- a_guid + , a_id_user -- a_id_user + , a_get_all_command_category + , a_get_inactive_command_category + , a_ids_command_category + , a_names_command_category + , a_get_all_command -- a_get_all_command + , a_get_inactive_command -- a_get_inactive_command + , a_ids_command -- a_ids_command + , a_names_command -- a_names_command + , 0 -- a_show_errors + , 0 -- a_debug + ); + + INSERT INTO tmp_Command_Category ( + id_command_category + , code + , name + , active + ) + SELECT + COMMAND_CATEGORY_T.id_command_category + , COMMAND_CATEGORY_T.code + , COMMAND_CATEGORY_T.name + , COMMAND_CATEGORY_T.active + FROM demo.DOG_Command_Category_Temp COMMAND_CATEGORY_T + WHERE COMMAND_CATEGORY_T.GUID = v_guid + ; + + INSERT INTO tmp_Command ( + id_command + , id_command_category + , name + , hand_signal_default_description + , can_have_button + , notes + , active + ) + SELECT + COMMAND_T.id_command + , COMMAND_T.id_command_category + , COMMAND_T.name + , COMMAND_T.hand_signal_default_description + , COMMAND_T.can_have_button + , COMMAND_T.notes + , COMMAND_T.active + FROM demo.DOG_Command_Temp COMMAND_T + WHERE COMMAND_T.GUID = v_guid + ; + + IF a_debug = 1 THEN + SELECT * FROM tmp_Command_Category; + SELECT * FROM tmp_Command; + END IF; + END IF; + + + -- 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; + SELECT * FROM tmp_Command; + SELECT * FROM tmp_Command_Category; + END IF; DELETE FROM tmp_Dog; + DELETE FROM tmp_Command; + DELETE FROM tmp_Command_Category; END IF; -- Outputs -- Commands SELECT - t_DOG.id_dog - , t_DOG.name - , DOG.appearance - , DOG.mass_kg - , DOG.notes - , DOG.active - FROM demo.DOG_Dog DOG - INNER JOIN tmp_Dog t_DOG ON DOG.id_dog = t_DOG.id_dog + DOG_COMMAND_LINK.id_link AS id_dog_command_link + , t_DOG.id_dog + , t_DOG.name AS name_dog + , t_COMMAND.id_command_category + , t_COMMAND_CATEGORY.name AS name_command_category + , t_COMMAND.id_command + , t_COMMAND.name AS name_command + -- , t_COMMAND.has_button AS command_has_button + , COALESCE(DOG_COMMAND_LINK.hand_signal_description, t_COMMAND.hand_signal_default_description) AS hand_signal_description_command + , t_COMMAND.can_have_button AS can_have_button_command + , DOG_COMMAND_LINK.notes + , DOG_COMMAND_LINK.active + FROM demo.DOG_Dog_Command_Link DOG_COMMAND_LINK + INNER JOIN tmp_Dog t_DOG ON DOG_COMMAND_LINK.id_dog = t_DOG.id_dog + INNER JOIN tmp_Command t_COMMAND ON DOG_COMMAND_LINK.id_command = t_COMMAND.id_command + INNER JOIN tmp_Command_Category t_COMMAND_CATEGORY ON t_COMMAND.id_command_category = t_COMMAND_CATEGORY.id_command_category ; -- Errors @@ -368,11 +405,14 @@ BEGIN IF a_debug = 1 AND v_can_view = 1 THEN SELECT * FROM tmp_Dog; + SELECT * FROM tmp_Command; + SELECT * FROM tmp_Command_Category; END IF; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id; + DROP TEMPORARY TABLE IF EXISTS tmp_Split; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; + DROP TEMPORARY TABLE IF EXISTS tmp_Command; + DROP TEMPORARY TABLE IF EXISTS tmp_Command_Category; DROP TEMPORARY TABLE IF EXISTS tmp_Dog; IF a_debug = 1 THEN @@ -382,378 +422,37 @@ END // DELIMITER ; +/* -USE demo; - -DROP PROCEDURE IF EXISTS demo.p_DOG_get_many_command; - -DELIMITER // -CREATE PROCEDURE demo.p_DOG_get_many_command ( - IN a_id_user INT - , IN a_get_all_command BIT - , IN a_get_inactive_command BIT - , IN a_ids_command TEXT - , IN a_names_command TEXT - , IN a_debug BIT -) -BEGIN - DECLARE v_code_type_error_bad_data VARCHAR(100); - DECLARE v_code_type_error_no_permission VARCHAR(100); - DECLARE v_id_type_error_bad_data INT; - DECLARE v_id_type_error_no_permission INT; - DECLARE v_has_filter_command_id BIT; - DECLARE v_has_filter_command_name BIT; - DECLARE v_guid BINARY(36); - DECLARE v_id_permission_command_view INT; - DECLARE v_id_minimum INT; - DECLARE v_time_start TIMESTAMP(6); - DECLARE v_can_view BIT; - - DECLARE exit handler for SQLEXCEPTION - BEGIN - GET DIAGNOSTICS CONDITION 1 - @sqlstate = RETURNED_SQLSTATE - , @errno = MYSQL_ERRNO - , @text = MESSAGE_TEXT - ; - - ROLLBACK; - - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error ( - id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT - , id_type INT NULL - , code VARCHAR(100) NOT NULL - , msg VARCHAR(4000) NOT NULL - ); - - INSERT INTO tmp_Msg_Error ( - id_type - , code - , msg - ) - SELECT - MET.id_type - , @errno - , @text - FROM demo.CORE_Msg_Error_Type MET - 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 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; - 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_command_view := (SELECT PERMISSION.id_permission FROM demo.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); - - SET a_id_user := IFNULL(a_id_user, 0); - SET a_get_all_command := IFNULL(a_get_all_command, 0); - SET a_get_inactive_command := IFNULL(a_get_inactive_command, 0); - SET a_ids_command := TRIM(IFNULL(a_ids_command, '')); - SET a_names_command := TRIM(IFNULL(a_names_command, '')); - SET a_debug := IFNULL(a_debug, 0); - - IF a_debug = 1 THEN - SELECT - a_id_user - , a_get_all_command - , a_get_inactive_command - , a_ids_command - , a_names_command - , a_debug - ; - - SELECT - v_id_type_error_bad_data - , v_id_type_error_no_permission - , v_guid - , v_id_permission_command_view - , v_time_start - ; - END IF; - - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id; - DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; - DROP TEMPORARY TABLE IF EXISTS tmp_Command; - - CREATE TEMPORARY TABLE tmp_Command ( - id_command INT NOT NULL - , name VARCHAR(250) - ); - - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error ( - id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT - , id_type INT NULL - , code VARCHAR(100) NOT NULL - , msg VARCHAR(4000) NOT NULL - ); - - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Id ( - substring VARCHAR(4000) NOT NULL - , as_int INT NULL - ); - DELETE FROM tmp_Split_Id; - - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Name ( - substring VARCHAR(4000) NOT NULL - , as_int INT NULL - ); - DELETE FROM tmp_Split_Name; - - CALL demo.p_core_validate_guid ( v_guid ); - - SET v_has_filter_command_id = CASE WHEN a_ids_command = '' THEN 0 ELSE 1 END; - SET v_has_filter_command_name = CASE WHEN a_names_command = '' THEN 0 ELSE 1 END; - - -- Commands - IF v_has_filter_command_id = 1 THEN - CALL demo.p_split(v_guid, a_ids_command, ',', a_debug); - - INSERT INTO tmp_Split_Id ( - substring - , as_int - ) - SELECT - SPLIT_T.substring - , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int - FROM demo.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = v_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; - - CALL demo.p_clear_split_temp( v_guid ); - END IF; - - IF v_has_filter_command_name = 1 THEN - CALL demo.p_split(v_guid, a_names_command, ',', a_debug); - - INSERT INTO tmp_Split_Name ( - substring - , as_int - ) - SELECT - SPLIT_T.substring - , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int - FROM demo.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = v_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; - - CALL demo.p_clear_split_temp( v_guid ); - END IF; - - 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 EXISTS ( - SELECT * - FROM tmp_Split_Id t_SPLIT_ID - LEFT JOIN demo.DOG_Command COMMAND ON t_SPLIT_ID.as_int = COMMAND.id_command - WHERE - ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(COMMAND.id_command) - OR ( - COMMAND.active = 0 - AND a_get_inactive_command = 0 - ) - ) THEN - INSERT INTO tmp_Msg_Error ( - id_type - , code - , msg - ) - SELECT - v_id_type_error_bad_data - , v_code_type_error_bad_data - , CONCAT('Invalid or inactive Command IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT_ID.substring SEPARATOR ', '), 'NULL')) - FROM tmp_Split_Id t_SPLIT_ID - LEFT JOIN demo.DOG_Command COMMAND ON t_SPLIT_ID.as_int = COMMAND.id_command - WHERE - ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(COMMAND.id_command) - OR ( - COMMAND.active = 0 - AND a_get_inactive_command = 0 - ) - ; - /* Don't error on codes or names not found - ELSEIF EXISTS ( - SELECT * - */ - ELSE - INSERT INTO tmp_Command ( - id_command - , name - ) - SELECT - COMMAND.id_command - , COMMAND.name - FROM demo.DOG_Command COMMAND - LEFT JOIN tmp_Split_Id t_SPLIT_ID ON COMMAND.id_command = t_SPLIT_ID.as_int - LEFT JOIN tmp_Split_Name t_SPLIT_NAME ON COMMAND.name = t_SPLIT_NAME.substring - WHERE - ( - a_get_all_command = 1 - OR ( - v_has_filter_command_id = 1 - OR v_has_filter_command_name = 1 - ) - ) - AND ( - a_get_inactive_command = 1 - OR COMMAND.active = 1 - ) - ; - END IF; - END IF; - - DELETE FROM tmp_Split_Id; - DELETE FROM tmp_Split_Name; - - - -- Permissions - IF a_debug = 1 THEN - SELECT - v_guid - , a_id_user - , FALSE -- a_get_inactive_user - , v_id_permission_command_view - , 0 -- a_debug - ; - END IF; - - CALL demo.p_DOG_calc_user( - v_guid - , a_id_user - , FALSE -- a_get_inactive_user - , v_id_permission_command_view - , 0 -- a_debug - ); - - SELECT - IFNULL(CALC_USER_T.has_access, 0) - INTO - v_can_view - FROM demo.DOG_Calc_User_Temp CALC_USER_T - WHERE CALC_USER_T.GUID = v_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 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 Commands.' - ) - ; - END IF; - - CALL demo.p_DOG_clear_calc_user( - v_guid - , 0 -- a_debug - ); - - 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_Command; - END IF; - - DELETE FROM tmp_Command; - END IF; - - -- Outputs - -- Commands - SELECT - t_COMMAND.id_command - , COMMAND.id_command_category - , t_COMMAND.name - , COMMAND.hand_signal_default_description - , COMMAND.can_have_button - , COMMAND.notes - , COMMAND.active - FROM demo.DOG_Command COMMAND - INNER JOIN tmp_Command t_COMMAND ON COMMAND.id_command = t_COMMAND.id_command - ; - - -- 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 - ; - - IF a_debug = 1 AND v_can_view = 1 THEN - SELECT * FROM tmp_Command; - END IF; - - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id; - DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; - DROP TEMPORARY TABLE IF EXISTS tmp_Command; - - IF a_debug = 1 THEN - CALL demo.p_core_debug_timing_reporting ( v_time_start ); - END IF; -END // -DELIMITER ; - - -CALL demo.p_DOG_get_many_dog ( +CALL demo.p_dog_get_many_dog_command_link ( 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user , 1 -- a_get_all_dog , 0 -- a_get_inactive_dog , '' -- a_ids_dog - , '' -- a_names_dog - , 1 -- a_debug -); - - - -CALL demo.p_DOG_get_many_command ( - 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user + , 1 -- a_get_all_command_category + , 0 -- a_get_inactive_command_category + , '' -- a_ids_command_category , 1 -- a_get_all_command , 0 -- a_get_inactive_command , '' -- a_ids_command - , '' -- a_names_command , 1 -- a_debug ); + +CALL demo.p_dog_get_many_dog_command_link ( + 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user + , 1 -- a_get_all_dog + , 0 -- a_get_inactive_dog + , '' -- a_ids_dog + , '' -- a_names_dog + , 1 -- a_get_all_command_category + , 0 -- a_get_inactive_command_category + , '' -- a_ids_command_category + , '' -- a_names_command_category + , 0 -- a_get_all_command + , 0 -- a_get_inactive_command + , '2' -- a_ids_command + , '2' -- a_names_command + , 1 -- a_debug +); + +*/ \ No newline at end of file diff --git a/static/MySQL/00001_destroy.sql b/static/MySQL/00001_destroy.sql index c48eea9..bb1243a 100644 --- a/static/MySQL/00001_destroy.sql +++ b/static/MySQL/00001_destroy.sql @@ -7,10 +7,10 @@ FLUSH PRIVILEGES; USE parts; -- Permanent Temp Tables -DROP TABLE IF EXISTS parts.tmp_DOG_Calc_User; +DROP TABLE IF EXISTS parts.tmp_dog_Calc_User; -- DROP TABLE IF EXISTS parts.tmp_core_Msg_Error; -DROP TABLE IF EXISTS parts.tmp_DOG_User; -DROP TABLE IF EXISTS parts.tmp_DOG_User_Role_Link; +DROP TABLE IF EXISTS parts.tmp_dog_User; +DROP TABLE IF EXISTS parts.tmp_dog_User_Role_Link; -- Permanent Tables @@ -181,16 +181,18 @@ DROP TABLE IF EXISTS parts.CORE_File_Type; DROP TABLE IF EXISTS parts.CORE_Msg_Error_Type; -- Stored Procedures -DROP PROCEDURE IF EXISTS parts.p_DOG_test_get_many_dog_command; -DROP PROCEDURE IF EXISTS parts.p_DOG_test_get_many_command; -DROP PROCEDURE IF EXISTS parts.p_DOG_get_many_command; -DROP PROCEDURE IF EXISTS parts.p_DOG_get_many_dog_command; -DROP PROCEDURE IF EXISTS parts.p_DOG_get_many_dog_command_link; -DROP PROCEDURE IF EXISTS parts.p_DOG_test_save_command; -DROP PROCEDURE IF EXISTS parts.p_DOG_save_command; +DROP PROCEDURE IF EXISTS parts.p_dog_test_get_many_dog_command; +DROP PROCEDURE IF EXISTS parts.p_dog_test_get_many_command; +DROP PROCEDURE IF EXISTS parts.p_dog_get_many_command; +DROP PROCEDURE IF EXISTS parts.p_dog_get_many_dog_command; +DROP PROCEDURE IF EXISTS parts.p_dog_get_many_dog_command_link; +DROP PROCEDURE IF EXISTS parts.p_dog_test_save_command; +DROP PROCEDURE IF EXISTS parts.p_dog_save_command; +DROP PROCEDURE IF EXISTS parts.p_command_clear_calc_command; -DROP PROCEDURE IF EXISTS parts.p_DOG_clear_calc_user; -DROP PROCEDURE IF EXISTS parts.p_DOG_calc_user; +DROP PROCEDURE IF EXISTS parts.p_dog_clear_calc_user; +DROP PROCEDURE IF EXISTS parts.p_dog_calc_user; +DROP PROCEDURE IF EXISTS parts.p_clear_split_temp; /* DROP PROCEDURE IF EXISTS parts.p_core_clear_split_key_value_pair_csv; @@ -198,9 +200,9 @@ DROP PROCEDURE IF EXISTS parts.p_core_split_key_value_pair_csv; DROP PROCEDURE IF EXISTS parts.p_core_clear_split; DROP PROCEDURE IF EXISTS parts.p_core_split; DROP PROCEDURE IF EXISTS parts.p_clear_split_key_value_pair_csv; -DROP PROCEDURE IF EXISTS parts.p_split_key_value_pair_csv; +DROP PROCEDURE IF EXISTS parts.p_core_split_key_value_pair_csv; DROP PROCEDURE IF EXISTS parts.p_clear_split; -DROP PROCEDURE IF EXISTS parts.p_split; +DROP PROCEDURE IF EXISTS parts.p_core_split; DROP PROCEDURE IF EXISTS parts.p_core_debug_timing_reporting; DROP PROCEDURE IF EXISTS parts.p_debug_timing_reporting; diff --git a/static/MySQL/60011_p_core_clear_split.sql b/static/MySQL/60011_p_core_clear_split.sql index 45434a0..4bbad8f 100644 --- a/static/MySQL/60011_p_core_clear_split.sql +++ b/static/MySQL/60011_p_core_clear_split.sql @@ -13,10 +13,11 @@ BEGIN START TRANSACTION; - -- DROP TABLE IF EXISTS - DELETE FROM parts.CORE_Split_Temp - WHERE GUID = a_guid - ; + -- DROP TABLE IF EXISTS + DELETE SPLIT_T + FROM parts.CORE_Split_Temp SPLIT_T + WHERE SPLIT_T.GUID = a_guid + ; COMMIT; END // diff --git a/static/MySQL/60013_p_core_clear_split_key_value_pair_csv.sql b/static/MySQL/60013_p_core_clear_split_key_value_pair_csv.sql index 8a0804c..bdd3c61 100644 --- a/static/MySQL/60013_p_core_clear_split_key_value_pair_csv.sql +++ b/static/MySQL/60013_p_core_clear_split_key_value_pair_csv.sql @@ -13,11 +13,12 @@ BEGIN START TRANSACTION; - -- DROP TABLE IF EXISTS - DELETE FROM parts.CORE_Split_Key_Value_Pair_Csv_Temp - WHERE GUID = a_guid - ; - + -- DROP TABLE IF EXISTS + DELETE SPLIT_PAIR_T + FROM parts.CORE_Split_Key_Value_Pair_Csv_Temp SPLIT_PAIR_T + WHERE SPLIT_PAIR_T.GUID = a_guid + ; + COMMIT; END // DELIMITER ; diff --git a/static/MySQL/70516_p_dog_get_many_user.sql b/static/MySQL/70516_p_dog_get_many_user.sql index 0d34936..1c8a743 100644 --- a/static/MySQL/70516_p_dog_get_many_user.sql +++ b/static/MySQL/70516_p_dog_get_many_user.sql @@ -18,7 +18,7 @@ CREATE PROCEDURE p_dog_get_many_user ( BEGIN DECLARE v_id_access_level_admin INT; DECLARE v_id_access_level_view INT; - DECLARE v_id_permission_store_admin INT; + DECLARE v_id_permission_dog_admin INT; DECLARE v_id_permission_user INT; DECLARE v_id_permission_user_admin INT; DECLARE v_ids_permission_required VARCHAR(4000); @@ -34,14 +34,14 @@ BEGIN SET v_time_start := CURRENT_TIMESTAMP(6); SET v_guid := UUID(); - SET v_id_access_level_admin := (SELECT id_access_level FROM demo.Shop_Access_Level WHERE code = 'ADMIN' LIMIT 1); - SET v_id_access_level_view := (SELECT id_access_level FROM demo.Shop_Access_Level WHERE code = 'VIEW' LIMIT 1); - SET v_id_permission_store_admin := (SELECT id_permission FROM demo.Shop_Permission WHERE code = 'STORE_ADMIN' LIMIT 1); - SET v_id_permission_user := (SELECT id_permission FROM demo.Shop_Permission WHERE code = 'STORE_USER' LIMIT 1); - SET v_id_permission_user_admin := (SELECT id_permission FROM demo.Shop_Permission WHERE code = 'STORE_USER_ADMIN' LIMIT 1); - SET v_code_error_bad_data := (SELECT code FROM demo.Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1); - SET v_id_type_error_bad_data := (SELECT id_type FROM demo.Shop_Msg_Error_Type WHERE code = v_code_error_bad_data LIMIT 1); - SET v_ids_permission_required := CONCAT(v_id_permission_user, ',', v_id_permission_user_admin, ',', v_id_permission_store_admin); + SET v_id_access_level_admin := (SELECT id_access_level FROM parts.Shop_Access_Level WHERE code = 'ADMIN' LIMIT 1); + SET v_id_access_level_view := (SELECT id_access_level FROM parts.Shop_Access_Level WHERE code = 'VIEW' LIMIT 1); + SET v_id_permission_dog_admin := (SELECT id_permission FROM parts.Shop_Permission WHERE code = 'DOG_ADMIN' LIMIT 1); + SET v_id_permission_user := (SELECT id_permission FROM parts.Shop_Permission WHERE code = 'USER_VIEW' LIMIT 1); + SET v_id_permission_user_admin := (SELECT id_permission FROM parts.Shop_Permission WHERE code = 'USER_ADMIN' LIMIT 1); + SET v_code_error_bad_data := (SELECT code FROM parts.Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1); + SET v_id_type_error_bad_data := (SELECT id_type FROM parts.Shop_Msg_Error_Type WHERE code = v_code_error_bad_data LIMIT 1); + SET v_ids_permission_required := CONCAT(v_id_permission_user, ',', v_id_permission_user_admin, ',', v_id_permission_dog_admin); SET v_is_new := FALSE; SET a_get_all_user := IFNULL(a_get_all_user, 1); @@ -70,7 +70,7 @@ BEGIN CREATE TEMPORARY TABLE tmp_User ( id_user INT NULL , rank_user INT NULL - , can_admin_store BIT NULL + , can_admin_dog BIT NULL , can_admin_user BIT NULL ); @@ -88,12 +88,12 @@ BEGIN ); IF ISNULL(a_id_user) AND NOT ISNULL(a_id_user_auth0) THEN - SET a_id_user := (SELECT U.id_user FROM demo.Shop_User U WHERE U.id_user_auth0 = a_id_user_auth0 LIMIT 1); -- LIKE CONCAT('%', a_id_user_auth0, '%') LIMIT 1); + SET a_id_user := (SELECT U.id_user FROM parts.Shop_User U WHERE U.id_user_auth0 = a_id_user_auth0 LIMIT 1); -- LIKE CONCAT('%', a_id_user_auth0, '%') LIMIT 1); END IF; IF ISNULL(a_id_user) THEN IF NOT ISNULL(a_id_user_auth0) THEN - INSERT INTO demo.Shop_User ( + INSERT INTO parts.Shop_User ( id_user_auth0 , is_super_user , active @@ -104,7 +104,7 @@ BEGIN , 1 -- active ) ; - SET a_id_user := (SELECT U.id_user FROM demo.Shop_User U WHERE U.id_user_auth0 = a_id_user_auth0 LIMIT 1); + SET a_id_user := (SELECT U.id_user FROM parts.Shop_User U WHERE U.id_user_auth0 = a_id_user_auth0 LIMIT 1); SET v_is_new := TRUE; ELSE INSERT INTO tmp_Msg_Error ( @@ -133,7 +133,7 @@ BEGIN -- User IDs IF (NOT EXISTS (SELECT * FROM tmp_Msg_Error LIMIT 1) AND v_has_filter_user = 1) THEN - CALL demo.p_split(v_guid, a_ids_user, ',', FALSE); + CALL parts.p_core_split(v_guid, a_ids_user, ',', FALSE); DELETE FROM tmp_Split; @@ -144,21 +144,21 @@ BEGIN SELECT substring , CONVERT(substring, DECIMAL(10,0)) AS as_int - FROM demo.Split_Temp + FROM parts.Split_Temp WHERE 1=1 AND GUID = v_guid AND NOT ISNULL(substring) AND substring != '' ; - CALL demo.p_clear_split_temp( v_guid ); + CALL parts.p_core_clear_split( v_guid ); END IF; IF (NOT EXISTS (SELECT * FROM tmp_Msg_Error LIMIT 1) AND v_has_filter_user = 1) THEN IF EXISTS ( SELECT * FROM tmp_Split t_S - LEFT JOIN demo.Shop_User U ON t_S.as_int = U.id_user + LEFT JOIN parts.Shop_User U ON t_S.as_int = U.id_user WHERE ISNULL(t_S.as_int) OR ISNULL(U.id_user) @@ -175,7 +175,7 @@ BEGIN v_code_error_bad_data, CONCAT('Invalid or inactive User IDs: ', IFNULL(GROUP_CONCAT(t_S.substring SEPARATOR ', '), 'NULL')) FROM tmp_Split t_S - LEFT JOIN demo.Shop_User U ON t_S.as_int = U.id_user + LEFT JOIN parts.Shop_User U ON t_S.as_int = U.id_user WHERE ISNULL(t_S.as_int) OR ISNULL(U.id_user) @@ -189,7 +189,7 @@ BEGIN U.id_user , RANK() OVER (ORDER BY U.id_user DESC) AS rank_user FROM tmp_Split t_S - RIGHT JOIN demo.Shop_User U ON t_S.as_int = U.id_user + RIGHT JOIN parts.Shop_User U ON t_S.as_int = U.id_user WHERE ( a_get_all_user = 1 @@ -208,7 +208,7 @@ BEGIN -- Auth0 User IDs IF (NOT EXISTS (SELECT * FROM tmp_Msg_Error LIMIT 1) AND v_has_filter_user_auth0 = 1) THEN - CALL demo.p_split(v_guid, a_ids_user_auth0, ',', FALSE); + CALL parts.p_core_split(v_guid, a_ids_user_auth0, ',', FALSE); DELETE FROM tmp_Split; @@ -217,21 +217,21 @@ BEGIN ) SELECT substring - FROM demo.Split_Temp + FROM parts.Split_Temp WHERE 1=1 AND GUID = v_guid AND NOT ISNULL(substring) AND substring != '' ; - CALL demo.p_clear_split_temp( v_guid ); + CALL parts.p_core_clear_split( v_guid ); END IF; IF (NOT EXISTS (SELECT * FROM tmp_Msg_Error LIMIT 1) AND v_has_filter_user_auth0 = 1) THEN IF EXISTS ( SELECT * FROM tmp_Split t_S - LEFT JOIN demo.Shop_User U ON t_S.substring = U.id_user_auth0 + LEFT JOIN parts.Shop_User U ON t_S.substring = U.id_user_auth0 WHERE ISNULL(t_S.substring) OR ISNULL(U.id_user_auth0) @@ -248,7 +248,7 @@ BEGIN v_code_error_bad_data, CONCAT('Invalid or inactive Auth0 User IDs: ', IFNULL(GROUP_CONCAT(t_S.substring SEPARATOR ', '), 'NULL')) FROM tmp_Split t_S - LEFT JOIN demo.Shop_User U ON t_S.substring = U.id_user_auth0 + LEFT JOIN parts.Shop_User U ON t_S.substring = U.id_user_auth0 WHERE ISNULL(t_S.substring) OR ISNULL(U.id_user_auth0) @@ -264,7 +264,7 @@ BEGIN U.id_user , v_rank_max + (RANK() OVER (ORDER BY U.id_user DESC)) AS rank_user FROM tmp_Split t_S - RIGHT JOIN demo.Shop_User U ON t_S.substring = U.id_user_auth0 + RIGHT JOIN parts.Shop_User U ON t_S.substring = U.id_user_auth0 WHERE ( a_get_all_user = 1 @@ -300,43 +300,43 @@ BEGIN SELECT * FROM tmp_User; END IF; - -- Can admin store + -- Can admin dog IF NOT EXISTS (SELECT * FROM tmp_Msg_Error LIMIT 1) THEN IF a_debug = 1 THEN SELECT v_guid -- guid , a_id_user -- ids_user , FALSE -- get_inactive_user - , v_id_permission_store_admin -- ids_permission + , v_id_permission_dog_admin -- ids_permission , v_id_access_level_admin -- ids_access_level , '' -- ids_product , 0 -- a_debug ; - SELECT * FROM demo.Shop_Calc_User_Temp; + SELECT * FROM parts.Shop_Calc_User_Temp; END IF; - CALL demo.p_shop_calc_user( + CALL parts.p_dog_calc_user( v_guid -- guid , a_id_user -- ids_user , FALSE -- get_inactive_user - , v_id_permission_store_admin -- ids_permission + , v_id_permission_dog_admin -- ids_permission , v_id_access_level_admin -- ids_access_level , '' -- ids_product , 0 -- a_debug ); IF a_debug = 1 THEN - SELECT * FROM demo.Shop_Calc_User_Temp WHERE GUID = v_guid; + SELECT * FROM parts.Shop_Calc_User_Temp WHERE GUID = v_guid; END IF; UPDATE tmp_User t_U - INNER JOIN demo.Shop_Calc_User_Temp CUT + INNER JOIN parts.Shop_Calc_User_Temp CUT ON CUT.GUID = v_guid AND t_U.id_user = CUT.id_user - SET t_U.can_admin_store = CUT.can_admin + SET t_U.can_admin_dog = CUT.can_admin ; - CALL demo.p_shop_clear_calc_user( v_guid, FALSE ); + CALL parts.p_dog_clear_calc_user( v_guid, FALSE ); END IF; -- Can admin user @@ -351,10 +351,10 @@ BEGIN , '' -- ids_product , 0 -- a_debug ; - SELECT * FROM demo.Shop_Calc_User_Temp; + SELECT * FROM parts.Shop_Calc_User_Temp; END IF; - CALL demo.p_shop_calc_user( + CALL parts.p_dog_calc_user( v_guid -- guid , a_id_user -- ids_user , FALSE -- get_inactive_user @@ -365,17 +365,17 @@ BEGIN ); IF a_debug = 1 THEN - SELECT * FROM demo.Shop_Calc_User_Temp WHERE GUID = v_guid; + SELECT * FROM parts.Shop_Calc_User_Temp WHERE GUID = v_guid; END IF; UPDATE tmp_User t_U - INNER JOIN demo.Shop_Calc_User_Temp CUT + INNER JOIN parts.Shop_Calc_User_Temp CUT ON CUT.GUID = v_guid AND t_U.id_user = CUT.id_user SET t_U.can_admin_user = CUT.can_admin ; - CALL demo.p_shop_clear_calc_user( v_guid, FALSE ); + CALL parts.p_dog_clear_calc_user( v_guid, FALSE ); END IF; -- Permissions @@ -390,10 +390,10 @@ BEGIN , '' -- ids_product , 0 -- a_debug ; - SELECT * FROM demo.Shop_Calc_User_Temp; + SELECT * FROM parts.Shop_Calc_User_Temp; END IF; - CALL demo.p_shop_calc_user( + CALL parts.p_dog_calc_user( v_guid -- guid , a_id_user -- ids_user , FALSE -- get_inactive_user @@ -404,12 +404,12 @@ BEGIN ); IF a_debug = 1 THEN - SELECT * FROM demo.Shop_Calc_User_Temp WHERE GUID = v_guid; + SELECT * FROM parts.Shop_Calc_User_Temp WHERE GUID = v_guid; END IF; IF NOT EXISTS ( SELECT can_view - FROM demo.Shop_Calc_User_Temp CUT + FROM parts.Shop_Calc_User_Temp CUT WHERE 1=1 AND CUT.GUID = v_guid AND can_view = 1 @@ -423,9 +423,9 @@ BEGIN VALUES ( v_id_type_error_bad_data, v_code_error_bad_data, - -- CONCAT('You do not have view permissions for ', (SELECT name FROM demo.Shop_Permission WHERE id_permission = v_id_permission_user LIMIT 1)) - -- CONCAT('You do not have view permissions for ', (SELECT GROUP_CONCAT(name SEPARATOR ', ') FROM demo.Shop_Permission WHERE FIND_IN_SET(v_id_permission_user, id_permission) > 0)) - CONCAT('You do not have view permissions for ', (SELECT name FROM demo.Shop_Permission P INNER JOIN demo.Shop_Calc_User_Temp CUT ON P.id_permission = CUT.id_permission_required WHERE GUID = v_guid AND IFNULL(can_view, 0) = 0 LIMIT 1)) -- WHERE IFNULL(CUT.can_view, 0) = 0 + -- CONCAT('You do not have view permissions for ', (SELECT name FROM parts.Shop_Permission WHERE id_permission = v_id_permission_user LIMIT 1)) + -- CONCAT('You do not have view permissions for ', (SELECT GROUP_CONCAT(name SEPARATOR ', ') FROM parts.Shop_Permission WHERE FIND_IN_SET(v_id_permission_user, id_permission) > 0)) + CONCAT('You do not have view permissions for ', (SELECT name FROM parts.Shop_Permission P INNER JOIN parts.Shop_Calc_User_Temp CUT ON P.id_permission = CUT.id_permission_required WHERE GUID = v_guid AND IFNULL(can_view, 0) = 0 LIMIT 1)) -- WHERE IFNULL(CUT.can_view, 0) = 0 ) ; ELSE @@ -433,7 +433,7 @@ BEGIN SET a_debug := a_debug; END IF; - CALL demo.p_shop_clear_calc_user( v_guid, FALSE ); + CALL parts.p_dog_clear_calc_user( v_guid, FALSE ); END IF; @@ -457,11 +457,11 @@ BEGIN , U.id_region_default , U.is_included_VAT_default , U.is_super_user - , t_U.can_admin_store + , t_U.can_admin_dog , t_U.can_admin_user , v_is_new AS is_new FROM tmp_User t_U - INNER JOIN demo.Shop_User U ON t_U.id_user = U.id_user + INNER JOIN parts.Shop_User U ON t_U.id_user = U.id_user ; # Errors @@ -472,7 +472,7 @@ BEGIN MET.name, MET.description FROM tmp_Msg_Error t_ME - INNER JOIN demo.Shop_Msg_Error_Type MET + INNER JOIN parts.Shop_Msg_Error_Type MET ON t_ME.id_type = MET.id_type ; @@ -486,12 +486,12 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; /* - DELETE FROM demo.Shop_Calc_User_Temp + DELETE FROM parts.Shop_Calc_User_Temp WHERE GUID = v_guid; */ IF a_debug = 1 THEN - CALL demo.p_debug_timing_reporting ( v_time_start ); + CALL parts.p_debug_timing_reporting ( v_time_start ); END IF; END // DELIMITER ; @@ -520,11 +520,11 @@ CALL p_dog_get_many_user ( );*/ /* -select * FROM demo.Shop_Calc_User_Temp; -delete FROM demo.Shop_Calc_User_Temp; +select * FROM parts.Shop_Calc_User_Temp; +delete FROM parts.Shop_Calc_User_Temp; SELECT * -FROM demo.Shop_USER; +FROM parts.Shop_USER; CALL p_dog_get_many_user( NULL -- :a_id_user, diff --git a/static/MySQL/70518_p_dog_save_user.sql b/static/MySQL/70518_p_dog_save_user.sql index ca5eee6..ee8478c 100644 --- a/static/MySQL/70518_p_dog_save_user.sql +++ b/static/MySQL/70518_p_dog_save_user.sql @@ -45,7 +45,7 @@ BEGIN MET.id_type , @errno , @text - FROM demo.Shop_Msg_Error_Type MET + FROM parts.Shop_Msg_Error_Type MET WHERE MET.code = 'MYSQL_ERROR' ; SELECT * @@ -112,7 +112,7 @@ BEGIN , IFNULL(U_T.is_included_VAT_default, U.is_included_VAT_default) AS is_included_VAT_default , IFNULL(IFNULL(U_T.active, U.active), 1) AS active , IFNULL(U_T.display_order, PC.display_order) AS display_order - FROM demo.Shop_User_Temp U_T + FROM parts.Shop_User_Temp U_T LEFT JOIN Shop_User U ON U_T.id_user = U.id_user WHERE U_T.guid = a_guid ; @@ -183,7 +183,7 @@ BEGIN ; END IF; - CALL p_shop_calc_user( + CALL p_dog_calc_user( a_guid -- GUID , a_id_user -- ID User , FALSE -- get inactive Users @@ -194,7 +194,7 @@ BEGIN SET v_can_admin_user := ( SELECT IFNULL(UE_T.can_edit, 0) = 1 - FROM demo.Shop_User_Eval_Temp UE_T + FROM parts.Shop_User_Eval_Temp UE_T WHERE UE_T.GUID = a_guid AND UE_T.id_user = a_id_user @@ -221,7 +221,7 @@ BEGIN ; END IF; - CALL p_shop_clear_calc_user(a_guid); + CALL p_dog_clear_calc_user(a_guid); IF NOT EXISTS (SELECT * FROM tmp_Msg_Error LIMIT 1) THEN START TRANSACTION; @@ -261,7 +261,7 @@ BEGIN # Errors SELECT * FROM tmp_Msg_Error t_ME - INNER JOIN demo.Shop_Msg_Error_Type MET ON t_ME.id_type = MET.id_type + INNER JOIN parts.Shop_Msg_Error_Type MET ON t_ME.id_type = MET.id_type ; IF a_debug = 1 THEN @@ -272,7 +272,7 @@ BEGIN DROP TABLE IF EXISTS tmp_User; IF a_debug = 1 THEN - CALL demo.p_debug_timing_reporting ( v_time_start ); + CALL parts.p_debug_timing_reporting ( v_time_start ); END IF; END // DELIMITER ; diff --git a/static/MySQL/70530_p_dog_calc_user.sql b/static/MySQL/70530_p_dog_calc_user.sql index 159f549..ac1a5b8 100644 --- a/static/MySQL/70530_p_dog_calc_user.sql +++ b/static/MySQL/70530_p_dog_calc_user.sql @@ -1,11 +1,11 @@ USE parts; -DROP PROCEDURE IF EXISTS parts.p_DOG_user_eval; -DROP PROCEDURE IF EXISTS parts.p_DOG_calc_user; +DROP PROCEDURE IF EXISTS parts.p_dog_user_eval; +DROP PROCEDURE IF EXISTS parts.p_dog_calc_user; DELIMITER // -CREATE PROCEDURE parts.p_DOG_calc_user ( +CREATE PROCEDURE parts.p_dog_calc_user ( IN a_guid BINARY(36) , IN a_ids_user TEXT , IN a_get_inactive_user BIT @@ -18,17 +18,17 @@ BEGIN DECLARE v_id_permission INT; DECLARE v_time_start TIMESTAMP(6); DECLARE v_ids_row_delete VARCHAR(500); - DECLARE v_code_type_error_bad_data VARCHAR(200); + DECLARE v_code_type_error_bad_data VARCHAR(250); DECLARE v_id_type_error_bad_data INT; - DECLARE v_code_error_permission VARCHAR(200); + DECLARE v_code_type_error_no_permission VARCHAR(250); DECLARE v_id_permission_required INT; DECLARE v_priority_access_level_required INT; DECLARE v_priority_access_level_view INT; SET v_time_start := CURRENT_TIMESTAMP(6); - SET v_code_type_error_bad_data := (SELECT code FROM parts.CORE_Msg_Error_Type WHERE code = 'BAD_DATA'); - SET v_id_type_error_bad_data := (SELECT id_type FROM parts.CORE_Msg_Error_Type WHERE code = v_code_type_error_bad_data); - SET v_code_error_permission := (SELECT code FROM parts.CORE_Msg_Error_Type WHERE id_type = 2); + SET v_code_type_error_bad_data := (SELECT code FROM parts.CORE_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1); + SET v_id_type_error_bad_data := (SELECT id_type FROM parts.CORE_Msg_Error_Type WHERE code = v_code_type_error_bad_data LIMIT 1); + SET v_code_type_error_no_permission := (SELECT code FROM parts.CORE_Msg_Error_Type WHERE code = 'NO_PERMISSION' LIMIT 1); SET v_priority_access_level_view := (SELECT priority FROM parts.DOG_Access_Level WHERE code = 'VIEW' LIMIT 1); CALL parts.p_core_validate_guid ( a_guid ); @@ -38,6 +38,7 @@ BEGIN SET a_debug := IFNULL(a_debug, 0); IF a_debug = 1 THEN + SELECT 'Arguments'; SELECT a_guid , a_ids_user @@ -45,6 +46,14 @@ BEGIN , a_ids_permission , a_debug ; + SELECT 'Derived variables'; + SELECT + v_code_type_error_bad_data + , v_code_type_error_no_permission + , v_id_type_error_bad_data + , v_priority_access_level_view + , v_time_start + ; END IF; DROP TABLE IF EXISTS tmp_Calc_User; @@ -174,6 +183,10 @@ BEGIN END IF; DELETE FROM tmp_Split_Calc_User; + IF a_debug = 1 THEN + SELECT v_id_permission_required; + END IF; + -- Users CALL parts.p_core_split(a_guid, a_ids_user, ',', a_debug); @@ -247,6 +260,17 @@ BEGIN AND AL_U.active GROUP BY U.id_user ; + + IF a_debug = 1 THEN + SELECT + t_UCU.id_user + , v_id_permission_required + , v_priority_access_level_required + , t_UCU.priority_access_level AS priority_access_level_user + , t_UCU.is_super_user AS is_super_user + FROM tmp_User_Calc_User t_UCU + ; + END IF; INSERT INTO tmp_Calc_User ( id_user @@ -306,7 +330,7 @@ BEGIN SELECT * FROM tmp_Calc_User; SELECT * FROM tmp_User_Calc_User; SELECT * FROM parts.DOG_Calc_User_Temp WHERE GUID = a_guid; - CALL parts.p_DOG_clear_calc_user ( a_guid, a_debug ); + CALL parts.p_dog_clear_calc_user ( a_guid, a_debug ); END IF; -- Clean up @@ -322,7 +346,7 @@ DELIMITER ; /* -CALL parts.p_DOG_calc_user ( +CALL parts.p_dog_calc_user ( 'chips ' -- a_guid , 1 -- a_ids_user , 0 -- a_get_inactive_user @@ -330,7 +354,7 @@ CALL parts.p_DOG_calc_user ( , '1' -- a_ids_access_level , 0 -- a_debug ); -CALL parts.p_DOG_calc_user ( +CALL parts.p_dog_calc_user ( 'chips ' -- a_guid , 1 -- a_ids_user , 0 -- a_get_inactive_user @@ -338,4 +362,15 @@ CALL parts.p_DOG_calc_user ( , '1' -- a_ids_access_level , 0 -- a_debug ); + + +DELETE FROM demo.DOG_Calc_User_Temp; +CALL demo.p_dog_calc_user ( + 'chips ' -- a_guid + , 1 -- a_ids_user + , 0 -- a_get_inactive_user + , '7' -- a_ids_permission + , 0 -- a_debug +); +SELECT * FROM demo.DOG_Calc_User_Temp; */ \ No newline at end of file diff --git a/static/MySQL/70531_p_dog_clear_calc_user.sql b/static/MySQL/70531_p_dog_clear_calc_user.sql index 61dad04..66149be 100644 --- a/static/MySQL/70531_p_dog_clear_calc_user.sql +++ b/static/MySQL/70531_p_dog_clear_calc_user.sql @@ -1,10 +1,10 @@ USE parts; -DROP PROCEDURE IF EXISTS parts.p_DOG_clear_calc_user; +DROP PROCEDURE IF EXISTS parts.p_dog_clear_calc_user; DELIMITER // -CREATE PROCEDURE parts.p_DOG_clear_calc_user ( +CREATE PROCEDURE parts.p_dog_clear_calc_user ( IN a_guid BINARY(36) , IN a_debug BIT ) @@ -16,8 +16,9 @@ BEGIN START TRANSACTION; - DELETE FROM parts.DOG_Calc_User_Temp - WHERE GUID = a_guid + DELETE CALC_USER_T + FROM parts.DOG_Calc_User_Temp CALC_USER_T + WHERE CALC_USER_T.GUID = a_guid ; COMMIT; @@ -30,7 +31,7 @@ DELIMITER ; /* -CALL parts.p_DOG_clear_calc_user ( +CALL parts.p_dog_clear_calc_user ( 'chips ' -- a_guid , 1 -- debug ); diff --git a/static/MySQL/71001_p_dog_calc_dog.sql b/static/MySQL/71001_p_dog_calc_dog.sql new file mode 100644 index 0000000..64fdb8d --- /dev/null +++ b/static/MySQL/71001_p_dog_calc_dog.sql @@ -0,0 +1,443 @@ + +USE parts; + +DROP PROCEDURE IF EXISTS parts.p_dog_calc_dog; + +DELIMITER // +CREATE PROCEDURE parts.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 + , 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_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); + + DECLARE exit handler for SQLEXCEPTION + BEGIN + GET DIAGNOSTICS CONDITION 1 + @sqlstate = RETURNED_SQLSTATE + , @errno = MYSQL_ERRNO + , @text = MESSAGE_TEXT + ; + + ROLLBACK; + + CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error_Calc_Dog ( + id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT + , id_type INT NULL + , code VARCHAR(100) NOT NULL + , msg VARCHAR(4000) NOT NULL + ); + + INSERT INTO tmp_Msg_Error_Calc_Dog ( + id_type + , code + , msg + ) + SELECT + MET.id_type + , @errno + , @text + FROM parts.CORE_Msg_Error_Type MET + 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_Dog t_ERROR + INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type + ; + + DROP TABLE IF EXISTS tmp_Msg_Error_Calc_Dog; + END; + + SET v_time_start := CURRENT_TIMESTAMP(6); + 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 parts.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 parts.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 parts.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); + + + CALL parts.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, '')); + 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_show_errors + , a_debug + ; + + SELECT + v_id_type_error_bad_data + , v_id_type_error_no_permission + , v_id_permission_dog_view + , 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; + + CREATE TEMPORARY TABLE tmp_Dog_Calc_Dog ( + id_dog INT NOT NULL + ); + + CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error_Calc_Dog ( + id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT + , id_type INT NULL + , code VARCHAR(100) NOT NULL + , msg VARCHAR(4000) NOT NULL + ); + + CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Id_Calc_Dog ( + substring VARCHAR(4000) NOT NULL + , as_int INT NULL + ); + 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 NULL + ); + DELETE FROM tmp_Split_Name_Calc_Dog; + + SET v_has_filter_dog_id = CASE WHEN a_ids_dog = '' THEN 0 ELSE 1 END; + SET v_has_filter_dog_name = CASE WHEN a_names_dog = '' THEN 0 ELSE 1 END; + + -- Dogs + IF v_has_filter_dog_id = 1 THEN + CALL parts.p_core_split(a_guid, a_ids_dog, ',', a_debug); + + INSERT INTO tmp_Split_Id_Calc_Dog ( + substring + , as_int + ) + SELECT + SPLIT_T.substring + , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int + FROM parts.CORE_Split_Temp SPLIT_T + WHERE + SPLIT_T.GUID = a_guid + AND IFNULL(SPLIT_T.substring, '') <> '' + ; + + CALL parts.p_core_clear_split( a_guid ); + END IF; + + IF v_has_filter_dog_name = 1 THEN + CALL parts.p_core_split(a_guid, a_names_dog, ',', a_debug); + + INSERT INTO tmp_Split_Name_Calc_Dog ( + substring + , as_int + ) + SELECT + SPLIT_T.substring + , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int + FROM parts.CORE_Split_Temp SPLIT_T + WHERE + SPLIT_T.GUID = a_guid + AND IFNULL(SPLIT_T.substring, '') <> '' + ; + + CALL parts.p_core_clear_split( a_guid ); + END IF; + + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Dog t_ERROR INNER JOIN parts.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 parts.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 parts.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 ( + SELECT * + FROM tmp_Split t_SPLIT + LEFT JOIN parts.DOG_Dog DOG ON t_SPLIT.as_int = DOG.id_dog + WHERE + ISNULL(t_SPLIT.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.substring SEPARATOR ', '), 'NULL')) + FROM tmp_Split t_SPLIT + LEFT JOIN parts.DOG_Dog DOG ON t_SPLIT.as_int = DOG.id_dog + WHERE + ISNULL(t_SPLIT.as_int) + OR ISNULL(DOG.id_dog) + OR ( + DOG.active = 0 + AND a_get_inactive_dog = 0 + ) + ; + */ + ELSE + INSERT INTO tmp_Dog_Calc_Dog ( + id_dog + ) + WITH + Dog_Id_Filter AS ( + SELECT DOG.id_dog + FROM tmp_Split_Id_Calc_Dog t_SPLIT_ID + RIGHT JOIN parts.DOG_Dog DOG ON t_SPLIT_ID.as_int = DOG.id_dog + WHERE t_SPLIT_ID.as_int IS NOT NULL + ) + , Dog_Name_Filter AS ( + SELECT DOG.id_dog + FROM tmp_Split_Name_Calc_Dog t_SPLIT_NAME + RIGHT JOIN parts.DOG_Dog DOG ON DOG.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') + WHERE + t_SPLIT_NAME.substring IS NOT NULL + AND t_SPLIT_NAME.substring <> '' + ) + , Dog_Filters AS ( + SELECT DISTINCT DOG_COMBINED.id_dog + FROM ( + SELECT DOG_ID_FILTER.id_dog FROM Dog_Id_Filter DOG_ID_FILTER + UNION + SELECT DOG_NAME_FILTER.id_dog FROM Dog_Name_Filter DOG_NAME_FILTER + ) DOG_COMBINED + ) + SELECT + DOG.id_dog + FROM parts.DOG_Dog DOG + LEFT JOIN Dog_Filters DOG_FILTERS ON DOG.id_dog = DOG_FILTERS.id_dog + WHERE + ( + a_get_all_dog = 1 + OR ( + ( + v_has_filter_dog_id = 1 + OR v_has_filter_dog_name = 1 + ) + AND DOG_FILTERS.id_dog IS NOT NULL + ) + ) + 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; + + + -- Permissions + IF a_debug = 1 THEN + SELECT + a_guid + , a_id_user + , FALSE -- a_get_inactive_user + , v_id_permission_dog_view + , 0 -- a_debug + ; + END IF; + + CALL parts.p_dog_calc_user( + a_guid + , a_id_user + , FALSE -- a_get_inactive_user + , v_id_permission_dog_view + , 0 -- a_debug + ); + + SELECT + IFNULL(CALC_USER_T.has_access, 0) + INTO + v_can_view + FROM parts.DOG_Calc_User_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_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 Commands.' + ) + ; + END IF; + + CALL parts.p_dog_clear_calc_user( + a_guid + , 0 -- a_debug + ); + + IF EXISTS(SELECT * FROM tmp_Msg_Error_Calc_Dog t_ERROR INNER JOIN parts.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; + END IF; + + DELETE FROM tmp_Dog_Calc_Dog; + END IF; + + -- Outputs + -- Commands + INSERT INTO parts.DOG_Dog_Temp ( + guid + , id_dog + , name + , appearance + , mass_kg + , notes + , active + ) + SELECT + a_guid + , t_DOG.id_dog + , DOG.name + , DOG.appearance + , DOG.mass_kg + , DOG.notes + , DOG.active + FROM parts.DOG_Dog DOG + INNER JOIN tmp_Dog_Calc_Dog t_DOG ON DOG.id_dog = t_DOG.id_dog + ; + + -- 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_Calc_Dog t_ERROR + INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type + ; + + IF a_debug = 1 AND v_can_view = 1 THEN + SELECT * FROM tmp_Dog_Calc_Dog; + 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; + + IF a_debug = 1 THEN + CALL parts.p_core_debug_timing_reporting ( v_time_start ); + END IF; +END // +DELIMITER ; + + +/* + + +CALL parts.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 + , 1 -- a_show_errors + , 1 -- a_debug +); + +SELECT * +FROM parts.DOG_Dog_Temp +; + +CALL parts.p_dog_clear_calc_dog ( + 'slips ' -- a_guid + , 1 -- debug +); + +*/ \ No newline at end of file diff --git a/static/MySQL/71001_p_dog_clear_calc_dog.sql b/static/MySQL/71001_p_dog_clear_calc_dog.sql new file mode 100644 index 0000000..a89d8a4 --- /dev/null +++ b/static/MySQL/71001_p_dog_clear_calc_dog.sql @@ -0,0 +1,44 @@ + +USE parts; + +DROP PROCEDURE IF EXISTS parts.p_dog_clear_calc_dog; + +DELIMITER // +CREATE PROCEDURE parts.p_dog_clear_calc_dog ( + IN a_guid BINARY(36) + , IN a_debug BIT +) +BEGIN + DECLARE v_time_start TIMESTAMP(6); + SET v_time_start := CURRENT_TIMESTAMP(6); + + CALL parts.p_core_validate_guid ( a_guid ); + + START TRANSACTION; + + DELETE DOG_T + FROM parts.DOG_Dog_Temp DOG_T + WHERE DOG_T.GUID = a_guid + ; + + COMMIT; + + IF a_debug = 1 THEN + CALL parts.p_debug_timing_reporting( v_time_start ); + END IF; +END // +DELIMITER ; + +/* + +CALL parts.p_dog_clear_calc_dog ( + 'crips ' -- a_guid + , 1 -- debug +); + +SELECT * +FROM parts.DOG_Calc_User_Temp +WHERE GUID = 'chips ' +; + +*/ diff --git a/static/MySQL/71001_p_dog_get_many_dog.sql b/static/MySQL/71001_p_dog_get_many_dog.sql index 4f75aca..133920e 100644 --- a/static/MySQL/71001_p_dog_get_many_dog.sql +++ b/static/MySQL/71001_p_dog_get_many_dog.sql @@ -1,10 +1,10 @@ USE parts; -DROP PROCEDURE IF EXISTS parts.p_DOG_get_many_dog; +DROP PROCEDURE IF EXISTS parts.p_dog_get_many_dog; DELIMITER // -CREATE PROCEDURE parts.p_DOG_get_many_dog ( +CREATE PROCEDURE parts.p_dog_get_many_dog ( IN a_id_user INT , IN a_get_all_dog BIT , IN a_get_inactive_dog BIT @@ -13,17 +13,17 @@ CREATE PROCEDURE parts.p_DOG_get_many_dog ( , 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_id_type_error_bad_data INT; - DECLARE v_id_type_error_no_permission INT; + DECLARE v_guid BINARY(36); DECLARE v_has_filter_dog_id BIT; DECLARE v_has_filter_dog_name BIT; - DECLARE v_guid BINARY(36); - DECLARE v_id_permission_dog_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); - DECLARE v_can_view BIT; DECLARE exit handler for SQLEXCEPTION BEGIN @@ -106,14 +106,16 @@ BEGIN ; END IF; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; DROP TEMPORARY TABLE IF EXISTS tmp_Dog; CREATE TEMPORARY TABLE tmp_Dog ( id_dog INT NOT NULL , name VARCHAR(250) + , appearance VARCHAR(1000) + , mass_kg DECIMAL(7, 3) + , notes TEXT + , active BIT ); CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error ( @@ -121,160 +123,8 @@ BEGIN , id_type INT NULL , code VARCHAR(100) NOT NULL , msg VARCHAR(4000) NOT NULL - ); + ); - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Id ( - substring VARCHAR(4000) NOT NULL - , as_int INT NULL - ); - DELETE FROM tmp_Split_Id; - - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Name ( - substring VARCHAR(4000) NOT NULL - , as_int INT NULL - ); - DELETE FROM tmp_Split_Name; - - CALL parts.p_core_validate_guid ( v_guid ); - - SET v_has_filter_dog_id = CASE WHEN a_ids_dog = '' THEN 0 ELSE 1 END; - SET v_has_filter_dog_name = CASE WHEN a_names_dog = '' THEN 0 ELSE 1 END; - - -- Dogs - IF v_has_filter_dog_id = 1 THEN - CALL parts.p_split(v_guid, a_ids_dog, ',', a_debug); - - INSERT INTO tmp_Split_Id ( - substring - , as_int - ) - SELECT - SPLIT_T.substring - , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int - FROM parts.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = v_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; - - CALL parts.p_clear_split_temp( v_guid ); - END IF; - - IF v_has_filter_dog_name = 1 THEN - CALL parts.p_split(v_guid, a_names_dog, ',', a_debug); - - INSERT INTO tmp_Split_Name ( - substring - , as_int - ) - SELECT - SPLIT_T.substring - , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int - FROM parts.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = v_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; - - CALL parts.p_clear_split_temp( v_guid ); - END IF; - - IF NOT EXISTS (SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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 t_SPLIT_ID - LEFT JOIN parts.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 ( - 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 t_SPLIT_ID - LEFT JOIN parts.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 ( - SELECT * - FROM tmp_Split t_SPLIT - LEFT JOIN parts.DOG_Dog DOG ON t_SPLIT.as_int = DOG.id_dog - WHERE - ISNULL(t_SPLIT.as_int) - OR ISNULL(DOG.id_dog) - OR ( - DOG.active = 0 - AND a_get_inactive_dog = 0 - ) - ) THEN - INSERT INTO tmp_Msg_Error ( - 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.substring SEPARATOR ', '), 'NULL')) - FROM tmp_Split t_SPLIT - LEFT JOIN parts.DOG_Dog DOG ON t_SPLIT.as_int = DOG.id_dog - WHERE - ISNULL(t_SPLIT.as_int) - OR ISNULL(DOG.id_dog) - OR ( - DOG.active = 0 - AND a_get_inactive_dog = 0 - ) - ; - */ - ELSE - INSERT INTO tmp_Dog ( - id_dog - , name - ) - SELECT - DOG.id_dog - , DOG.name - FROM parts.DOG_Dog DOG - LEFT JOIN tmp_Split_Id t_SPLIT_ID ON DOG.id_dog = t_SPLIT_ID.as_int - LEFT JOIN tmp_Split_Name t_SPLIT_NAME ON DOG.name = t_SPLIT_NAME.substring - WHERE - ( - a_get_all_dog = 1 - OR ( - v_has_filter_dog_id = 1 - OR v_has_filter_dog_name = 1 - ) - ) - AND ( - a_get_inactive_dog = 1 - OR DOG.active = 1 - ) - ; - END IF; - END IF; - - DELETE FROM tmp_Split_Id; - DELETE FROM tmp_Split_Name; - - -- Permissions IF a_debug = 1 THEN SELECT @@ -286,7 +136,7 @@ BEGIN ; END IF; - CALL parts.p_DOG_calc_user( + CALL parts.p_dog_calc_user( v_guid , a_id_user , FALSE -- a_get_inactive_user @@ -305,6 +155,8 @@ BEGIN 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 @@ -325,11 +177,63 @@ BEGIN ; END IF; - CALL parts.p_DOG_clear_calc_user( + CALL parts.p_dog_clear_calc_user( v_guid , 0 -- a_debug ); + + -- Call Dog Calc + IF NOT EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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_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 + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL parts.p_dog_calc_dog( + v_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 + , 0 -- a_show_errors + , 0 -- a_debug + ); + + INSERT INTO tmp_Dog ( + id_dog + , name + , appearance + , mass_kg + , notes + , active + ) + SELECT + DOG_T.id_dog + , DOG_T.name + , DOG_T.appearance + , DOG_T.mass_kg + , DOG_T.notes + , DOG_T.active + FROM parts.DOG_Dog_Temp DOG_T + WHERE DOG_T.GUID = v_guid + ; + + IF a_debug = 1 THEN + SELECT * FROM tmp_Dog; + END IF; + END IF; + + -- Filter outputs IF EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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; @@ -338,19 +242,18 @@ BEGIN DELETE FROM tmp_Dog; END IF; + -- Outputs - -- Commands SELECT - t_DOG.id_dog - , t_DOG.name - , DOG.appearance - , DOG.mass_kg - , DOG.notes - , DOG.active - FROM parts.DOG_Dog DOG - INNER JOIN tmp_Dog t_DOG ON DOG.id_dog = t_DOG.id_dog - ; - + DOG_T.id_dog + , DOG_T.name + , DOG_T.appearance + , DOG_T.mass_kg + , DOG_T.notes + , DOG_T.active + FROM parts.DOG_Dog_Temp DOG_T + ; + -- Errors SELECT t_ERROR.id_error @@ -369,9 +272,12 @@ BEGIN IF a_debug = 1 AND v_can_view = 1 THEN SELECT * FROM tmp_Dog; END IF; + + CALL parts.p_dog_clear_calc_dog( + v_guid -- a_guid + , 0 -- a_debug + ); - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; DROP TEMPORARY TABLE IF EXISTS tmp_Dog; @@ -384,7 +290,7 @@ DELIMITER ; /* -CALL parts.p_DOG_get_many_dog ( +CALL parts.p_dog_get_many_dog ( 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user , 1 -- a_get_all_dog , 0 -- a_get_inactive_dog diff --git a/static/MySQL/71003_p_dog_save_command.sql b/static/MySQL/71003_p_dog_save_command.sql index 481087c..b2fb104 100644 --- a/static/MySQL/71003_p_dog_save_command.sql +++ b/static/MySQL/71003_p_dog_save_command.sql @@ -1,10 +1,10 @@ USE parts; -DROP PROCEDURE IF EXISTS parts.p_DOG_save_command; +DROP PROCEDURE IF EXISTS parts.p_dog_save_command; DELIMITER // -CREATE PROCEDURE parts.p_DOG_save_command ( +CREATE PROCEDURE parts.p_dog_save_command ( IN a_comment VARCHAR(500), IN a_guid BINARY(36), IN a_id_user INT, @@ -219,7 +219,7 @@ BEGIN ; END IF; - CALL parts.p_DOG_calc_user( + CALL parts.p_dog_calc_user( a_guid , a_id_user , FALSE -- a_get_inactive_user @@ -236,12 +236,12 @@ BEGIN LIMIT 1 ; - CALL parts.p_DOG_clear_calc_user( + CALL parts.p_dog_clear_calc_user( a_guid , 0 -- a_debug ); - CALL parts.p_DOG_calc_user( + CALL parts.p_dog_calc_user( a_guid , a_id_user , FALSE -- a_get_inactive_user @@ -258,7 +258,7 @@ BEGIN LIMIT 1 ; - CALL parts.p_DOG_clear_calc_user( + CALL parts.p_dog_clear_calc_user( a_guid , 0 -- a_debug ); @@ -427,7 +427,7 @@ from parts.DOG_Command ; -CALL parts.p_DOG_save_command ( +CALL parts.p_dog_save_command ( 'nipples' , (SELECT GUID FROM parts.DOG_Command_Temp COMMAND_TEMP ORDER BY id_temp DESC LIMIT 1) , 1 diff --git a/static/MySQL/71004_p_dog_test_save_command.sql b/static/MySQL/71004_p_dog_test_save_command.sql index c6f90be..80b1e76 100644 --- a/static/MySQL/71004_p_dog_test_save_command.sql +++ b/static/MySQL/71004_p_dog_test_save_command.sql @@ -1,10 +1,10 @@ USE parts; -DROP PROCEDURE IF EXISTS parts.p_DOG_test_save_command; +DROP PROCEDURE IF EXISTS parts.p_dog_test_save_command; DELIMITER // -CREATE PROCEDURE parts.p_DOG_test_save_command () +CREATE PROCEDURE parts.p_dog_test_save_command () BEGIN DECLARE v_guid BINARY(36); @@ -61,7 +61,7 @@ BEGIN -- WHERE GUID = v_guid ; - CALL parts.p_DOG_save_command ( + CALL parts.p_dog_save_command ( 'Test save Command' -- comment , v_guid -- guid , 3 -- 1 -- id_user @@ -90,7 +90,7 @@ FROM parts.DOG_Command_Temp ; -CALL parts.p_DOG_test_save_command (); +CALL parts.p_dog_test_save_command (); SELECT 'After Test'; SELECT * diff --git a/static/MySQL/71104_p_dog_calc_command.sql b/static/MySQL/71104_p_dog_calc_command.sql new file mode 100644 index 0000000..3a1e0b0 --- /dev/null +++ b/static/MySQL/71104_p_dog_calc_command.sql @@ -0,0 +1,651 @@ + +USE parts; + +DROP PROCEDURE IF EXISTS parts.p_dog_calc_command; + +DELIMITER // +CREATE PROCEDURE parts.p_dog_calc_command ( + IN a_guid BINARY(36) + , IN a_id_user INT + , IN a_get_all_command_category BIT + , IN a_get_inactive_command_category BIT + , IN a_ids_command_category TEXT + , IN a_names_command_category TEXT + , IN a_get_all_command BIT + , IN a_get_inactive_command BIT + , IN a_ids_command TEXT + , IN a_names_command TEXT + , 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_command_id BIT; + DECLARE v_has_filter_command_name BIT; + DECLARE v_has_filter_command_category_id BIT; + DECLARE v_has_filter_command_category_name BIT; + 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); + + DECLARE exit handler for SQLEXCEPTION + BEGIN + GET DIAGNOSTICS CONDITION 1 + @sqlstate = RETURNED_SQLSTATE + , @errno = MYSQL_ERRNO + , @text = MESSAGE_TEXT + ; + + ROLLBACK; + + CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error_Calc_Command ( + id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT + , id_type INT NULL + , code VARCHAR(100) NOT NULL + , msg VARCHAR(4000) NOT NULL + ); + + INSERT INTO tmp_Msg_Error_Calc_Command ( + id_type + , code + , msg + ) + SELECT + MET.id_type + , @errno + , @text + FROM parts.CORE_Msg_Error_Type MET + 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_Command t_ERROR + INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type + ; + + DROP TABLE IF EXISTS tmp_Msg_Error_Calc_Command; + END; + + SET v_time_start := CURRENT_TIMESTAMP(6); + 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 parts.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 parts.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 parts.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); + + + CALL parts.p_core_validate_guid ( a_guid ); + + SET a_id_user := IFNULL(a_id_user, 0); + SET a_get_all_command_category := IFNULL(a_get_all_command_category, 0); + SET a_get_inactive_command_category := IFNULL(a_get_inactive_command_category, 0); + SET a_ids_command_category := TRIM(IFNULL(a_ids_command_category, '')); + SET a_names_command_category := TRIM(IFNULL(a_names_command_category, '')); + SET a_get_all_command := IFNULL(a_get_all_command, 0); + SET a_get_inactive_command := IFNULL(a_get_inactive_command, 0); + SET a_ids_command := TRIM(IFNULL(a_ids_command, '')); + SET a_names_command := TRIM(IFNULL(a_names_command, '')); + 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_command_category + , a_get_inactive_command_category + , a_ids_command_category + , a_names_command_category + , a_get_all_command + , a_get_inactive_command + , a_ids_command + , a_names_command + , a_show_errors + , a_debug + ; + + SELECT + v_id_type_error_bad_data + , v_id_type_error_no_permission + , v_id_permission_dog_view + , v_time_start + ; + END IF; + + DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name_Calc_Command; + DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_Command; + DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_Command; + DROP TEMPORARY TABLE IF EXISTS tmp_Command_Calc_Command; + + CREATE TEMPORARY TABLE tmp_Command_Calc_Command_Category ( + id_command_category INT NOT NULL + ); + + CREATE TEMPORARY TABLE tmp_Command_Calc_Command ( + id_command INT NOT NULL + , id_command_category INT NOT NULL + ); + + CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error_Calc_Command ( + id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT + , id_type INT NULL + , code VARCHAR(100) NOT NULL + , msg VARCHAR(4000) NOT NULL + ); + + CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Id_Calc_Command ( + substring VARCHAR(4000) NOT NULL + , as_int INT NULL + ); + DELETE FROM tmp_Split_Id_Calc_Command; + + CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Name_Calc_Command ( + substring VARCHAR(4000) NOT NULL + , as_int INT NULL + ); + DELETE FROM tmp_Split_Name_Calc_Command; + + SET v_has_filter_command_category_id = CASE WHEN a_ids_command_category = '' THEN 0 ELSE 1 END; + SET v_has_filter_command_category_name = CASE WHEN a_names_command_category = '' THEN 0 ELSE 1 END; + SET v_has_filter_command_id = CASE WHEN a_ids_command = '' THEN 0 ELSE 1 END; + SET v_has_filter_command_name = CASE WHEN a_names_command = '' THEN 0 ELSE 1 END; + + -- Command Categories + IF v_has_filter_command_category_id = 1 THEN + CALL parts.p_core_split(a_guid, a_ids_command_category, ',', a_debug); + + INSERT INTO tmp_Split_Id_Calc_Command ( + substring + , as_int + ) + SELECT + SPLIT_T.substring + , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int + FROM parts.CORE_Split_Temp SPLIT_T + WHERE + SPLIT_T.GUID = a_guid + AND IFNULL(SPLIT_T.substring, '') <> '' + ; + + CALL parts.p_core_clear_split( a_guid ); + END IF; + + IF v_has_filter_command_category_name = 1 THEN + CALL parts.p_core_split(a_guid, a_names_command_category, ',', a_debug); + + INSERT INTO tmp_Split_Name_Calc_Command ( + substring + , as_int + ) + SELECT + SPLIT_T.substring + , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int + FROM parts.CORE_Split_Temp SPLIT_T + WHERE + SPLIT_T.GUID = a_guid + AND IFNULL(SPLIT_T.substring, '') <> '' + ; + + CALL parts.p_core_clear_split( a_guid ); + END IF; + + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Command t_ERROR INNER JOIN parts.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_Command t_SPLIT_ID + LEFT JOIN parts.DOG_Command_Category COMMAND_CATEGORY ON t_SPLIT_ID.as_int = COMMAND_CATEGORY.id_command_category + WHERE + ISNULL(t_SPLIT_ID.as_int) + OR ISNULL(COMMAND_CATEGORY.id_command_category) + OR ( + COMMAND_CATEGORY.active = 0 + AND a_get_inactive_command_category = 0 + ) + ) THEN + INSERT INTO tmp_Msg_Error_Calc_Command ( + id_type + , code + , msg + ) + SELECT + v_id_type_error_bad_data + , v_code_type_error_bad_data + , CONCAT('Invalid or inactive Command IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT_ID.substring SEPARATOR ', '), 'NULL')) + FROM tmp_Split_Id_Calc_Command t_SPLIT_ID + LEFT JOIN parts.DOG_Command_Category COMMAND_CATEGORY ON t_SPLIT_ID.as_int = COMMAND_CATEGORY.id_command_category + WHERE + ISNULL(t_SPLIT_ID.as_int) + OR ISNULL(COMMAND_CATEGORY.id_command_category) + OR ( + COMMAND_CATEGORY.active = 0 + AND a_get_inactive_command_category = 0 + ) + ; + /* Don't error on names not found + ELSEIF EXISTS ( + SELECT * + FROM tmp_Split t_SPLIT + LEFT JOIN parts.DOG_Command_Category COMMAND_CATEGORY ON t_SPLIT.as_int = COMMAND_CATEGORY.id_command_category + WHERE + ISNULL(t_SPLIT.as_int) + OR ISNULL(COMMAND_CATEGORY.id_command_category) + OR ( + COMMAND_CATEGORY.active = 0 + AND a_get_inactive_command_category = 0 + ) + ) THEN + INSERT INTO tmp_Msg_Error_Calc_Command ( + id_type + , code + , msg + ) + SELECT + v_id_type_error_bad_data + , v_code_type_error_bad_data + , CONCAT('Invalid or inactive Command IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT.substring SEPARATOR ', '), 'NULL')) + FROM tmp_Split t_SPLIT + LEFT JOIN parts.DOG_Command_Category COMMAND_CATEGORY ON t_SPLIT.as_int = COMMAND_CATEGORY.id_command_category + WHERE + ISNULL(t_SPLIT.as_int) + OR ISNULL(COMMAND_CATEGORY.id_command_category) + OR ( + COMMAND_CATEGORY.active = 0 + AND a_get_inactive_command_category = 0 + ) + ; + */ + ELSE + INSERT INTO tmp_Command_Calc_Command_Category ( + id_command_category + ) + WITH + Command_Category_Id_Filter AS ( + SELECT COMMAND_CATEGORY.id_command_category + FROM tmp_Split_Id_Calc_Command t_SPLIT_ID + RIGHT JOIN parts.DOG_Command_Category COMMAND_CATEGORY ON t_SPLIT_ID.as_int = COMMAND_CATEGORY.id_command_category + WHERE t_SPLIT_ID.as_int IS NOT NULL + ) + , Command_Category_Name_Filter AS ( + SELECT COMMAND_CATEGORY.id_command_category + FROM tmp_Split_Name_Calc_Command t_SPLIT_NAME + RIGHT JOIN parts.DOG_Command_Category COMMAND_CATEGORY ON COMMAND_CATEGORY.name LIKE CONCAT('%', t_SPLIT_NAME.substring, '%') + WHERE + t_SPLIT_NAME.substring IS NOT NULL + AND t_SPLIT_NAME.substring <> '' + ) + , Command_Category_Filters AS ( + SELECT DISTINCT COMMAND_CATEGORY_COMBINED.id_command_category + FROM ( + SELECT COMMAND_CATEGORY_ID_FILTER.id_command_category FROM Command_Category_Id_Filter COMMAND_CATEGORY_ID_FILTER + UNION + SELECT COMMAND_CATEGORY_NAME_FILTER.id_command_category FROM Command_Category_Name_Filter COMMAND_CATEGORY_NAME_FILTER + ) COMMAND_CATEGORY_COMBINED + ) + SELECT + COMMAND_CATEGORY.id_command_category + FROM parts.DOG_Command_Category COMMAND_CATEGORY + LEFT JOIN Command_Category_Filters COMMAND_CATEGORY_FILTERS ON COMMAND_CATEGORY.id_command_category = COMMAND_CATEGORY_FILTERS.id_command_category + WHERE + ( + a_get_all_command_category = 1 + OR ( + ( + v_has_filter_command_category_id = 1 + OR v_has_filter_command_category_name = 1 + ) + AND COMMAND_CATEGORY_FILTERS.id_command_category IS NOT NULL + ) + ) + AND ( + a_get_inactive_command_category = 1 + OR COMMAND_CATEGORY.active = 1 + ) + ; + END IF; + END IF; + + DELETE FROM tmp_Split_Id_Calc_Command; + DELETE FROM tmp_Split_Name_Calc_Command; + + -- Commands + IF v_has_filter_command_id = 1 THEN + CALL parts.p_core_split(a_guid, a_ids_command, ',', a_debug); + + INSERT INTO tmp_Split_Id_Calc_Command ( + substring + , as_int + ) + SELECT + SPLIT_T.substring + , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int + FROM parts.CORE_Split_Temp SPLIT_T + WHERE + SPLIT_T.GUID = a_guid + AND IFNULL(SPLIT_T.substring, '') <> '' + ; + + CALL parts.p_core_clear_split( a_guid ); + END IF; + + IF v_has_filter_command_name = 1 THEN + CALL parts.p_core_split(a_guid, a_names_command, ',', a_debug); + + INSERT INTO tmp_Split_Name_Calc_Command ( + substring + , as_int + ) + SELECT + SPLIT_T.substring + , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int + FROM parts.CORE_Split_Temp SPLIT_T + WHERE + SPLIT_T.GUID = a_guid + AND IFNULL(SPLIT_T.substring, '') <> '' + ; + + CALL parts.p_core_clear_split( a_guid ); + END IF; + + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error_Calc_Command t_ERROR INNER JOIN parts.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_Command t_SPLIT_ID + LEFT JOIN parts.DOG_Command COMMAND ON t_SPLIT_ID.as_int = COMMAND.id_command + WHERE + ISNULL(t_SPLIT_ID.as_int) + OR ISNULL(COMMAND.id_command) + OR ( + COMMAND.active = 0 + AND a_get_inactive_command = 0 + ) + ) THEN + INSERT INTO tmp_Msg_Error_Calc_Command ( + id_type + , code + , msg + ) + SELECT + v_id_type_error_bad_data + , v_code_type_error_bad_data + , CONCAT('Invalid or inactive Command IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT_ID.substring SEPARATOR ', '), 'NULL')) + FROM tmp_Split_Id_Calc_Command t_SPLIT_ID + LEFT JOIN parts.DOG_Command COMMAND ON t_SPLIT_ID.as_int = COMMAND.id_command + WHERE + ISNULL(t_SPLIT_ID.as_int) + OR ISNULL(COMMAND.id_command) + OR ( + COMMAND.active = 0 + AND a_get_inactive_command = 0 + ) + ; + /* Don't error on names not found + ELSEIF EXISTS ( + SELECT * + FROM tmp_Split t_SPLIT + LEFT JOIN parts.DOG_Command COMMAND ON t_SPLIT.as_int = COMMAND.id_command + WHERE + ISNULL(t_SPLIT.as_int) + OR ISNULL(COMMAND.id_command) + OR ( + COMMAND.active = 0 + AND a_get_inactive_command = 0 + ) + ) THEN + INSERT INTO tmp_Msg_Error_Calc_Command ( + id_type + , code + , msg + ) + SELECT + v_id_type_error_bad_data + , v_code_type_error_bad_data + , CONCAT('Invalid or inactive Command IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT.substring SEPARATOR ', '), 'NULL')) + FROM tmp_Split t_SPLIT + LEFT JOIN parts.DOG_Command COMMAND ON t_SPLIT.as_int = COMMAND.id_command + WHERE + ISNULL(t_SPLIT.as_int) + OR ISNULL(COMMAND.id_command) + OR ( + COMMAND.active = 0 + AND a_get_inactive_command = 0 + ) + ; + */ + ELSE + INSERT INTO tmp_Command_Calc_Command ( + id_command + , id_command_category + ) + WITH + Command_Id_Filter AS ( + SELECT COMMAND.id_command + FROM tmp_Split_Id_Calc_Command t_SPLIT_ID + RIGHT JOIN parts.DOG_Command COMMAND ON t_SPLIT_ID.as_int = COMMAND.id_command + WHERE t_SPLIT_ID.as_int IS NOT NULL + ) + , Command_Name_Filter AS ( + SELECT COMMAND.id_command + FROM tmp_Split_Name_Calc_Command t_SPLIT_NAME + RIGHT JOIN parts.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_Filters AS ( + SELECT DISTINCT COMMAND_COMBINED.id_command + FROM ( + SELECT COMMAND_ID_FILTER.id_command FROM Command_Id_Filter COMMAND_ID_FILTER + UNION + SELECT COMMAND_NAME_FILTER.id_command FROM Command_Name_Filter COMMAND_NAME_FILTER + ) COMMAND_COMBINED + ) + SELECT + COMMAND.id_command + , COMMAND.id_command_category + FROM parts.DOG_Command COMMAND + INNER JOIN tmp_Command_Calc_Command_Category 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 + WHERE + ( + a_get_all_command = 1 + OR ( + ( + v_has_filter_command_id = 1 + OR v_has_filter_command_name = 1 + ) + AND COMMAND_FILTERS.id_command IS NOT NULL + ) + ) + AND ( + a_get_inactive_command = 1 + OR COMMAND.active = 1 + ) + ; + END IF; + END IF; + + DELETE FROM tmp_Split_Id_Calc_Command; + DELETE FROM tmp_Split_Name_Calc_Command; + + + -- Permissions + IF a_debug = 1 THEN + SELECT + a_guid + , a_id_user + , FALSE -- a_get_inactive_user + , v_id_permission_dog_view + , 0 -- a_debug + ; + END IF; + + CALL parts.p_dog_calc_user( + a_guid + , a_id_user + , FALSE -- a_get_inactive_user + , v_id_permission_dog_view + , 0 -- a_debug + ); + + SELECT + IFNULL(CALC_USER_T.has_access, 0) + INTO + v_can_view + FROM parts.DOG_Calc_User_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_Command t_ME + WHERE t_ME.id_type <> v_id_type_error_no_permission + ; + INSERT INTO tmp_Msg_Error_Calc_Command ( + 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 Commands.' + ) + ; + END IF; + + CALL parts.p_dog_clear_calc_user( + a_guid + , 0 -- a_debug + ); + + IF EXISTS(SELECT * FROM tmp_Msg_Error_Calc_Command t_ERROR INNER JOIN parts.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_Command_Calc_Command; + END IF; + + DELETE FROM tmp_Command_Calc_Command; + END IF; + + -- Outputs + START TRANSACTION; + -- Command Categories + INSERT INTO parts.DOG_Command_Category_Temp ( + guid + , id_command_category + , code + , name + , active + ) + SELECT + a_guid + , t_COMMAND_CATEGORY.id_command_category + , COMMAND_CATEGORY.code + , COMMAND_CATEGORY.name + , COMMAND_CATEGORY.active + FROM parts.DOG_Command_Category COMMAND_CATEGORY + INNER JOIN tmp_Command_Calc_Command_Category t_COMMAND_CATEGORY ON COMMAND_CATEGORY.id_command_category = t_COMMAND_CATEGORY.id_command_category + ; + + -- Commands + INSERT INTO parts.DOG_Command_Temp ( + guid + , id_command + , id_command_category + , name + , hand_signal_default_description + , can_have_button + , notes + , active + ) + SELECT + a_guid + , t_COMMAND.id_command + , t_COMMAND_CATEGORY.id_command_category + , COMMAND.name + , COMMAND.hand_signal_default_description + , COMMAND.can_have_button + , COMMAND.notes + , COMMAND.active + FROM parts.DOG_Command COMMAND + INNER JOIN tmp_Command_Calc_Command t_COMMAND ON COMMAND.id_command = t_COMMAND.id_command + INNER JOIN tmp_Command_Calc_Command_Category t_COMMAND_CATEGORY ON t_COMMAND.id_command_category = t_COMMAND_CATEGORY.id_command_category + ; + COMMIT; + + -- 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_Calc_Command t_ERROR + INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type + ; + + IF a_debug = 1 AND v_can_view = 1 THEN + SELECT * FROM tmp_Command_Calc_Command; + END IF; + + DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name_Calc_Command; + DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id_Calc_Command; + DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error_Calc_Command; + DROP TEMPORARY TABLE IF EXISTS tmp_Command_Calc_Command; + + IF a_debug = 1 THEN + CALL parts.p_core_debug_timing_reporting ( v_time_start ); + END IF; +END // +DELIMITER ; + + +/* + + +CALL parts.p_dog_calc_command ( + 'slips ' -- a_guid + , 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user + , 1 -- a_get_all_command_category + , 0 -- a_get_inactive_command_category + , '' -- a_ids_command_category + , '' -- a_names_command_category + , 1 -- a_get_all_command + , 0 -- a_get_inactive_command + , '' -- a_ids_command + , '' -- a_names_command + , 1 -- a_show_errors + , 1 -- a_debug +); + +SELECT * +FROM parts.DOG_Command_Temp +; + +CALL parts.p_dog_clear_calc_command ( + 'slips ' -- a_guid + , 1 -- debug +); + +*/ \ No newline at end of file diff --git a/static/MySQL/71104_p_dog_clear_calc_command.sql b/static/MySQL/71104_p_dog_clear_calc_command.sql new file mode 100644 index 0000000..25875a3 --- /dev/null +++ b/static/MySQL/71104_p_dog_clear_calc_command.sql @@ -0,0 +1,45 @@ + +USE parts; + +DROP PROCEDURE IF EXISTS parts.p_dog_clear_calc_command; +DROP PROCEDURE IF EXISTS parts.p_command_clear_calc_command; + +DELIMITER // +CREATE PROCEDURE parts.p_dog_clear_calc_command ( + IN a_guid BINARY(36) + , IN a_debug BIT +) +BEGIN + DECLARE v_time_start TIMESTAMP(6); + SET v_time_start := CURRENT_TIMESTAMP(6); + + CALL parts.p_core_validate_guid ( a_guid ); + + START TRANSACTION; + + DELETE COMMAND_T + FROM parts.DOG_Command_Temp COMMAND_T + WHERE COMMAND_T.GUID = a_guid + ; + + COMMIT; + + IF a_debug = 1 THEN + CALL parts.p_debug_timing_reporting( v_time_start ); + END IF; +END // +DELIMITER ; + +/* + +CALL parts.p_dog_clear_calc_command ( + 'crips ' -- a_guid + , 1 -- debug +); + +SELECT * +FROM parts.DOG_Calc_User_Temp +WHERE GUID = 'chips ' +; + +*/ diff --git a/static/MySQL/71104_p_dog_get_many_command.sql b/static/MySQL/71104_p_dog_get_many_command.sql index 5d77e22..5d5ff71 100644 --- a/static/MySQL/71104_p_dog_get_many_command.sql +++ b/static/MySQL/71104_p_dog_get_many_command.sql @@ -1,29 +1,37 @@ USE parts; -DROP PROCEDURE IF EXISTS parts.p_DOG_get_many_command; +DROP PROCEDURE IF EXISTS parts.p_dog_get_many_command; DELIMITER // -CREATE PROCEDURE parts.p_DOG_get_many_command ( +CREATE PROCEDURE parts.p_dog_get_many_command ( IN a_id_user INT + , IN a_get_all_command_category BIT + , IN a_get_inactive_command_category BIT + , IN a_ids_command_category TEXT + , IN a_names_command_category TEXT , IN a_get_all_command BIT , IN a_get_inactive_command BIT , IN a_ids_command TEXT , IN a_names_command TEXT + , IN a_output_command_categories BIT + , IN a_output_commands 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_id_type_error_bad_data INT; - DECLARE v_id_type_error_no_permission INT; + DECLARE v_guid BINARY(36); DECLARE v_has_filter_command_id BIT; DECLARE v_has_filter_command_name BIT; - DECLARE v_guid BINARY(36); - DECLARE v_id_permission_command_view INT; + DECLARE v_has_filter_command_category_id BIT; + DECLARE v_has_filter_command_category_name BIT; 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); - DECLARE v_can_view BIT; DECLARE exit handler for SQLEXCEPTION BEGIN @@ -78,22 +86,36 @@ BEGIN SET v_code_type_error_no_permission := 'NO_PERMISSION'; SET v_id_type_error_bad_data := (SELECT ERROR_TYPE.id_type FROM parts.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 parts.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 parts.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); + SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM parts.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); SET a_id_user := IFNULL(a_id_user, 0); + /* + SET a_get_all_command_category := IFNULL(a_get_all_command_category, 0); + SET a_get_inactive_command_category := IFNULL(a_get_inactive_command_category, 0); + SET a_ids_command_category := TRIM(IFNULL(a_ids_command_category, '')); + SET a_names_command_category := TRIM(IFNULL(a_names_command_category, '')); SET a_get_all_command := IFNULL(a_get_all_command, 0); SET a_get_inactive_command := IFNULL(a_get_inactive_command, 0); SET a_ids_command := TRIM(IFNULL(a_ids_command, '')); SET a_names_command := TRIM(IFNULL(a_names_command, '')); + */ + SET a_output_command_categories := IFNULL(a_output_command_categories, 0); + SET a_output_commands := IFNULL(a_output_commands, 0); SET a_debug := IFNULL(a_debug, 0); IF a_debug = 1 THEN SELECT a_id_user + , a_get_all_command_category + , a_get_inactive_command_category + , a_ids_command_category + , a_names_command_category , a_get_all_command , a_get_inactive_command , a_ids_command , a_names_command + , a_output_command_categories + , a_output_commands , a_debug ; @@ -101,19 +123,30 @@ 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_time_start ; END IF; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; DROP TEMPORARY TABLE IF EXISTS tmp_Command; + DROP TEMPORARY TABLE IF EXISTS tmp_Command_Category; + + CREATE TEMPORARY TABLE tmp_Command_Category ( + id_command_category INT NOT NULL + , code VARCHAR(100) + , name VARCHAR(250) + , active BIT + ); CREATE TEMPORARY TABLE tmp_Command ( id_command INT NOT NULL + , id_command_category INT NOT NULL , name VARCHAR(250) + , hand_signal_default_description TEXT + , can_have_button BIT + , notes TEXT + , active BIT ); CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error ( @@ -121,147 +154,24 @@ BEGIN , id_type INT NULL , code VARCHAR(100) NOT NULL , msg VARCHAR(4000) NOT NULL - ); + ); - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Id ( - substring VARCHAR(4000) NOT NULL - , as_int INT NULL - ); - DELETE FROM tmp_Split_Id; - - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Name ( - substring VARCHAR(4000) NOT NULL - , as_int INT NULL - ); - DELETE FROM tmp_Split_Name; - - CALL parts.p_core_validate_guid ( v_guid ); - - SET v_has_filter_command_id = CASE WHEN a_ids_command = '' THEN 0 ELSE 1 END; - SET v_has_filter_command_name = CASE WHEN a_names_command = '' THEN 0 ELSE 1 END; - - -- Commands - IF v_has_filter_command_id = 1 THEN - CALL parts.p_split(v_guid, a_ids_command, ',', a_debug); - - INSERT INTO tmp_Split_Id ( - substring - , as_int - ) - SELECT - SPLIT_T.substring - , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int - FROM parts.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = v_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; - - CALL parts.p_clear_split_temp( v_guid ); - END IF; - - IF v_has_filter_command_name = 1 THEN - CALL parts.p_split(v_guid, a_names_command, ',', a_debug); - - INSERT INTO tmp_Split_Name ( - substring - , as_int - ) - SELECT - SPLIT_T.substring - , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int - FROM parts.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = v_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; - - CALL parts.p_clear_split_temp( v_guid ); - END IF; - - IF NOT EXISTS (SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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 t_SPLIT_ID - LEFT JOIN parts.DOG_Command COMMAND ON t_SPLIT_ID.as_int = COMMAND.id_command - WHERE - ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(COMMAND.id_command) - OR ( - COMMAND.active = 0 - AND a_get_inactive_command = 0 - ) - ) THEN - INSERT INTO tmp_Msg_Error ( - id_type - , code - , msg - ) - SELECT - v_id_type_error_bad_data - , v_code_type_error_bad_data - , CONCAT('Invalid or inactive Command IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT_ID.substring SEPARATOR ', '), 'NULL')) - FROM tmp_Split_Id t_SPLIT_ID - LEFT JOIN parts.DOG_Command COMMAND ON t_SPLIT_ID.as_int = COMMAND.id_command - WHERE - ISNULL(t_SPLIT_ID.as_int) - OR ISNULL(COMMAND.id_command) - OR ( - COMMAND.active = 0 - AND a_get_inactive_command = 0 - ) - ; - /* Don't error on codes or names not found - ELSEIF EXISTS ( - SELECT * - */ - ELSE - INSERT INTO tmp_Command ( - id_command - , name - ) - SELECT - COMMAND.id_command - , COMMAND.name - FROM parts.DOG_Command COMMAND - LEFT JOIN tmp_Split_Id t_SPLIT_ID ON COMMAND.id_command = t_SPLIT_ID.as_int - LEFT JOIN tmp_Split_Name t_SPLIT_NAME ON COMMAND.name = t_SPLIT_NAME.substring - WHERE - ( - a_get_all_command = 1 - OR ( - v_has_filter_command_id = 1 - OR v_has_filter_command_name = 1 - ) - ) - AND ( - a_get_inactive_command = 1 - OR COMMAND.active = 1 - ) - ; - END IF; - END IF; - - DELETE FROM tmp_Split_Id; - DELETE FROM tmp_Split_Name; - - -- Permissions IF a_debug = 1 THEN SELECT v_guid , a_id_user , FALSE -- a_get_inactive_user - , v_id_permission_command_view + , v_id_permission_dog_view , 0 -- a_debug ; END IF; - CALL parts.p_DOG_calc_user( + CALL parts.p_dog_calc_user( v_guid , a_id_user , FALSE -- a_get_inactive_user - , v_id_permission_command_view + , v_id_permission_dog_view , 0 -- a_debug ); @@ -276,6 +186,8 @@ BEGIN 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 @@ -296,33 +208,126 @@ BEGIN ; END IF; - CALL parts.p_DOG_clear_calc_user( + CALL parts.p_dog_clear_calc_user( v_guid , 0 -- a_debug ); + + -- Call Command Calc + IF NOT EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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_command_category + , a_get_inactive_command_category + , a_ids_command_category + , a_names_command_category + , a_get_all_command -- a_get_all_command + , a_get_inactive_command -- a_get_inactive_command + , a_ids_command -- a_ids_command + , a_names_command -- a_names_command + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL parts.p_dog_calc_command ( + v_guid -- a_guid + , a_id_user -- a_id_user + , a_get_all_command_category + , a_get_inactive_command_category + , a_ids_command_category + , a_names_command_category + , a_get_all_command -- a_get_all_command + , a_get_inactive_command -- a_get_inactive_command + , a_ids_command -- a_ids_command + , a_names_command -- a_names_command + , 0 -- a_show_errors + , 0 -- a_debug + ); + + INSERT INTO tmp_Command_Category ( + id_command_category + , code + , name + , active + ) + SELECT + COMMAND_CATEGORY_T.id_command_category + , COMMAND_CATEGORY_T.code + , COMMAND_CATEGORY_T.name + , COMMAND_CATEGORY_T.active + FROM parts.DOG_Command_Category_Temp COMMAND_CATEGORY_T + WHERE COMMAND_CATEGORY_T.GUID = v_guid + ; + + INSERT INTO tmp_Command ( + id_command + , id_command_category + , name + , hand_signal_default_description + , can_have_button + , notes + , active + ) + SELECT + COMMAND_T.id_command + , COMMAND_T.id_command_category + , COMMAND_T.name + , COMMAND_T.hand_signal_default_description + , COMMAND_T.can_have_button + , COMMAND_T.notes + , COMMAND_T.active + FROM parts.DOG_Command_Temp COMMAND_T + WHERE COMMAND_T.GUID = v_guid + ; + + IF a_debug = 1 THEN + SELECT * FROM tmp_Command_Category; + SELECT * FROM tmp_Command; + END IF; + END IF; + + -- Filter outputs IF EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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_Command_Category; SELECT * FROM tmp_Command; END IF; DELETE FROM tmp_Command; + DELETE FROM tmp_Command_Category; END IF; + -- Outputs + -- Command Categories + IF a_output_command_categories = 1 THEN + SELECT + t_COMMAND_CATEGORY.id_command_category + , t_COMMAND_CATEGORY.code + , t_COMMAND_CATEGORY.name + , t_COMMAND_CATEGORY.active + FROM tmp_Command_Category t_COMMAND_CATEGORY + ; + END IF; + -- Commands - SELECT - t_COMMAND.id_command - , COMMAND.id_command_category - , t_COMMAND.name - , COMMAND.hand_signal_default_description - , COMMAND.can_have_button - , COMMAND.notes - , COMMAND.active - FROM parts.DOG_Command COMMAND - INNER JOIN tmp_Command t_COMMAND ON COMMAND.id_command = t_COMMAND.id_command - ; - + IF a_output_commands = 1 THEN + SELECT + t_COMMAND.id_command + , t_COMMAND.id_command_category + , t_COMMAND.name + , t_COMMAND.hand_signal_default_description + , t_COMMAND.can_have_button + , t_COMMAND.notes + , t_COMMAND.active + FROM tmp_Command t_COMMAND + ; + END IF; + -- Errors SELECT t_ERROR.id_error @@ -341,11 +346,15 @@ BEGIN IF a_debug = 1 AND v_can_view = 1 THEN SELECT * FROM tmp_Command; END IF; + + CALL parts.p_dog_clear_calc_dog( + v_guid -- a_guid + , 0 -- a_debug + ); - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name; - DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; DROP TEMPORARY TABLE IF EXISTS tmp_Command; + DROP TEMPORARY TABLE IF EXISTS tmp_Command_Category; IF a_debug = 1 THEN CALL parts.p_core_debug_timing_reporting ( v_time_start ); @@ -356,12 +365,18 @@ DELIMITER ; /* -CALL parts.p_DOG_get_many_command ( +CALL parts.p_dog_get_many_command ( 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user + , 1 -- a_get_all_command_category + , 0 -- a_get_inactive_command_category + , '' -- a_ids_command_category + , '' -- a_names_command_category , 1 -- a_get_all_command , 0 -- a_get_inactive_command , '' -- a_ids_command , '' -- a_names_command + , 1 -- a_output_command_categories + , 1 -- a_output_commands , 1 -- a_debug ); diff --git a/static/MySQL/71108_p_dog_get_many_dog_command_link.sql b/static/MySQL/71108_p_dog_get_many_dog_command_link.sql index 8823b57..8533414 100644 --- a/static/MySQL/71108_p_dog_get_many_dog_command_link.sql +++ b/static/MySQL/71108_p_dog_get_many_dog_command_link.sql @@ -1,26 +1,33 @@ USE parts; -DROP PROCEDURE IF EXISTS parts.p_DOG_get_many_dog_command; -DROP PROCEDURE IF EXISTS parts.p_DOG_get_many_dog_command_link; +DROP PROCEDURE IF EXISTS parts.p_dog_get_many_dog_command; +DROP PROCEDURE IF EXISTS parts.p_dog_get_many_dog_command_link; DELIMITER // -CREATE PROCEDURE parts.p_DOG_get_many_dog_command_link ( +CREATE PROCEDURE parts.p_dog_get_many_dog_command_link ( 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 + , IN a_get_all_command_category BIT + , IN a_get_inactive_command_category BIT + , IN a_ids_command_category TEXT + , IN a_names_command_category TEXT , IN a_get_all_command BIT , IN a_get_inactive_command BIT , IN a_ids_command TEXT + , IN a_names_command TEXT , IN a_debug BIT ) BEGIN DECLARE v_code_type_error_bad_data VARCHAR(100); DECLARE v_code_type_error_no_permission VARCHAR(100); + DECLARE v_code_type_error_warning VARCHAR(100); DECLARE v_id_type_error_bad_data INT; DECLARE v_id_type_error_no_permission INT; - DECLARE v_has_filter_command BIT; + DECLARE v_id_type_error_warning INT; DECLARE v_has_filter_dog BIT; DECLARE v_guid BINARY(36); DECLARE v_id_permission_dog_view INT; @@ -79,17 +86,22 @@ BEGIN SET v_guid := UUID(); SET v_code_type_error_bad_data := 'BAD_DATA'; SET v_code_type_error_no_permission := 'NO_PERMISSION'; + SET v_code_type_error_warning := 'WARNING'; SET v_id_type_error_bad_data := (SELECT ERROR_TYPE.id_type FROM parts.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 parts.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_no_permission LIMIT 1); + SET v_id_type_error_warning := (SELECT ERROR_TYPE.id_type FROM parts.CORE_Msg_Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = v_code_type_error_warning LIMIT 1); SET v_id_permission_dog_view := (SELECT PERMISSION.id_permission FROM parts.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); 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_get_all_command := IFNULL(a_get_all_command, 0); - SET a_get_inactive_command := IFNULL(a_get_inactive_command, 0); - SET a_ids_command := TRIM(IFNULL(a_ids_command, '')); + -- 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_get_all_command_category := IFNULL(a_get_all_command_category, 0); + -- SET a_get_inactive_command_category := IFNULL(a_get_inactive_command_category, 0); + -- SET a_ids_command_category := TRIM(IFNULL(a_ids_command_category, '')); + -- SET a_get_all_command := IFNULL(a_get_all_command, 0); + -- SET a_get_inactive_command := IFNULL(a_get_inactive_command, 0); + -- SET a_ids_command := TRIM(IFNULL(a_ids_command, '')); SET a_debug := IFNULL(a_debug, 0); IF a_debug = 1 THEN @@ -98,15 +110,22 @@ BEGIN , a_get_all_dog , a_get_inactive_dog , a_ids_dog + , a_names_dog + , a_get_all_command_category + , a_get_inactive_command_category + , a_ids_command_category + , a_names_command_category , a_get_all_command , a_get_inactive_command , a_ids_command + , a_names_command , a_debug ; SELECT v_id_type_error_bad_data , v_id_type_error_no_permission + , v_id_type_error_warning , v_guid , v_id_permission_dog_view , v_time_start @@ -116,20 +135,33 @@ BEGIN DROP TEMPORARY TABLE IF EXISTS tmp_Split; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; DROP TEMPORARY TABLE IF EXISTS tmp_Command; + DROP TEMPORARY TABLE IF EXISTS tmp_Command_Category; DROP TEMPORARY TABLE IF EXISTS tmp_Dog; CREATE TEMPORARY TABLE tmp_Dog ( id_dog INT NOT NULL , name VARCHAR(250) + , appearance VARCHAR(1000) + , mass_kg DECIMAL(7, 3) + , notes TEXT + , active BIT + ); + + CREATE TEMPORARY TABLE tmp_Command_Category ( + id_command_category INT NOT NULL + , code VARCHAR(100) + , name VARCHAR(250) + , active BIT ); CREATE TEMPORARY TABLE tmp_Command ( id_command INT NOT NULL - , id_command_category INT NOT NULL - , name_command_category VARCHAR(250) - -- , code VARCHAR(100) + , id_command_category INT NOT NULL , name VARCHAR(250) - , has_button BIT + , hand_signal_default_description TEXT + , can_have_button BIT + , notes TEXT + , active BIT ); CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error ( @@ -139,190 +171,6 @@ BEGIN , msg VARCHAR(4000) NOT NULL ); - CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split ( - substring VARCHAR(4000) NOT NULL - , as_int INT NULL - ); - DELETE FROM tmp_Split; - - CALL parts.p_core_validate_guid ( v_guid ); - - SET v_has_filter_dog = CASE WHEN a_ids_dog = '' THEN 0 ELSE 1 END; - SET v_has_filter_command = CASE WHEN a_ids_command = '' THEN 0 ELSE 1 END; - - -- Dogs - IF v_has_filter_dog = 1 THEN - CALL parts.p_split(v_guid, a_ids_dog, ',', a_debug); - - INSERT INTO tmp_Split ( - substring - , as_int - ) - SELECT - SPLIT_T.substring - , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int - FROM parts.CORE_Split_Temp SPLIT_T - WHERE - SPLIT_T.GUID = v_guid - AND IFNULL(SPLIT_T.substring, '') <> '' - ; - - CALL parts.p_clear_split_temp( v_guid ); - END IF; - - IF NOT EXISTS (SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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 t_SPLIT - LEFT JOIN parts.DOG_Dog DOG ON t_SPLIT.as_int = DOG.id_dog - WHERE - ISNULL(t_SPLIT.as_int) - OR ISNULL(DOG.id_dog) - OR ( - DOG.active = 0 - AND a_get_inactive_dog = 0 - ) - ) THEN - INSERT INTO tmp_Msg_Error ( - 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.substring SEPARATOR ', '), 'NULL')) - FROM tmp_Split t_SPLIT - LEFT JOIN parts.DOG_Dog DOG ON t_SPLIT.as_int = DOG.id_dog - WHERE - ISNULL(t_SPLIT.as_int) - OR ISNULL(DOG.id_dog) - OR ( - DOG.active = 0 - AND a_get_inactive_dog = 0 - ) - ; - ELSE - INSERT INTO tmp_Dog ( - id_dog - , name - ) - SELECT - DOG.id_dog - , DOG.name - FROM tmp_Split t_SPLIT - RIGHT JOIN parts.DOG_Dog DOG ON t_SPLIT.as_int = DOG.id_dog - WHERE - ( - a_get_all_dog = 1 - OR ( - v_has_filter_dog = 1 - AND NOT ISNULL(t_SPLIT.as_int) - ) - ) - AND ( - a_get_inactive_dog = 1 - OR DOG.active = 1 - ) - ; - END IF; - END IF; - - DELETE FROM tmp_Split; - - -- Commands - IF v_has_filter_command = 1 THEN - CALL parts.p_split(v_guid, a_ids_command, ',', a_debug); - - INSERT INTO tmp_Split ( - substring - , as_int - ) - SELECT - substring - , CONVERT(substring, DECIMAL(10,0)) AS as_int - FROM parts.CORE_Split_Temp - WHERE - GUID = v_guid - AND NOT ISNULL(substring) - AND substring <> '' - ; - - CALL parts.p_clear_split_temp( v_guid ); - END IF; - - IF NOT EXISTS (SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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 t_SPLIT - LEFT JOIN parts.DOG_Command COMMAND ON t_SPLIT.as_int = COMMAND.id_command - WHERE - ISNULL(t_SPLIT.as_int) - OR ISNULL(COMMAND.id_command) - OR ( - COMMAND.active = 0 - AND a_get_inactive_command = 0 - ) - ) THEN - INSERT INTO tmp_Msg_Error ( - id_type - , code - , msg - ) - SELECT - v_id_type_error_bad_data - , v_code_type_error_bad_data - , CONCAT('Invalid or inactive Command IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT.substring SEPARATOR ', '), 'NULL')) - FROM tmp_Split t_SPLIT - LEFT JOIN parts.DOG_Command COMMAND ON t_SPLIT.as_int = COMMAND.id_command - WHERE - ISNULL(t_SPLIT.as_int) - OR ISNULL(COMMAND.id_command) - OR ( - COMMAND.active = 0 - AND a_get_inactive_command = 0 - ) - ; - ELSE - INSERT INTO tmp_Command ( - id_command - , id_command_category - , name_command_category - , name - , has_button - ) - SELECT - COMMAND.id_command - , COMMAND.id_command_category - , COMMAND_CATEGORY.name AS name_command_category - -- , COMMAND.code - , COMMAND.name - , CASE WHEN ISNULL(COMMANDS_WITH_BUTTONS.id_command) THEN 0 ELSE 1 END AS has_button - FROM tmp_Split t_SPLIT - RIGHT JOIN parts.DOG_Command COMMAND ON t_SPLIT.as_int = COMMAND.id_command - LEFT JOIN parts.DOG_Command_Category COMMAND_CATEGORY ON COMMAND.id_command_category = COMMAND_CATEGORY.id_command_category - LEFT JOIN ( - SELECT DISTINCT COMMAND_BUTTON_LINK.id_command - FROM parts.DOG_Command_Button_Link COMMAND_BUTTON_LINK - ) COMMANDS_WITH_BUTTONS ON COMMAND.id_command = COMMANDS_WITH_BUTTONS.id_command - WHERE - ( - a_get_all_command = 1 - OR ( - v_has_filter_command = 1 - AND NOT ISNULL(t_SPLIT.as_int) - ) - ) - AND ( - a_get_inactive_command = 1 - OR COMMAND.active = 1 - ) - ; - END IF; - END IF; - - DELETE FROM tmp_Split; - -- Permissions IF a_debug = 1 THEN @@ -335,11 +183,11 @@ BEGIN ; END IF; - CALL parts.p_DOG_calc_user( - v_guid - , a_id_user + CALL parts.p_dog_calc_user( + v_guid -- a_guid + , a_id_user -- a_ids_user , FALSE -- a_get_inactive_user - , v_id_permission_dog_view + , v_id_permission_dog_view -- a_ids_permission , 0 -- a_debug ); @@ -369,24 +217,154 @@ BEGIN VALUES ( v_id_type_error_no_permission , v_code_type_error_no_permission - , 'You do not have permission to view Commands.' + , 'You do not have permission to view Dogs and Commands.' ) ; END IF; - CALL parts.p_DOG_clear_calc_user( + CALL parts.p_dog_clear_calc_user( v_guid , 0 -- a_debug ); + -- Call Dog Calc + IF NOT EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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_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 + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL parts.p_dog_calc_dog( + v_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 + , 0 -- a_show_errors + , 0 -- a_debug + ); + + INSERT INTO tmp_Dog ( + id_dog + , name + , appearance + , mass_kg + , notes + , active + ) + SELECT + DOG_T.id_dog + , DOG_T.name + , DOG_T.appearance + , DOG_T.mass_kg + , DOG_T.notes + , DOG_T.active + FROM parts.DOG_Dog_Temp DOG_T + WHERE DOG_T.GUID = v_guid + ; + + IF a_debug = 1 THEN + SELECT * FROM tmp_Dog; + END IF; + END IF; + + -- Call Command Calc + IF NOT EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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_command_category + , a_get_inactive_command_category + , a_ids_command_category + , a_names_command_category + , a_get_all_command -- a_get_all_command + , a_get_inactive_command -- a_get_inactive_command + , a_ids_command -- a_ids_command + , a_names_command -- a_names_command + , 0 -- a_show_errors + , 0 -- a_debug + ; + END IF; + + CALL parts.p_dog_calc_command ( + v_guid -- a_guid + , a_id_user -- a_id_user + , a_get_all_command_category + , a_get_inactive_command_category + , a_ids_command_category + , a_names_command_category + , a_get_all_command -- a_get_all_command + , a_get_inactive_command -- a_get_inactive_command + , a_ids_command -- a_ids_command + , a_names_command -- a_names_command + , 0 -- a_show_errors + , 0 -- a_debug + ); + + INSERT INTO tmp_Command_Category ( + id_command_category + , code + , name + , active + ) + SELECT + COMMAND_CATEGORY_T.id_command_category + , COMMAND_CATEGORY_T.code + , COMMAND_CATEGORY_T.name + , COMMAND_CATEGORY_T.active + FROM parts.DOG_Command_Category_Temp COMMAND_CATEGORY_T + WHERE COMMAND_CATEGORY_T.GUID = v_guid + ; + + INSERT INTO tmp_Command ( + id_command + , id_command_category + , name + , hand_signal_default_description + , can_have_button + , notes + , active + ) + SELECT + COMMAND_T.id_command + , COMMAND_T.id_command_category + , COMMAND_T.name + , COMMAND_T.hand_signal_default_description + , COMMAND_T.can_have_button + , COMMAND_T.notes + , COMMAND_T.active + FROM parts.DOG_Command_Temp COMMAND_T + WHERE COMMAND_T.GUID = v_guid + ; + + IF a_debug = 1 THEN + SELECT * FROM tmp_Command_Category; + SELECT * FROM tmp_Command; + END IF; + END IF; + + + -- Filter outputs IF EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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; SELECT * FROM tmp_Command; + SELECT * FROM tmp_Command_Category; END IF; DELETE FROM tmp_Dog; DELETE FROM tmp_Command; + DELETE FROM tmp_Command_Category; END IF; -- Outputs @@ -396,17 +374,18 @@ BEGIN , t_DOG.id_dog , t_DOG.name AS name_dog , t_COMMAND.id_command_category - , t_COMMAND.name_command_category + , t_COMMAND_CATEGORY.name AS name_command_category , t_COMMAND.id_command - -- , t_COMMAND.code , t_COMMAND.name AS name_command - , t_COMMAND.has_button AS command_has_button - , DOG_COMMAND_LINK.hand_signal_description + -- , t_COMMAND.has_button AS command_has_button + , COALESCE(DOG_COMMAND_LINK.hand_signal_description, t_COMMAND.hand_signal_default_description) AS hand_signal_description_command + , t_COMMAND.can_have_button AS can_have_button_command , DOG_COMMAND_LINK.notes , DOG_COMMAND_LINK.active FROM parts.DOG_Dog_Command_Link DOG_COMMAND_LINK INNER JOIN tmp_Dog t_DOG ON DOG_COMMAND_LINK.id_dog = t_DOG.id_dog INNER JOIN tmp_Command t_COMMAND ON DOG_COMMAND_LINK.id_command = t_COMMAND.id_command + INNER JOIN tmp_Command_Category t_COMMAND_CATEGORY ON t_COMMAND.id_command_category = t_COMMAND_CATEGORY.id_command_category ; -- Errors @@ -427,11 +406,13 @@ BEGIN IF a_debug = 1 AND v_can_view = 1 THEN SELECT * FROM tmp_Dog; SELECT * FROM tmp_Command; + SELECT * FROM tmp_Command_Category; END IF; DROP TEMPORARY TABLE IF EXISTS tmp_Split; DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; DROP TEMPORARY TABLE IF EXISTS tmp_Command; + DROP TEMPORARY TABLE IF EXISTS tmp_Command_Category; DROP TEMPORARY TABLE IF EXISTS tmp_Dog; IF a_debug = 1 THEN @@ -443,15 +424,35 @@ DELIMITER ; /* -CALL parts.p_DOG_get_many_dog_command_link ( +CALL parts.p_dog_get_many_dog_command_link ( 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user , 1 -- a_get_all_dog , 0 -- a_get_inactive_dog , '' -- a_ids_dog + , 1 -- a_get_all_command_category + , 0 -- a_get_inactive_command_category + , '' -- a_ids_command_category , 1 -- a_get_all_command , 0 -- a_get_inactive_command , '' -- a_ids_command , 1 -- a_debug ); +CALL parts.p_dog_get_many_dog_command_link ( + 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user + , 1 -- a_get_all_dog + , 0 -- a_get_inactive_dog + , '' -- a_ids_dog + , '' -- a_names_dog + , 1 -- a_get_all_command_category + , 0 -- a_get_inactive_command_category + , '' -- a_ids_command_category + , '' -- a_names_command_category + , 0 -- a_get_all_command + , 0 -- a_get_inactive_command + , '2' -- a_ids_command + , '2' -- a_names_command + , 1 -- a_debug +); + */ \ No newline at end of file diff --git a/static/MySQL/90000_populate.sql b/static/MySQL/90000_populate.sql index e67e718..8dfa7be 100644 --- a/static/MySQL/90000_populate.sql +++ b/static/MySQL/90000_populate.sql @@ -111,7 +111,7 @@ VALUES , 'DOG_VIEW' , 'View Dog' , 1 - , 3 + , 1 ) , ( 1 @@ -125,8 +125,29 @@ VALUES , 'DOG_CREATE' , 'Create Dog' , 1 + , 2 + ) + , ( + 1 + , 'USER_VIEW' + , 'View User' + , 2 , 1 ) + , ( + 1 + , 'USER_ADMIN' + , 'Admin User' + , 2 + , 3 + ) + , ( + 1 + , 'USER_CREATE' + , 'Create User' + , 2 + , 2 + ) ; -- Users @@ -212,6 +233,24 @@ VALUES , 3 , 3 , 1 + ) + , ( + 1 + , 4 + , 3 + , 1 + ) + , ( + 1 + , 5 + , 3 + , 1 + ) + , ( + 1 + , 6 + , 3 + , 1 ) , ( 2 @@ -231,6 +270,24 @@ VALUES , 1 , 1 ) + , ( + 2 + , 4 + , 1 + , 1 + ) + , ( + 2 + , 5 + , 1 + , 1 + ) + , ( + 2 + , 6 + , 1 + , 1 + ) ; -- User Role link @@ -1018,7 +1075,7 @@ VALUES SELECT COUNT(*) FROM parts.DOG_Command_Temp; -CALL parts.p_DOG_save_command ( +CALL parts.p_dog_save_command ( 'nipples' , (SELECT GUID FROM parts.DOG_Command_Temp COMMAND_TEMP ORDER BY id_temp DESC LIMIT 1) , 1 diff --git a/static/MySQL/deprecated/71104_p_dog_get_many_command.sql b/static/MySQL/deprecated/71104_p_dog_get_many_command.sql new file mode 100644 index 0000000..8093e4a --- /dev/null +++ b/static/MySQL/deprecated/71104_p_dog_get_many_command.sql @@ -0,0 +1,368 @@ + +USE parts; + +DROP PROCEDURE IF EXISTS parts.p_dog_get_many_command; + +DELIMITER // +CREATE PROCEDURE parts.p_dog_get_many_command ( + IN a_id_user INT + , IN a_get_all_command BIT + , IN a_get_inactive_command BIT + , IN a_ids_command TEXT + , IN a_names_command TEXT + , IN a_debug BIT +) +BEGIN + DECLARE v_code_type_error_bad_data VARCHAR(100); + DECLARE v_code_type_error_no_permission VARCHAR(100); + DECLARE v_id_type_error_bad_data INT; + DECLARE v_id_type_error_no_permission INT; + DECLARE v_has_filter_command_id BIT; + DECLARE v_has_filter_command_name BIT; + DECLARE v_guid BINARY(36); + DECLARE v_id_permission_command_view INT; + DECLARE v_id_minimum INT; + DECLARE v_time_start TIMESTAMP(6); + DECLARE v_can_view BIT; + + DECLARE exit handler for SQLEXCEPTION + BEGIN + GET DIAGNOSTICS CONDITION 1 + @sqlstate = RETURNED_SQLSTATE + , @errno = MYSQL_ERRNO + , @text = MESSAGE_TEXT + ; + + ROLLBACK; + + CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error ( + id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT + , id_type INT NULL + , code VARCHAR(100) NOT NULL + , msg VARCHAR(4000) NOT NULL + ); + + INSERT INTO tmp_Msg_Error ( + id_type + , code + , msg + ) + SELECT + MET.id_type + , @errno + , @text + FROM parts.CORE_Msg_Error_Type MET + 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 t_ERROR + INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type + ; + + 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 parts.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 parts.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 parts.DOG_Permission PERMISSION WHERE PERMISSION.code = 'DOG_VIEW' LIMIT 1); + + SET a_id_user := IFNULL(a_id_user, 0); + SET a_get_all_command := IFNULL(a_get_all_command, 0); + SET a_get_inactive_command := IFNULL(a_get_inactive_command, 0); + SET a_ids_command := TRIM(IFNULL(a_ids_command, '')); + SET a_names_command := TRIM(IFNULL(a_names_command, '')); + SET a_debug := IFNULL(a_debug, 0); + + IF a_debug = 1 THEN + SELECT + a_id_user + , a_get_all_command + , a_get_inactive_command + , a_ids_command + , a_names_command + , a_debug + ; + + SELECT + v_id_type_error_bad_data + , v_id_type_error_no_permission + , v_guid + , v_id_permission_command_view + , v_time_start + ; + END IF; + + DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name; + DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id; + DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; + DROP TEMPORARY TABLE IF EXISTS tmp_Command; + + CREATE TEMPORARY TABLE tmp_Command ( + id_command INT NOT NULL + , name VARCHAR(250) + ); + + CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error ( + id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT + , id_type INT NULL + , code VARCHAR(100) NOT NULL + , msg VARCHAR(4000) NOT NULL + ); + + CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Id ( + substring VARCHAR(4000) NOT NULL + , as_int INT NULL + ); + DELETE FROM tmp_Split_Id; + + CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Split_Name ( + substring VARCHAR(4000) NOT NULL + , as_int INT NULL + ); + DELETE FROM tmp_Split_Name; + + CALL parts.p_core_validate_guid ( v_guid ); + + SET v_has_filter_command_id = CASE WHEN a_ids_command = '' THEN 0 ELSE 1 END; + SET v_has_filter_command_name = CASE WHEN a_names_command = '' THEN 0 ELSE 1 END; + + -- Commands + IF v_has_filter_command_id = 1 THEN + CALL parts.p_core_split(v_guid, a_ids_command, ',', a_debug); + + INSERT INTO tmp_Split_Id ( + substring + , as_int + ) + SELECT + SPLIT_T.substring + , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int + FROM parts.CORE_Split_Temp SPLIT_T + WHERE + SPLIT_T.GUID = v_guid + AND IFNULL(SPLIT_T.substring, '') <> '' + ; + + CALL parts.p_core_clear_split( v_guid ); + END IF; + + IF v_has_filter_command_name = 1 THEN + CALL parts.p_core_split(v_guid, a_names_command, ',', a_debug); + + INSERT INTO tmp_Split_Name ( + substring + , as_int + ) + SELECT + SPLIT_T.substring + , CONVERT(SPLIT_T.substring, DECIMAL(10,0)) AS as_int + FROM parts.CORE_Split_Temp SPLIT_T + WHERE + SPLIT_T.GUID = v_guid + AND IFNULL(SPLIT_T.substring, '') <> '' + ; + + CALL parts.p_core_clear_split( v_guid ); + END IF; + + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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 t_SPLIT_ID + LEFT JOIN parts.DOG_Command COMMAND ON t_SPLIT_ID.as_int = COMMAND.id_command + WHERE + ISNULL(t_SPLIT_ID.as_int) + OR ISNULL(COMMAND.id_command) + OR ( + COMMAND.active = 0 + AND a_get_inactive_command = 0 + ) + ) THEN + INSERT INTO tmp_Msg_Error ( + id_type + , code + , msg + ) + SELECT + v_id_type_error_bad_data + , v_code_type_error_bad_data + , CONCAT('Invalid or inactive Command IDs: ', IFNULL(GROUP_CONCAT(t_SPLIT_ID.substring SEPARATOR ', '), 'NULL')) + FROM tmp_Split_Id t_SPLIT_ID + LEFT JOIN parts.DOG_Command COMMAND ON t_SPLIT_ID.as_int = COMMAND.id_command + WHERE + ISNULL(t_SPLIT_ID.as_int) + OR ISNULL(COMMAND.id_command) + OR ( + COMMAND.active = 0 + AND a_get_inactive_command = 0 + ) + ; + /* Don't error on codes or names not found + ELSEIF EXISTS ( + SELECT * + */ + ELSE + INSERT INTO tmp_Command ( + id_command + , name + ) + SELECT + COMMAND.id_command + , COMMAND.name + FROM parts.DOG_Command COMMAND + LEFT JOIN tmp_Split_Id t_SPLIT_ID ON COMMAND.id_command = t_SPLIT_ID.as_int + LEFT JOIN tmp_Split_Name t_SPLIT_NAME ON COMMAND.name = t_SPLIT_NAME.substring + WHERE + ( + a_get_all_command = 1 + OR ( + v_has_filter_command_id = 1 + OR v_has_filter_command_name = 1 + ) + ) + AND ( + a_get_inactive_command = 1 + OR COMMAND.active = 1 + ) + ; + END IF; + END IF; + + DELETE FROM tmp_Split_Id; + DELETE FROM tmp_Split_Name; + + + -- Permissions + IF a_debug = 1 THEN + SELECT + v_guid + , a_id_user + , FALSE -- a_get_inactive_user + , v_id_permission_command_view + , 0 -- a_debug + ; + END IF; + + CALL parts.p_dog_calc_user( + v_guid + , a_id_user + , FALSE -- a_get_inactive_user + , v_id_permission_command_view + , 0 -- a_debug + ); + + SELECT + IFNULL(CALC_USER_T.has_access, 0) + INTO + v_can_view + FROM parts.DOG_Calc_User_Temp CALC_USER_T + WHERE CALC_USER_T.GUID = v_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 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 Commands.' + ) + ; + END IF; + + CALL parts.p_dog_clear_calc_user( + v_guid + , 0 -- a_debug + ); + + IF EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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_Command; + END IF; + + DELETE FROM tmp_Command; + END IF; + + -- Outputs + -- Commands + SELECT + t_COMMAND.id_command + , COMMAND.id_command_category + , t_COMMAND.name + , COMMAND.hand_signal_default_description + , COMMAND.can_have_button + , COMMAND.notes + , COMMAND.active + FROM parts.DOG_Command COMMAND + INNER JOIN tmp_Command t_COMMAND ON COMMAND.id_command = t_COMMAND.id_command + ; + + -- 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 parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type + ; + + IF a_debug = 1 AND v_can_view = 1 THEN + SELECT * FROM tmp_Command; + END IF; + + DROP TEMPORARY TABLE IF EXISTS tmp_Split_Name; + DROP TEMPORARY TABLE IF EXISTS tmp_Split_Id; + DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error; + DROP TEMPORARY TABLE IF EXISTS tmp_Command; + + IF a_debug = 1 THEN + CALL parts.p_core_debug_timing_reporting ( v_time_start ); + END IF; +END // +DELIMITER ; + + +/* + +CALL parts.p_dog_get_many_command ( + 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user + , 1 -- a_get_all_command + , 0 -- a_get_inactive_command + , '' -- a_ids_command + , '' -- a_names_command + , 1 -- a_debug +); + +*/ \ No newline at end of file diff --git a/static/MySQL/deprecated/7213_p_dog_get_many_understanding_level.sql b/static/MySQL/deprecated/7213_p_dog_get_many_understanding_level.sql index b07b50c..dc6489c 100644 --- a/static/MySQL/deprecated/7213_p_dog_get_many_understanding_level.sql +++ b/static/MySQL/deprecated/7213_p_dog_get_many_understanding_level.sql @@ -1,10 +1,10 @@ USE parts; -DROP PROCEDURE IF EXISTS parts.p_DOG_get_many_understanding_level; +DROP PROCEDURE IF EXISTS parts.p_dog_get_many_understanding_level; DELIMITER // -CREATE PROCEDURE parts.p_DOG_get_many_understanding_level ( +CREATE PROCEDURE parts.p_dog_get_many_understanding_level ( IN a_id_user INT , IN a_get_all_understanding_level BIT , IN a_get_inactive_understanding_level BIT @@ -155,7 +155,7 @@ BEGIN -- Understanding_Levels IF v_has_filter_understanding_level_id = 1 THEN - CALL parts.p_split(v_guid, a_ids_understanding_level, ',', a_debug); + CALL parts.p_core_split(v_guid, a_ids_understanding_level, ',', a_debug); INSERT INTO tmp_Split_Id ( substring @@ -170,11 +170,11 @@ BEGIN AND IFNULL(SPLIT_T.substring, '') <> '' ; - CALL parts.p_clear_split_temp( v_guid ); + CALL parts.p_core_clear_split( v_guid ); END IF; IF v_has_filter_understanding_level_code = 1 THEN - CALL parts.p_split(v_guid, a_codes_understanding_level, ',', a_debug); + CALL parts.p_core_split(v_guid, a_codes_understanding_level, ',', a_debug); INSERT INTO tmp_Split_Code ( substring @@ -189,11 +189,11 @@ BEGIN AND IFNULL(SPLIT_T.substring, '') <> '' ; - CALL parts.p_clear_split_temp( v_guid ); + CALL parts.p_core_clear_split( v_guid ); END IF; IF v_has_filter_understanding_level_name = 1 THEN - CALL parts.p_split(v_guid, a_names_understanding_level, ',', a_debug); + CALL parts.p_core_split(v_guid, a_names_understanding_level, ',', a_debug); INSERT INTO tmp_Split_Name ( substring @@ -208,7 +208,7 @@ BEGIN AND IFNULL(SPLIT_T.substring, '') <> '' ; - CALL parts.p_clear_split_temp( v_guid ); + CALL parts.p_core_clear_split( v_guid ); END IF; IF NOT EXISTS (SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.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 @@ -294,7 +294,7 @@ BEGIN ; END IF; - CALL parts.p_DOG_calc_user( + CALL parts.p_dog_calc_user( v_guid , a_id_user , FALSE -- a_get_inactive_user @@ -333,7 +333,7 @@ BEGIN ; END IF; - CALL parts.p_DOG_clear_calc_user( + CALL parts.p_dog_clear_calc_user( v_guid , 0 -- a_debug ); @@ -391,7 +391,7 @@ DELIMITER ; /* -CALL parts.p_DOG_get_many_understanding_level ( +CALL parts.p_dog_get_many_understanding_level ( 1 -- 'auth0|6582b95c895d09a70ba10fef', -- a_id_user , 1 -- a_get_all_understanding_level , 0 -- a_get_inactive_understanding_level diff --git a/static/batch/sql_combine.bat b/static/batch/sql_combine.bat index 997fadb..f4bdebf 100644 --- a/static/batch/sql_combine.bat +++ b/static/batch/sql_combine.bat @@ -13,8 +13,8 @@ set "strs_delete_1=910_anal.sql" set "strs_delete_2=deprecated" set "strs_delete_3=%f_list%" set "strs_delete_4=%f_tmp%" -set "strs_delete_5=701_p_shop_get_many_role_permission.sql" -set "strs_delete_6=600_p_shop_save_product.sql" +set "strs_delete_5=701_p_dog_get_many_role_permission.sql" +set "strs_delete_6=600_p_dog_save_product.sql" set "strs_delete_7=170_ish_tbl_ERP_Order.sql" set "strs_delete_7=dump.sql" set strs_n_max=8 diff --git a/static/css/components/button.css b/static/css/components/button.css index fb55ad0..6395d8f 100644 --- a/static/css/components/button.css +++ b/static/css/components/button.css @@ -6,26 +6,33 @@ font-weight: 500; transition: all 0.3s ease; width: fit-content; + cursor: pointer; } .button-primary { - background: var(--primary); + background: var(--colour-primary); color: white; } .button-primary:hover { - background: var(--secondary); + background: var(--colour-secondary); } .button-light { background: white; - color: var(--primary); + color: var(--colour-primary); } .button-light:hover { - background: var(--light); + background: var(--colour-accent); } .logo:hover{ cursor: pointer; +} + + +.button.icon.active.delete, +.button.icon.active.add { + height: 2vh; } \ No newline at end of file diff --git a/static/css/components/card.css b/static/css/components/card.css new file mode 100644 index 0000000..e69de29 diff --git a/static/css/components/dialog.css b/static/css/components/dialog.css new file mode 100644 index 0000000..e69de29 diff --git a/static/css/components/form.css b/static/css/components/form.css new file mode 100644 index 0000000..e69de29 diff --git a/static/css/components/image.css b/static/css/components/image.css new file mode 100644 index 0000000..589ed1c --- /dev/null +++ b/static/css/components/image.css @@ -0,0 +1,4 @@ + +img, video { + border-radius: 3vh; +} diff --git a/static/css/components/label.css b/static/css/components/label.css new file mode 100644 index 0000000..b1c4029 --- /dev/null +++ b/static/css/components/label.css @@ -0,0 +1,26 @@ + +h1 { + font-size: min(24px, calc(1vh * 6)); +} + +h2 { + font-size: min(20px, calc(1vh * 5)); +} + +h3 { + font-size: min(16px, calc(1vh * 4)); + margin-top: 1vh; +} + +h4 { + font-size: 13px; + margin: 1vh; + text-align: center; + margin-left: auto; + margin-right: auto; +} + +h5 { + font-size: 11px; + margin: 1vh; +} diff --git a/static/css/components/modal.css b/static/css/components/modal.css new file mode 100644 index 0000000..e69de29 diff --git a/static/css/components/navigation.css b/static/css/components/navigation.css new file mode 100644 index 0000000..e69de29 diff --git a/static/css/components/overlay.css b/static/css/components/overlay.css new file mode 100644 index 0000000..4450241 --- /dev/null +++ b/static/css/components/overlay.css @@ -0,0 +1,82 @@ + + +/* Overlay modal */ +.overlay { + /* + display: none; + */ + position: fixed; + top: 15vh; + right: 0; + width: 100px; + /* height: 50%; */ + background: var(--colour-page-background); + justify-content: right; + align-items: right; + align-self: right; + z-index: 999; +} +.overlay.expanded { + display: block; +} +.collapsed { + display: none; +} + +/* Hamburger menu overlay */ +#buttonHamburger:hover { + text-decoration: none; +} +#overlayHamburger { + overflow-x: hidden; + overflow-y: auto; + max-height: 80%; +} +.hamburger { + border: 2px solid var(--border-colour); + border-radius: 4px; +} +.hamburger:first-child { + border-top-left-radius: 12px; + border-top-right-radius: 12px; +} +.hamburger:last-child { + border-bottom-left-radius: 12px; + border-bottom-right-radius: 12px; +} + +.hamburger > * { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + text-align: center; + width: 100%; + /* color: var(--colour-text); */ + font-weight: bold; + font-size: 18px; + /* height: 18px; */ +} +.hamburger > :hover { + color: var(--colour-page-background); + background-color: var(--colour-primary); +} +.hamburger > * > * { + width: 100%; + /* + margin-top: 4.5px; + margin-bottom: 4.5px; + */ +} +.hamburger > .container { + padding-top: 4.5px; + padding-bottom: 4.5px; +} + +/* Confirm overlay */ +#overlayConfirm { + position: absolute; + left: 25vw; + width: 50vw; + height: 50vh; +} \ No newline at end of file diff --git a/static/css/components/table.css b/static/css/components/table.css new file mode 100644 index 0000000..5a03bd5 --- /dev/null +++ b/static/css/components/table.css @@ -0,0 +1,60 @@ + +#formFilters .container { + max-width: fit-content; +} + +thead, tbody { + padding-top: 0px !important; + padding-bottom: 0px !important; +} + +th { + background-color: transparent; +} +td { + font-size: min(12px, calc(1vh * 3)); +} + +th, td { + min-width: fit-content; +} +tr:not(:last-child) > td { + border-bottom: 1px dashed var(--border-colour); +} +td > table > tbody > tr > td { + border: none !important; +} +th.collapsed, td.collapsed { + display: table-cell !important; +} +td.dirty { + background-color: var(--colour-primary); +} +td:not(.dirty) { + background-color: transparent; +} + +tr { + min-height: 1px; + border-bottom: 1px solid; + border-top: 1px solid; + border-color: var(--border-colour); + background-color: transparent; +} + +table button { + margin: 0.25vh; + padding: 0.5vh 1vh; +} + +table button.active { + background-color: var(--colour-page-background); +} + +tr.delete, tr.delete > td { + background-color: var(--colour-error); +} + +table div { + align-content: center; +} \ No newline at end of file diff --git a/static/css/layouts/footer.css b/static/css/layouts/footer.css index 7ab4517..b491c24 100644 --- a/static/css/layouts/footer.css +++ b/static/css/layouts/footer.css @@ -1,57 +1,25 @@ +/* Footer */ .footer { - background: #1f2937; - color: #f3f4f6; - padding: 4rem 0 2rem; -} - -.footer-content { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - gap: 2rem; - margin-bottom: 2rem; -} - -.footer-section h3 { - color: #fff; - margin-bottom: 1rem; - font-size: 1.2rem; -} - -.footer-section ul { - list-style: none; - padding: 0; -} - -.footer-section ul li { - margin-bottom: 0.5rem; -} - -.footer-section a { - color: #f3f4f6; - text-decoration: none; - transition: color 0.3s ease; -} - -.footer-section a:hover { - color: #fff; - text-decoration: underline; -} - -.footer-bottom { - border-top: 1px solid #374151; - padding-top: 2rem; + padding: 1vh; + padding-left: 1vw; + padding-right: 1vw; text-align: center; - font-size: 0.9rem; + margin: 0; + height: 8vh !important; + overflow-y: auto; + background-color: var(--colour-accent); + /* + border-top-left-radius: 2.5vh; + border-top-right-radius: 2.5vh; + */ + position: absolute; + /* top: 2.5vh; */ + bottom: 0; + width: 98vw; } -.footer-bottom a { - color: aquamarine; -} - -@media (max-width: 768px) { - .footer-content { - grid-template-columns: 1fr; - text-align: center; - } +.footer > h4, h5 { + padding: 0; + margin: 0; } \ No newline at end of file diff --git a/static/css/layouts/header.css b/static/css/layouts/header.css index a0d1656..f73093f 100644 --- a/static/css/layouts/header.css +++ b/static/css/layouts/header.css @@ -1,9 +1,10 @@ +/* header { background: white; box-shadow: 0 2px 4px rgba(0,0,0,0.1); - /* position: fixed; - top: 0; */ + / * position: fixed; + top: 0; * / width: 100%; z-index: 1000; } @@ -34,4 +35,108 @@ header { } .nav-links a.button { color: white; +} +*/ + + +/* Navigation */ +.topnav { + border-bottom-left-radius: 2.5vh; + border-bottom-right-radius: 2.5vh; + display: flex; + flex-wrap: wrap; + flex: 1; + flex-direction: row; + font-weight: bold; + font-size: 1vh; + max-height: 15vh; + height: 15vh; + align-items: flex-start; +} +.topnav a, .topnav label, .topnav p, .topnav h1 { + float: left; + display: flex; + text-align: center; + text-decoration: none; + width: 100%; + max-height: 15vh; + font-weight: normal; + justify-content: center; +} +.topnav a:hover { + background-color: var(--colour-page-background); +} + +.topnav > .container { + max-width: 50%; + height: 100%; + align-items: center; + align-self: center; + display: flex; +} +.topnav select { + padding: 1vh; + margin: 1vh; + border-radius: 1vh; + border: 2px solid var(--border-colour); + font-weight: bold; + text-align: center; +} +.topnav select .collapsed { + width: 5vw; +} +.topnav select .expanded { + width: 25vw; +} + +.company-name { + font-size: min(28px, calc(1vh * 7)); +} +@media screen and (max-width: 450px) { + .company-name { + font-size: min(24px, calc(1vh * 7)); + } +} + +/* Page Filters */ +#formFilters { + width: fit-content; + margin-left: auto; + margin-right: auto; + +} +#formFilters * { + font-size: 12px; +} + +#formFilters .container { + max-width: fit-content; +} +#formFilters .container-input { + padding: 0 0.5vh; +} + +#formFilters .container-input input { + max-width: 5vh; +} + +#formFilters .container-input.filter.active { + width: 8vh; +} +#formFilters .container-input.filter.is_not_empty { + width: 12vh; +} + +button.collapsed { + display: block; + opacity: 0; +} + +form.filter button.save, form.filter button.button-cancel { + margin-top: 0; + margin-bottom: 0; +} +form.filter button.save, form.filter button.button-cancel { + margin-top: 0; + margin-bottom: 1px; } \ No newline at end of file diff --git a/static/css/layouts/table-main.css b/static/css/layouts/table-main.css new file mode 100644 index 0000000..8974c1d --- /dev/null +++ b/static/css/layouts/table-main.css @@ -0,0 +1,65 @@ + +#tableMain { + overflow-x: auto; + padding: 1vh; + max-width: 95vw; /* min(calc(1vh * 80), calc(1vw * 90)); */ + width: min-content; + margin: 1vh auto; + align-items: normal; + justify-content: normal; +} + +#tableMain * { + padding: 0.25vh 0.5vh; +} + +#tableMain tbody{ + max-height: 53vh; + overflow-y: auto; + min-width: fit-content; + max-width: fit-content; + overflow-x: visible; +} +#tableMain:has(tbody > div) tbody { +} +#tableMain tbody > div { + margin-left: auto; + margin-right: auto; + text-align: center; + justify-content: center; + justify-items: center; + justify-self: center; + align-content: center; + align-items: center; + align-self: center; + position: relative; + display: block; + width: 90vh; +} + +#tableMain select, #tableMain input:not([type="checkbox"]), #tableMain textarea, #tableMain div { + box-sizing: border-box; + width: 100%; + height: 100%; +} + +#tableMain thead tr th, #tableMain tbody tr td { + width: 20vh; + min-width: 20vh; + padding: 0 0.5vh; +} +#tableMain tbody tr td { + height: 5vh; + padding-top: 0.5vh; +} +#tableMain tbody tr:not(:last-of-type) td { + padding-bottom: 0.5vh; +} +#tableMain thead tr th.active, #tableMain tbody tr td.active { + width: 6vh; + min-width: 6vh; +} +#tableMain tbody tr td.display_order, #tableMain thead tr th.display_order { + width: 5vh; + min-width: 5vh; +} diff --git a/static/css/main.css b/static/css/main.css index 88813b4..83649c5 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -1,33 +1,240 @@ :root { - --primary: #2563eb; - --secondary: #1e40af; - --text: #1f2937; - --subheading: #4b5563; - --light: #f3f4f6; + --font-family-base: 'Open Sans', Arial, sans-serif; + /* Declare global variables */ + /* + --c_purple: #5B29FF; + --c_purple_pastel: #D1D1FF; + --c_purple_lighter: #E8E1FF; + --c_purple_light: #C6BDFF; + --c_purple_dark: #4700B3; + */ + /* purple theme + - light https://coolors.co/palette/a172fd-a77afe-ac82fe-b691fe-c1a0fe-cbaffe-d6bffe-e0cefe-ebddfe-f5ecfe + - dark https://coolors.co/palette/310055-3c0663-4a0a77-5a108f-6818a5-8b2fc9-ab51e3-bd68ee-d283ff-dc97ff + */ + /* + --c_purple_darker: #310055; + --c_purple_dark: #4A0A77; + --c_purple: #6818A5; + --c_purple_light: #CBAFFE; + --c_purple_lighter: #F5ECFE; + + --c_blue: #0044FF; + --c_blue_pastel: #B8E0FF; + --c_blue_light: #73E8FF; + --c_blue_dark: #003ADB; + */ + /* --c_red: * / + --c-red: #FF0000; + --c_red_pastel: #FAE0E2; + --c_red_lighter: #FAE0E2; + */ +} + +html { + height: 100%; +} + +body { + background-color: var(--colour-page-background); + color: var(--colour-text); + font-family: var(--font-family-base); + font-family: Arial; + padding: 0; + margin: 0; + border: 0; + background: linear-gradient(to bottom right, var(--colour-page-background-1), var(--colour-page-background-2)); /* var(--c_purple); */ + height: 100vh; + max-height: 100%; } * { margin: 0; - padding: 0; - box-sizing: border-box; - font-family: system-ui, -apple-system, sans-serif; } -body { - line-height: 1.6; - color: var(--text); +script, link { + display: none !important; +} + +#pageBody { + height: 69vh !important; + padding: 1vh; + padding-left: 1vw; + padding-right: 1vw; + margin: 1vh; + margin-left: 0; + margin-right: 0; + border: 0; + align-content: center; + justify-content: flex-start; + display: flex; + flex-direction: column; + align-items: flex-start; + overflow-y: auto; + overflow-x: hidden; + position: absolute; + width: 98vw; + color: var(--colour-text); +} + +.page-body > * { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + text-align: center; + width: 100%; + align-self: center; + font-size: min(16px, calc(1vh * 4)); +} +#pageBody > * > * { + align-self: center; + padding-top: 0.5vh; + padding-bottom: 0.5vh; +} +#pageBody > .card { + height: fit-content; + margin-top: 1vh; +} +#pageBody > .card:first-of-type{ + margin-top: 0vh; + top: 0; +} + +/* header image */ +img.header-logo { + max-height: 15vh; + max-width: 20vw; + cursor: pointer; + border-radius: 5vh !important; +} + +/* icon images */ +.img-icon { + max-width: 16vh; + max-height: 8vh; + border-radius: 0; +} + +/* Add a card effect for articles */ +.card { + background-color: var(--colour-text-background); + padding: 1vh; + margin: 1vh; + display: flex !important; + flex-wrap: wrap; + align-items: center; + justify-content: center; + text-align: center; + border-radius: 4vh; + position: relative; + height: fit-content; + max-width: 80vw; + padding-left: 2.5vw; + padding-right: 2.5vw; +} + +.header.card { + border-radius: 2.5vh; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } .container { - max-width: 1200px; - margin: 0 auto; - padding: 0 1.5rem; + flex: 1; + margin: 0px; + align-items: flex-start; + justify-content: flex-start; + text-align: flex-start; + /* max-width: 100%; */ + /* min-width: fit-content; */ } +.column { + display: flex; + flex-direction: column; + align-items: center; + margin: auto 0; +} + +.row { + display: flex; + flex-direction: row; + width: 100%; + /* min-width: fit-content; */ +} + +.container > .card:first-of-type { + margin-top: none; +} + + /* -.page_body { - position: fixed; - top: +/* Responsive layout - when the screen is less than 800px wide, make the two columns stack on top of each other instead of next to each other * +@media screen and (max-width: 800px) { + .leftcolumn, .rightcolumn { + width: 100%; + /* padding: 0; * + } +} + +/* Responsive layout - when the screen is less than 400px wide, make the navigation links stack on top of each other instead of next to each other * +@media screen and (max-width: 400px) { + .topnav a { + float: none; + width: 100%; + } } */ + +.container-input { + padding: 1vh; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + text-align: center; +} + +.container-input > label { + width: 100%; + margin-bottom: 1vh; + margin-top: 0; +} + +.container-input:not(:nth-child(3)) > label { + margin-top: 1vh; +} + +.container-input > input, .container-input > textarea { + border: 2px solid var(--colour-primary); + padding: 1vh; +} + +.label-title { + width: 100%; +} + + +ul { + max-width: 90%; + padding: 5px 0 10px 0; +} +li { + text-align: left; + font-size: 18px; +} + + +:not(input,textarea,select,button).dirty { + background-color: var(--colour-accent); +} +input.dirty, textarea.dirty, select.dirty { + border-color: var(--colour-primary); +} + + +#pageBody > *, button { + font-size: min(12px, calc(1vh * 3)); +} \ No newline at end of file diff --git a/static/css/pages/core/admin_home.css b/static/css/pages/core/admin_home.css new file mode 100644 index 0000000..6c3e5cc --- /dev/null +++ b/static/css/pages/core/admin_home.css @@ -0,0 +1,7 @@ +#pageBody > .card:first-of-type { + width: min(80vw, 500px); +} + +.container.row { + width: auto; +} \ No newline at end of file diff --git a/static/css/pages/core/contact.css b/static/css/pages/core/contact.css deleted file mode 100644 index 461239c..0000000 --- a/static/css/pages/core/contact.css +++ /dev/null @@ -1,129 +0,0 @@ - -.contact-section { - padding: 2rem 2rem 4rem; -} - -.command { - max-width: 60vw; - width: fit-content; - margin: 0 auto; - background: #fff; - padding: 2rem; - border-radius: 8px; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); -} -.command textarea { - max-width: 40vw; -} - -.form-grid { - display: grid; - grid-template-columns: 200px 1fr; - gap: 1.5rem; - margin-bottom: 1rem; -} -.form-label { - padding-top: 0.5rem; - font-weight: 500; -} -.form-input { - width: 100%; - padding: 0.5rem; - border: 1px solid #d1d5db; - border-radius: 4px; - font-size: 1rem; -} -textarea.form-input { - min-height: 120px; -} - -.marketing-consent input { - display: inline-block; - margin-left: 20%; - margin-bottom: 1.25rem; -} - -.container.captcha > div:first-child > label:first-child { - display: flex; - justify-content: center; - width: fit-content; - text-align: center; - margin: 0 auto; -} -.container.captcha > p:last-child{ - font-size: 0.9rem; - margin: 1vh 0; -} -.container.captcha .altcha-main { - padding-left: 1rem; - padding-top: 0.75rem; - padding-bottom: 0; -} -.container.captcha .altcha-main > :last-child { - display: none; -} -.container.captcha .altcha, -altcha-widget > div:first-child, -.container.captcha > div > .altcha-widget > div { - width: fit-content; - display: flex; - margin-left: auto; - margin-right: auto; -} - -input[type="submit"] { - margin-left: 40%; - padding: 0.75rem 1.5rem; - background: #2563eb; - color: white; - border: none; - border-radius: 4px; - cursor: pointer; - font-size: 1rem; -} - -input[type="submit"]:hover { - background: #1d4ed8; -} - -.data-notice { - margin-top: 3rem; - padding: 1.5rem; - background: #f3f4f6; - border-radius: 4px; - font-size: 0.95rem; -} - -.data-notice h3 { - margin-bottom: 1rem; - font-size: 1.1rem; -} - -.data-notice ul li { - list-style-position: inside; -} - -@media (max-width: 768px) { - .command { - max-width: 80vw; - } - .command textarea { - max-width: 60vw; - } - .form-grid { - grid-template-columns: 1fr; - gap: 0.5rem; - } - - .form-label { - padding-top: 0; - } - - .submit-button { - margin-left: 0; - width: 100%; - } -} - -@media (max-width: 400px) { -} \ No newline at end of file diff --git a/static/css/pages/core/home.css b/static/css/pages/core/home.css index 7d5fa20..10d72e8 100644 --- a/static/css/pages/core/home.css +++ b/static/css/pages/core/home.css @@ -1,25 +1,32 @@ /* Hero Section */ -.hero { +.home-hero { padding: 8rem 0 4rem; - background: linear-gradient(45deg, #f8fafc, #eff6ff); + align-self: center; + margin-left: auto; + margin-right: auto; } .hero-content { max-width: 600px; } -.hero h1 { +.home-hero h2 { font-size: 3rem; line-height: 1.2; margin-bottom: 1.5rem; - color: var(--text); + color: var(--colour-text); + margin-left: auto; + margin-right: auto; } -.hero p { +.home-hero a { font-size: 1.25rem; margin-bottom: 2rem; - color: var(--subheading); + color: var(--colour-text-background); + cursor: pointer; + margin-left: auto; + margin-right: auto; } /* Services Section */ diff --git a/static/css/pages/dog/assessments.css b/static/css/pages/dog/assessments.css new file mode 100644 index 0000000..669b4a3 --- /dev/null +++ b/static/css/pages/dog/assessments.css @@ -0,0 +1,90 @@ + +#formFilters .container-input.filter.active { + width: 8vh; +} +#formFilters .container-input.filter.date_from, +#formFilters .container-input.filter.date_to { + width: 8vh; +} + + +#tableMain tbody tr td.cost_total_local_vat_excl, #tableMain thead tr th.cost_total_local_vat_excl, +#tableMain tbody tr td.cost_total_local_vat_incl, #tableMain thead tr th.cost_total_local_vat_incl { + width: 10vh; + min-width: 10vh; +} + +#tableMain thead tr th.order_items.collapsed, +#tableMain tbody tr td.order_items.collapsed { + width: 15vh; + min-width: 15vh; +} +#tableMain:has(tbody tr td.order_items table thead tr th.product_variations.collapsed) thead tr th.order_items, +#tableMain:has(tbody tr td.order_items table thead tr th.product_variations.collapsed) tbody tr td.order_items { + width: 100vh; /* 95vh */ + min-width: 100vh; +} +#tableMain thead tr th.order_items, +#tableMain tbody tr td.order_items { + width: 110vh; + min-width: 110vh; +} +#tableMain tbody tr td.order_items table thead tr th, #tableMain tbody tr td.order_items table tbody tr td { + width: 12vh; + min-width: 12vh; +} +#tableMain tbody tr td.order_items table thead tr th.display_order, #tableMain tbody tr td.order_items table tbody tr td.display_order { + width: 5vh; + min-width: 5vh; +} +#tableMain tbody tr td.order_items table thead tr th.id_unit_measurement_quantity, #tableMain tbody tr td.order_items table tbody tr td.id_unit_measurement_quantity, +#tableMain tbody tr td.order_items table thead tr th.unit_measurement_latency_manufacture, #tableMain tbody tr td.order_items table tbody tr td.unit_measurement_latency_manufacture { + width: 6vh; + min-width: 6vh; +} + +#tableMain tbody tr td.order_items table thead tr th.product_variations.collapsed, #tableMain tbody tr td.order_items table tbody tr td.product_variations.collapsed { + width: 10vh; + min-width: 10vh; +} +#tableMain tbody tr td.order_items table thead tr th.product_variations, #tableMain tbody tr td.order_items table tbody tr td.product_variations { + width: 20vh; + min-width: 20vh; +} +#tableMain tbody tr td.order_items table tbody tr td.product_variations table thead tr th, #tableMain tbody tr td.order_items table tbody tr td.product_variations table tbody tr td { + width: 8vh; + min-width: 8vh; +} +#tableMain tbody tr td.order_items table tbody tr td.product_variations table thead tr th:last-of-type, #tableMain tbody tr td.order_items table tbody tr td.product_variations table tbody tr td:last-of-type { + width: 4vh; + min-width: 4vh; +} + +#tableMain tbody tr td.order_items table thead tr th.quantity_used, #tableMain tbody tr td.order_items table tbody tr td.quantity_used, +#tableMain tbody tr td.order_items table thead tr th.quantity_produced, #tableMain tbody tr td.order_items table tbody tr td.quantity_produced, +#tableMain tbody tr td.order_items table thead tr th.latency_manufacture, #tableMain tbody tr td.order_items table tbody tr td.latency_manufacture { + width: 8vh; + min-width: 8vh; +} +#tableMain tbody tr td.order_items table thead tr th.active, #tableMain tbody tr td.order_items table tbody tr td.active, +#tableMain tbody tr td.order_items table thead tr th.add, #tableMain tbody tr td.order_items table tbody tr td.delete { + width: 4vh; + min-width: 4vh; +} + +#tableMain thead tr th.currency.collapsed, #tableMain tbody tr td.currency.collapsed { + width: 9vh; + min-width: 9vh; +} +#tableMain thead tr th.currency, #tableMain tbody tr td.currency { + width: 11vh; + min-width: 11vh; +} + +#tableMain tbody tr td.cost_total_local_vat_excl, #tableMain thead tr th.cost_total_local_vat_excl, +#tableMain tbody tr td.cost_total_local_vat_incl, #tableMain thead tr th.cost_total_local_vat_incl, +#tableMain tbody tr td.price_total_local_vat_excl, #tableMain thead tr th.price_total_local_vat_excl, +#tableMain tbody tr td.price_total_local_vat_incl, #tableMain thead tr th.price_total_local_vat_incl { + width: 5vh; + min-width: 5vh; +} \ No newline at end of file diff --git a/static/css/pages/dog/commands.css b/static/css/pages/dog/commands.css new file mode 100644 index 0000000..2393818 --- /dev/null +++ b/static/css/pages/dog/commands.css @@ -0,0 +1,53 @@ + + +#formFilters .container { + max-width: fit-content; +} + +#formFilters .container-input.filter.is_not_empty { + width: 10vh; +} + +#formFilters .container-input.filter.active { + width: 8vh; +} + + +#tableMain { + max-width: min(calc(1vh * 65), calc(1vw * 90)); +} + +#tableMain tbody tr td.display_order, #tableMain thead tr th.display_order { + width: 5vh; + min-width: 5vh; +} +#tableMain tbody tr td.product_category, #tableMain thead tr th.product_category { + width: 15vh; + min-width: 15vh; +} +#tableMain tbody tr td.name, #tableMain thead tr th.name { + width: 15vh; + min-width: 15vh; +} +#tableMain thead tr th.has_variations, #tableMain tbody tr td.has_variations { + width: 5vh; + min-width: 5vh; +} +#tableMain tbody tr td.access_level, #tableMain thead tr th.access_level { + width: 7vh; + min-width: 7vh; +} +#tableMain tbody tr td.active, #tableMain thead tr th.active { + width: 5vh; + min-width: 5vh; +} + +td > input, td > select, td > textarea, .container-input > input, .container-input > select, .container-input > textarea { + border: 2px solid var(--border-colour); + border-radius: 0.5vh; +} + +#tableMain tbody tr td table thead tr th.id_variation_type, #tableMain tbody tr td table tbody tr td.id_variation_type, #tableMain tbody tr td table thead tr th.id_variation, #tableMain tbody tr td table tbody tr td.id_variation { + width: 47.5%; +} + diff --git a/static/css/pages/dog/dog_command_links.css b/static/css/pages/dog/dog_command_links.css new file mode 100644 index 0000000..491d5ec --- /dev/null +++ b/static/css/pages/dog/dog_command_links.css @@ -0,0 +1,55 @@ + + +#formFilters .container { + max-width: fit-content; +} + +#formFilters .container-input:has(.dirty) { + background-color: var(--colour-accent); +} + +#formFilters .container-input.filter.active_only { +} + + +#tableMain { + max-width: 90vw; +} +/* +#tableMain thead tr th.category, #tableMain tbody tr td.category { + width: 8vh; + min-width: 8vh; +} +#tableMain thead tr th.product, #tableMain tbody tr td.product { + width: 10vh; + min-width: 10vh; +} +#tableMain thead tr th.product_variations.collapsed, #tableMain tbody tr td.product_variations.collapsed { + width: 10vh; + min-width: 10vh; + display: table-cell !important; +} +#tableMain thead tr th.product_variations, #tableMain tbody tr td.product_variations { + width: 24vh; + min-width: 24vh; +} +#tableMain thead tr th.active, #tableMain tbody tr td.active { + width: 6vh; + min-width: 6vh; +} +*/ + +td > input, td > select, td > textarea, .container-input > input, .container-input > select, .container-input > textarea { + border: 2px solid var(--colour-primary); + border-radius: 0.5vh; +} + +#tableMain tbody tr td table thead tr th.id_variation_type, #tableMain tbody tr td table tbody tr td.id_variation_type, #tableMain tbody tr td table thead tr th.id_variation, #tableMain tbody tr td table tbody tr td.id_variation { + width: 47.5%; +} + +/* +select.id_variation, select.id_variation_type { + max-width: 40% !important; +} +*/ diff --git a/static/css/pages/dog/dogs.css b/static/css/pages/dog/dogs.css new file mode 100644 index 0000000..3d30345 --- /dev/null +++ b/static/css/pages/dog/dogs.css @@ -0,0 +1,48 @@ + +#formFilters .container { + max-width: fit-content; +} + +#formFilters .container-input.filter.is_not_empty { + width: 10vh; +} + +#formFilters .container-input.filter.active { + width: 8vh; +} + + +#tableMain tbody tr td.display_order, #tableMain thead tr th.display_order { + width: 5vh; + min-width: 5vh; +} +#tableMain tbody tr td.code, #tableMain thead tr th.code { + width: 10vh; + min-width: 10vh; +} +#tableMain tbody tr td.name, #tableMain thead tr th.name { + width: 15vh; + min-width: 15vh; +} +#tableMain tbody tr td.description, #tableMain thead tr th.description { + width: 25vh; + min-width: 25vh; +} +#tableMain tbody tr td.access_level, #tableMain thead tr th.access_level { + width: 7vh; + min-width: 7vh; +} +#tableMain tbody tr td.active, #tableMain thead tr th.active { + width: 5vh; + min-width: 5vh; +} + +td > input, td > select, td > textarea, .container-input > input, .container-input > select, .container-input > textarea { + border: 2px solid var(--border-colour); + border-radius: 0.5vh; +} + +#tableMain tbody tr td table thead tr th.id_variation_type, #tableMain tbody tr td table tbody tr td.id_variation_type, #tableMain tbody tr td table thead tr th.id_variation, #tableMain tbody tr td table tbody tr td.id_variation { + width: 47.5%; +} + diff --git a/static/css/pages/dog/home.css b/static/css/pages/dog/home.css new file mode 100644 index 0000000..e69de29 diff --git a/static/css/pages/dog/z_product_variations.css b/static/css/pages/dog/z_product_variations.css new file mode 100644 index 0000000..794cabc --- /dev/null +++ b/static/css/pages/dog/z_product_variations.css @@ -0,0 +1,39 @@ + +#tableMain:has(thead tr th.product_variations.collapsed) { + max-width: 66vh; +} +#tableMain { + max-width: 97vh; +} + +#tableMain tbody tr td.display_order, #tableMain thead tr th.display_order, +#tableMain tbody tr td.active, #tableMain thead tr th.active { + width: 6vh; + min-width: 6vh; +} +#tableMain tbody tr td.code, #tableMain thead tr th.code, +#tableMain tbody tr td.name, #tableMain thead tr th.name, +#tableMain tbody tr td.name_plural, #tableMain thead tr th.name_plural { + width: 12vh; + min-width: 12vh; +} + +#tableMain thead tr th.product_variations.collapsed, #tableMain tbody tr td.product_variations.collapsed { + width: 8vh; + min-width: 8vh; +} +#tableMain thead tr th.product_variations, #tableMain tbody tr td.product_variations { + width: 41vh; + min-width: 41vh; +} + +#tableMain tbody tr td.product_variations table thead tr th.code, #tableMain tbody tr td.product_variations table tbody tr td.code, +#tableMain tbody tr td.product_variations table thead tr th.name, #tableMain tbody tr td.product_variations table tbody tr td.name { + width: 12vh; + min-width: 12vh; +} +#tableMain tbody tr td.product_variations table thead tr th.display_order, #tableMain tbody tr td.product_variations table tbody tr td.display_order, +#tableMain tbody tr td.product_variations table thead tr th.active, #tableMain tbody tr td.product_variations table tbody tr td.active { + width: 6vh; + min-width: 6vh; +} diff --git a/static/css/pages/dog/z_stock_items.css b/static/css/pages/dog/z_stock_items.css new file mode 100644 index 0000000..f833070 --- /dev/null +++ b/static/css/pages/dog/z_stock_items.css @@ -0,0 +1,87 @@ + +th, td { + min-width: fit-content; +} + + +#tableMain { + max-width: 90vw; +} +#tableMain thead tr th.product_category, #tableMain tbody tr td.product_category { + width: 12vh; + min-width: 12vh; +} +#tableMain thead tr th.product, #tableMain tbody tr td.product, +#tableMain thead tr th.storage_location, #tableMain tbody tr td.storage_location { + width: 10vh; + min-width: 10vh; +} + +#tableMain thead tr th.product_variations.collapsed, #tableMain tbody tr td.product_variations.collapsed { + width: 10vh; + min-width: 10vh; + display: table-cell !important; +} +#tableMain thead tr th.product_variations, #tableMain tbody tr td.product_variations { + width: 24vh; + min-width: 24vh; +} +#tableMain tbody tr td.product_variations table thead tr th.product_variation_type, #tableMain tbody tr td.product_variations table tbody tr td.product_variation_type, +#tableMain tbody tr td.product_variations table thead tr th.product_variation, #tableMain tbody tr td.product_variations table tbody tr td.product_variation { + width: 8vh; + min-width: 8vh; +} +#tableMain tbody tr td.product_variations table thead tr th.add, #tableMain tbody tr td.product_variations table tbody tr td.delete { + width: 4vh; + min-width: 4vh; +} + +#tableMain thead tr th.id_currency_cost.collapsed, #tableMain tbody tr td.id_currency_cost.collapsed { + width: 9vh; + min-width: 9vh; +} +#tableMain thead tr th.id_currency_cost, #tableMain tbody tr td.id_currency_cost { + width: 11vh; + min-width: 11vh; +} + +#tableMain thead tr th.cost_unit_local_vat_excl, #tableMain tbody tr td.cost_unit_local_vat_excl, +#tableMain thead tr th.cost_unit_local_vat_incl, #tableMain tbody tr td.cost_unit_local_vat_incl { + width: 9vh; + min-width: 9vh; +} + +#tableMain thead tr th.storage_location.collapsed, #tableMain tbody tr td.storage_location.collapsed { + width: 10vh; + min-width: 10vh; +} +#tableMain thead tr th.storage_location, #tableMain tbody tr td.storage_location { + width: 20vh; + min-width: 20vh; +} +#tableMain tbody tr td.storage_location table thead tr th, +#tableMain tbody tr td.storage_location table tbody tr td { + width: 8vh; + min-width: 8vh; +} +#tableMain tbody tr td.storage_location table thead tr th:last-of-type, +#tableMain tbody tr td.storage_location table tbody tr td:last-of-type { + width: 4vh; + min-width: 4vh; +} + +#tableMain thead tr th.active, #tableMain tbody tr td.active, +#tableMain thead tr th.is_sealed, #tableMain tbody tr td.is_sealed, +#tableMain thead tr th.is_consumed, #tableMain tbody tr td.is_consumed { + width: 6vh; + min-width: 6vh; +} + +#tableMain thead tr th.date_purchased, #tableMain tbody tr td.date_purchased, +#tableMain thead tr th.date_received, #tableMain tbody tr td.date_received, +#tableMain thead tr th.date_unsealed, #tableMain tbody tr td.date_unsealed, +#tableMain thead tr th.date_expiration, #tableMain tbody tr td.date_expiration, +#tableMain thead tr th.date_consumed, #tableMain tbody tr td.date_consumed { + width: 15vh; + min-width: 15vh; +} \ No newline at end of file diff --git a/static/css/pages/dog/z_supplier.css b/static/css/pages/dog/z_supplier.css new file mode 100644 index 0000000..1f7b40e --- /dev/null +++ b/static/css/pages/dog/z_supplier.css @@ -0,0 +1,55 @@ + +#formFilters .container-input.filter.active { + width: 8vh; +} + +#tableMain tbody tr td.name_company, #tableMain thead tr th.name_company, +#tableMain tbody tr td.name_contact, #tableMain thead tr th.name_contact, +#tableMain tbody tr td.department_contact, #tableMain thead tr th.department_contact, +#tableMain tbody tr td.phone_number, #tableMain thead tr th.phone_number { + width: 10vh; + min-width: 10vh; +} +#tableMain tbody tr td.email, #tableMain thead tr th.email, +#tableMain tbody tr td.website, #tableMain thead tr th.website { + width: 15vh; + min-width: 15vh; +} + +#tableMain thead tr th.address.collapsed, #tableMain tbody tr td.address.collapsed { + width: 9vh; + min-width: 9vh; + display: table-cell !important; +} +#tableMain thead tr th.address, #tableMain tbody tr td.address { + width: 108vh; + min-width: 108vh; +} +#tableMain tbody tr td.address table thead tr th.postcode, #tableMain tbody tr td.address table tbody tr td.postcode, +#tableMain tbody tr td.address table thead tr th.address_line_1, #tableMain tbody tr td.address table tbody tr td.address_line_1, +#tableMain tbody tr td.address table thead tr th.address_line_2, #tableMain tbody tr td.address table tbody tr td.address_line_2, +#tableMain tbody tr td.address table thead tr th.city, #tableMain tbody tr td.address table tbody tr td.city, +#tableMain tbody tr td.address table thead tr th.county, #tableMain tbody tr td.address table tbody tr td.county, +#tableMain tbody tr td.address table thead tr th.region, #tableMain tbody tr td.address table tbody tr td.region { + width: 15vh; + min-width: 15vh; +} +#tableMain tbody tr td.address table thead tr th.active, #tableMain tbody tr td.address table tbody tr td.active, +#tableMain tbody tr td.address table thead tr th.add, #tableMain tbody tr td.address table tbody tr td.delete { + width: 5vh; + min-width: 5vh; +} + +#tableMain thead tr th.currency.collapsed, #tableMain tbody tr td.currency.collapsed { + width: 9vh; + min-width: 9vh; +} +#tableMain thead tr th.currency, #tableMain tbody tr td.currency { + width: 11vh; + min-width: 11vh; +} + +#tableMain tbody tr td.active, #tableMain thead tr th.active { + width: 5vh; + min-width: 5vh; +} diff --git a/static/css/pages/dog/z_supplier_purchase_order.css b/static/css/pages/dog/z_supplier_purchase_order.css new file mode 100644 index 0000000..be6f529 --- /dev/null +++ b/static/css/pages/dog/z_supplier_purchase_order.css @@ -0,0 +1,98 @@ + + +#formFilters .container-input.filter.active { + width: 8vh; +} +#formFilters .container-input.filter.date_from, +#formFilters .container-input.filter.date_to { + width: 8vh; +} + +#tableMain tbody tr td.supplier, #tableMain thead tr th.supplier { + width: 15vh; + min-width: 15vh; +} + +#tableMain thead tr th.currency.collapsed, #tableMain tbody tr td.currency.collapsed { + width: 9vh; + min-width: 9vh; +} +#tableMain thead tr th.currency, #tableMain tbody tr td.currency { + width: 11vh; + min-width: 11vh; +} + +#tableMain tbody tr td.cost_total_local_vat_excl, #tableMain thead tr th.cost_total_local_vat_excl, +#tableMain tbody tr td.cost_total_local_vat_incl, #tableMain thead tr th.cost_total_local_vat_incl { + width: 10vh; + min-width: 10vh; +} + +#tableMain tbody tr td.order_items, #tableMain thead tr th.items { + width: 40vh; + min-width: 40vh; +} +#tableMain thead tr th.order_items.collapsed, #tableMain tbody tr td.order_items.collapsed { + width: 15vh; + min-width: 15vh; +} +#tableMain:has(tbody tr td.order_items table thead tr th.product_variations.collapsed) thead tr th.order_items, +#tableMain:has(tbody tr td.order_items table thead tr th.product_variations.collapsed) tbody tr td.order_items { + width: 126vh; + min-width: 126vh; +} +#tableMain thead tr th.order_items, +#tableMain tbody tr td.order_items { + width: 136vh; + min-width: 136vh; +} +#tableMain tbody tr td.order_items table thead tr th, #tableMain tbody tr td.order_items table tbody tr td { + width: 12vh; + min-width: 12vh; +} +#tableMain tbody tr td.order_items table thead tr th.display_order, #tableMain tbody tr td.order_items table tbody tr td.display_order, +#tableMain tbody tr td.order_items table thead tr th.add, #tableMain tbody tr td.order_items table tbody tr td.delete { + width: 5vh; + min-width: 5vh; +} + +#tableMain tbody tr td.order_items table thead tr th.product_variations.collapsed, #tableMain tbody tr td.order_items table tbody tr td.product_variations.collapsed { + width: 10vh; + min-width: 10vh; +} +#tableMain tbody tr td.order_items table thead tr th.product_variations, #tableMain tbody tr td.order_items table tbody tr td.product_variations { + width: 20vh; + min-width: 20vh; +} +#tableMain tbody tr td.order_items table tbody tr td.product_variations table thead tr th, #tableMain tbody tr td.order_items table tbody tr td.product_variations table tbody tr td { + width: 8vh; + min-width: 8vh; +} +#tableMain tbody tr td.order_items table tbody tr td.product_variations table thead tr th:last-of-type, #tableMain tbody tr td.order_items table tbody tr td.product_variations table tbody tr td:last-of-type { + width: 4vh; + min-width: 4vh; +} + +#tableMain tbody tr td.order_items table thead tr th.id_unit_measurement_quantity, #tableMain tbody tr td.order_items table tbody tr td.id_unit_measurement_quantity { + width: 6vh; + min-width: 6vh; +} +#tableMain tbody tr td.order_items table thead tr th.quantity_ordered, #tableMain tbody tr td.order_items table tbody tr td.quantity_ordered, +#tableMain tbody tr td.order_items table thead tr th.quantity_received, #tableMain tbody tr td.order_items table tbody tr td.quantity_received, +#tableMain tbody tr td.order_items table thead tr th.cost_total_local_vat_excl, #tableMain tbody tr td.order_items table tbody tr td.cost_total_local_vat_excl, +#tableMain tbody tr td.order_items table thead tr th.cost_total_local_vat_incl, #tableMain tbody tr td.order_items table tbody tr td.cost_total_local_vat_incl, +#tableMain tbody tr td.order_items table thead tr th.cost_unit_local_vat_excl, #tableMain tbody tr td.order_items table tbody tr td.cost_unit_local_vat_excl, +#tableMain tbody tr td.order_items table thead tr th.cost_unit_local_vat_incl, #tableMain tbody tr td.order_items table tbody tr td.cost_unit_local_vat_incl, +#tableMain tbody tr td.order_items table thead tr th.latency_delivery_days, #tableMain tbody tr td.order_items table tbody tr td.latency_delivery_days { + width: 8vh; + min-width: 8vh; +} +#tableMain tbody tr td.order_items table thead tr th.active, #tableMain tbody tr td.order_items table tbody tr td.active { + width: 4vh; + min-width: 4vh; +} + +#tableMain tbody tr td.active, #tableMain thead tr th.active { + width: 5vh; + min-width: 5vh; +} diff --git a/static/css/sections/dog.css b/static/css/sections/dog.css new file mode 100644 index 0000000..75e3700 --- /dev/null +++ b/static/css/sections/dog.css @@ -0,0 +1,55 @@ + +.img-product { + max-width: 20vh; + max-height: 20vh; + border-radius: 3vh; + justify-self: left; +} + +.img-thumbnail { + max-width: 10vh; + max-height: 10vh; + border-radius: 3vh; + justify-self: left; +} + +.buttonAddToBasket { + background-color: var(--colour-page-background); + border-color: var(--colour-primary); +} + +#buttonCheckout, .buttonBuyNow { + background-color: var(--colour-page-background); + /* color: var(--c_purple_dark); */ + border-color: var(--colour-primary); +} + +.button-increment, .button-decrement { + border: 2px solid darkgrey; + background-color: lightgray; + margin: 1vh 1vh; + width: 2.5vh; + height: 2.5vh; + border-radius: 1.25vh; + font-size: 2vh; +} + +.container-input > input { + padding: 0vh 1vh; + border-radius: 0.5vh; + max-width: 7vh; +} + +#basket { + max-width: 100%; +} + + + +/* Right column */ +.rightcolumn { + min-width: fit-content; +} + +/* Main Table */ + diff --git a/static/css/themes/dark.css b/static/css/themes/dark.css index 5c30a95..689631a 100644 --- a/static/css/themes/dark.css +++ b/static/css/themes/dark.css @@ -1,3 +1,4 @@ +/* :root { --background-color: #121212; --text-color: #e0e0e0; @@ -12,34 +13,35 @@ --border-color: #333333; --shadow-color: rgba(255, 255, 255, 0.1); - /* Header */ + /* Header * / --header-bg: #1f1f1f; --header-text: #e0e0e0; - /* Footer */ + /* Footer * / --footer-bg: #1f1f1f; --footer-text: #a0a0a0; - /* Navigation */ + /* Navigation * / --nav-bg: #1f1f1f; --nav-text: #e0e0e0; --nav-hover-bg: #2c2c2c; --nav-hover-text: #bb86fc; - /* Buttons */ + /* Buttons * / --Button-primary-bg: #bb86fc; --Button-primary-text: #121212; --Button-secondary-bg: #03dac6; --Button-secondary-text: #121212; - /* Forms */ + /* Forms * / --input-bg: #2c2c2c; --input-border: #454545; --input-text: #e0e0e0; --input-focus-border: #bb86fc; - /* Cards */ + /* Cards * / --card-bg: #1f1f1f; --card-border: #333333; --card-shadow: 0 0.125rem 0.25rem rgba(255, 255, 255, 0.05); -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/static/css/themes/icons.css b/static/css/themes/icons.css new file mode 100644 index 0000000..b487b27 --- /dev/null +++ b/static/css/themes/icons.css @@ -0,0 +1,77 @@ + +/* Toggle light mode / dark mode button */ +.theme-switch { + background: none; + border: none; + cursor: pointer; + width: 4vh; + height: 4vh; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + position: relative; + margin-top: auto; + border-radius: 2vh; +} +.theme-switch:hover { + background-color: var(--colour-primary); +} +.theme-switch img.theme-icon, +.theme-switch svg.theme-icon { + width: 100%; + height: 100%; + object-fit: contain; + transition: opacity 1s ease, transform 1s ease; + position: absolute; + margin-top: auto; +} +img.theme-icon.dark-mode-icon { + top: 0vh; + left: 0vh; +} +svg.theme-icon.light-mode-icon { + width: 3.5vh; + height: 3.5vh; + top: 0.25vh; + left: 0.25vh; +} +svg.theme-icon.light-mode-icon .background { + fill: var(--colour-secondary); +} +.theme-switch:hover svg.theme-icon.light-mode-icon .background { + fill: var(--colour-primary); +} +svg.theme-icon.light-mode-icon .sun { + fill: var(--colour-text); + stroke: var(--colour-text); +} +/* +svg.theme-icon { + width: 2vh; + height: 2vh; +} +*/ + +/* Hide the icon that doesn't match the current theme */ +[data-theme="light"] .theme-switch .dark-mode-icon { + opacity: 1; + display: block; + transform: rotate(0deg); +} +[data-theme="light"] .theme-switch .light-mode-icon { + opacity: 0; + display: none; + transform: rotate(90deg); +} + +[data-theme="dark"] .theme-switch .dark-mode-icon { + opacity: 0; + display: none; + transform: rotate(-90deg); +} +[data-theme="dark"] .theme-switch .light-mode-icon { + opacity: 1; + display: block; + transform: rotate(0deg); +} diff --git a/static/css/themes/light.css b/static/css/themes/light.css index c1faf9a..723ca46 100644 --- a/static/css/themes/light.css +++ b/static/css/themes/light.css @@ -1 +1,33 @@ -/* Default */ \ No newline at end of file +/* Default */ +:root { + /* Claude dark blue / grey theme */ + --colour-accent: #C77DFF; + --colour-error: red; + --colour-page-background: #E0AAFF; + --colour-page-background-1: #F5ECFE; + --colour-page-background-2: #FAE0E2; + --colour-primary: #240046; + --colour-secondary: #3C096C; + --colour-text: #10002B; + --colour-text-background: white; + --colour-text-link-unvisited: #0000EE; + --colour-text-link-visited: #551A8B; +} + +/* +--c_purple_darker: #310055; +--c_purple_dark: #4A0A77; +--c_purple: #6818A5; +--c_purple_light: #CBAFFE; +--c_purple_lighter: #F5ECFE; + +--c_blue: #0044FF; +--c_blue_pastel: #B8E0FF; +--c_blue_light: #73E8FF; +--c_blue_dark: #003ADB; +/* --c_red: * / +--c-red: #FF0000; +--c_red_pastel: #FAE0E2; +--c_red_lighter: #FAE0E2; +} +*/ \ No newline at end of file diff --git a/static/js/dom.js b/static/js/dom.js index 8907d40..bea7348 100644 --- a/static/js/dom.js +++ b/static/js/dom.js @@ -41,10 +41,10 @@ export default class DOM { let selector = Validation.isEmpty(flagRow) ? 'tr' : 'tr.' + flagRow; return element.closest(selector); } - static getClosestParent(element, selector) { + static getClosestParent(element, parentSelector) { let parent = element.parentElement; while (parent) { - if (parent.matches(selector)) { + if (parent.matches(parentSelector)) { return parent; } parent = parent.parentElement; @@ -136,7 +136,7 @@ export default class DOM { return returnVal; } static getElementAttributeValueCurrent(element) { - debugger; + // debugger; if (Validation.isEmpty(element)) return null; return element.getAttribute(attrValueCurrent); } diff --git a/static/js/pages/base.js b/static/js/pages/base.js index d598eac..a78d8d5 100644 --- a/static/js/pages/base.js +++ b/static/js/pages/base.js @@ -70,13 +70,17 @@ export default class BasePage { }); this.hookupButtonsNavHome(); + // this.hookupButtonsNavAdminHome(); this.hookupButtonsNavUserAccount(); this.hookupButtonsNavUserLogout(); this.hookupButtonsNavUserLogin(); // this.hookupButtonsNavStoreHome(); // this.hookupButtonsNavStoreManufacturingPurchaseOrders(); - this.hookupButtonsNavAdminHome(); + this.hookupButtonsNavDogHome(); + this.hookupButtonsNavDogCommands(); + this.hookupButtonsNavDogDogCommandLinks(); + this.hookupButtonsNavDogDogs(); } hookupEventHandler(eventType, selector, callback) { Events.initialiseEventHandler(selector, flagInitialised, (element) => { @@ -94,9 +98,14 @@ export default class BasePage { this.router.navigateToHash(hashPageNav); }); } + /* + hookupButtonsNavAdminHome() { + this.hookupButtonsNav('.' + flagNavAdminHome, hashPageAdminHome); + } hookupButtonsNavServices() { this.hookupButtonsNav('.' + flagNavServices, hashPageServices); } + */ hookupButtonsNavUserAccount() { this.hookupButtonsNav('.' + flagNavUserAccount, hashPageUserAccount); } @@ -117,16 +126,17 @@ export default class BasePage { }); }); } - /* hookupButtonsNavDogHome() { this.hookupButtonsNav('.' + flagNavDogHome, hashPageDogHome); } - */ - hookupButtonsNavDogDogCommandLink() { - this.hookupButtonsNav('.' + flagNavDogDogCommandLink, hashPageDogDogCommandLink); + hookupButtonsNavDogCommands() { + this.hookupButtonsNav('.' + flagNavDogCommands, hashPageDogCommands); } - hookupButtonsNavAdminHome() { - this.hookupButtonsNav('.' + flagNavAdminHome, hashPageAdminHome); + hookupButtonsNavDogDogCommandLinks() { + this.hookupButtonsNav('.' + flagNavDogDogCommandLinks, hashPageDogDogCommandLinks); + } + hookupButtonsNavDogDogs() { + this.hookupButtonsNav('.' + flagNavDogDogs, hashPageDogDogs); } hookupLogos() { diff --git a/static/js/pages/base_table.js b/static/js/pages/base_table.js index d1808b5..a9e9327 100644 --- a/static/js/pages/base_table.js +++ b/static/js/pages/base_table.js @@ -66,15 +66,19 @@ export default class TableBasePage extends BasePage { this.hookupFilter(flagActive); } hookupFilter(filterFlag, handler = (event, filter) => { return TableBasePage.isDirtyFilter(filter); }) { - let filterSelector = idFormFilters + ' .' + filterFlag; + let filterSelector = idFormFilters + ' #' + filterFlag; this.hookupEventHandler("change", filterSelector, handler); + let filter = document.querySelector(filterSelector); + let filterValuePrevious = DOM.getElementValueCurrent(filter); + filter.setAttribute(attrValueCurrent, filterValuePrevious); + filter.setAttribute(attrValuePrevious, filterValuePrevious); } static isDirtyFilter(filter) { let isDirty = DOM.updateAndCheckIsElementDirty(filter); if (isDirty) { let tbody = document.querySelector(idTableMain + ' tbody'); - tbody.querySelectorAll('tr').remove(); - tbody.appendChild(document.createElement('
Press "Apply Filters" to refresh the table.
')); + tbody.querySelectorAll('tr').forEach((tr) => { tr.remove(); }); + tbody.innerHTML = '
Press "Apply Filters" to refresh the table.
'; } return isDirty; } @@ -99,6 +103,11 @@ export default class TableBasePage extends BasePage { callFilterTableContent() { let formFilters = this.getFormFilters(); let filtersJson = DOM.convertForm2JSON(formFilters); + console.log("callFilterTableContent"); + console.log("formFilters"); + console.log(formFilters); + console.log("filtersJson"); + console.log(filtersJson); this.leave(); API.goToHash(this.constructor.hash, filtersJson); } @@ -508,6 +517,13 @@ export default class TableBasePage extends BasePage { toggleColumnHeaderCollapsed(flagColumn, isCollapsed) { this.toggleColumnHasClassnameFlag(flagColumn, isCollapsed, flagCollapsed); } + + hookupFieldsCommand() { + this.hookupTableCellDdlPreviews(idTableMain + ' td.' + flagCommand, Utils.getListFromDict(filterCommands)); + } + hookupFieldsDog() { + this.hookupTableCellDdlPreviews(idTableMain + ' td.' + flagDog, Utils.getListFromDict(filterDogs)); + } createTdActive(isActive) { let tdActive = document.createElement("td"); diff --git a/static/js/pages/dog/basket.js b/static/js/pages/dog/basket.js new file mode 100644 index 0000000..5a571ba --- /dev/null +++ b/static/js/pages/dog/basket.js @@ -0,0 +1,198 @@ + +import Events from "../../lib/events.js"; +import LocalStorage from "../../lib/local_storage.js"; +import BasePage from "../base.js"; + +export default class PageDogBasket extends BasePage { + static hash = hashPageDogBasket; + + constructor(router) { + super(router); + } + + initialize() { + this.sharedInitialize(); + this.hookupDogCardsInfo(); + this.hookupOverlaysDogBasketInfo(); + this.hookupButtonCheckoutSession(); + } + + + hookupDogCardsInfo() { + + document.querySelectorAll(idContainerInfoDelivery).addEventListener("click", function(event) { + if (_verbose) { console.log("delivery modal display method"); } + document.querySelectorAll(idOverlayInfoDelivery).css('display', 'block'); + }); + + document.querySelectorAll(idContainerInfoBilling).addEventListener("click", function(event) { + if (_verbose) { console.log("billing modal display method"); } + document.querySelectorAll(idOverlayInfoBilling).css('display', 'block'); + }); + } + + hookupOverlaysDogBasketInfo() { + + let elOverlay, elForm; + + // Delivery + elOverlay = document.querySelectorAll(idOverlayInfoDelivery); + elForm = elOverlay.querySelector('form'); + + hookupOverlay(elOverlay); + Events.initialiseEventHandler(elForm, flagInitialised, function() { + elForm.submit(function(event) { + elForm = document.querySelectorAll(elForm); + event.preventDefault(); + if (_verbose) { console.log("delivery submit method"); } + + ajaxData = {}; + ajaxData[keyInfoType] = keyInfoDelivery; + ajaxData = convertFormBilling2JSON(ajaxData, idOverlayInfoDelivery); + + ajaxJSONData('info delivery', mapHashToController(hashDogBasketInfo), ajaxData, loadInfoAddress, false); + // document.querySelectorAll(idOverlayInfoDelivery).css('display', 'none'); + }); + }); + + // Billing + elOverlay = document.querySelectorAll(idOverlayInfoBilling); + elForm = elOverlay.querySelector('form'); + + hookupOverlay(elOverlay); + Events.initialiseEventHandler(elForm, flagInitialised, function() { + elForm.submit(function(event) { + event.preventDefault(); + if (_verbose) { console.log("billing submit method"); } + + ajaxData = {}; + ajaxData[keyInfoType] = keyInfoBilling; + ajaxData = convertFormBilling2JSON(ajaxData, idOverlayInfoBilling); // formData; // form.serialize(); + + ajaxJSONData('info billing', mapHashToController(hashDogBasketInfo), ajaxData, loadInfoAddress, false); + // document.querySelectorAll(idOverlayInfoBilling).css('display', 'none'); + }); + }); + let keys = [keyNameFull, keyPhoneNumber, keyPostcode, keyAddress1, keyCity, keyCounty]; + for (var k in keys) { + elForm.querySelector('#' + keys[k]).removeAttr('required'); + } + } + + loadInfoAddress(response) { + + if (_verbose) { console.log('response:'); console.log(response.data); } + let infoType = response.data[keyInfoType]; + let infoAddress = response.data[infoType]; + LocalStorage.setLocalStorage(infoType, infoAddress); + + // update webpage elements in background + if (infoType == keyInfoBilling) { + + let container = document.querySelectorAll(idContainerInfoBilling); + if (infoAddress[keyInfoIdentical]) { + container.querySelector('div').innerHTML = "Same as delivery address"; + } else { + container.querySelector('div').innerHTML = "" + infoAddress[keyNameFull] + ' at ' + infoAddress[keyPostcode] + ""; + } + + document.querySelectorAll(idOverlayInfoBilling).css('display', 'none'); + + document.querySelectorAll(idOverlayInfoBilling).querySelector('form').classList.add(flagSubmitted); + } else { + + let container = document.querySelectorAll(idContainerInfoDelivery); + container.querySelector('div').innerHTML = "" + infoAddress[keyNameFull] + ' at ' + infoAddress[keyPostcode] + ""; + + document.querySelectorAll(idOverlayInfoDelivery).css('display', 'none'); + + document.querySelectorAll(idOverlayInfoDelivery).querySelector('form').classList.add(flagSubmitted); + } + } + + convertFormBilling2JSON(ajaxData, idOverlayInfo) { + + let elOverlay, elForm, elOverlayDelivery, elFormDelivery; + + elOverlay = document.querySelectorAll(idOverlayInfo); + elForm = elOverlay.querySelector('form'); + elOverlay = document.querySelectorAll(idOverlayInfoDelivery); + elForm = elOverlay.querySelector('form'); + + ajaxData[flagForm] = convertForm2JSON(elForm); // formData; // form.serialize(); + let keys = [keyNameFull, keyPhoneNumber, keyPostcode, keyAddress1, keyAddress2, keyCity, keyCounty]; + if (_verbose) { + console.log('converting billing form to json\nform ID: ' + elForm.id); + console.log('ajaxData:'); + console.log(ajaxData); + } + ajaxData[flagForm][keyInfoIdentical] = getElementValueCurrent(elForm.querySelector('#' + keyInfoIdentical)); + for (var k in keys) { + if (idOverlayInfo == idOverlayInfoBilling && ajaxData[flagForm][keyInfoIdentical]) { + ajaxData[flagForm][keys[k]] = getElementValueCurrent(elFormDelivery.querySelector('#' + keys[k])); + } else { + ajaxData[flagForm][keys[k]] = getElementValueCurrent(elForm.querySelector('#' + keys[k])); + } + } + if (_verbose) { + console.log('ajaxData:'); + console.log(ajaxData); + } + return ajaxData; + } + + hookupButtonCheckoutSession() { + let btnCheckout = document.querySelectorAll(idButtonCheckout); + btnCheckout.classList.remove(flagInitialised); + Events.initialiseEventHandler(idButtonCheckout, flagInitialised, function() { + + btnCheckout.removeEventListener("click"); + btnCheckout.addEventListener("click", function(event) { + + + //setupPageLocalStorageNext(hashPageDogBasket); + let basket = LocalStorage.getLocalStorage(keyBasket); + // goToPage(hashPageDogBasket); + let ajaxData = {}; + ajaxData[keyBasket] = basket; + ajaxData = convertFormBilling2JSON(ajaxData, idOverlayInfoDelivery); + ajaxData = convertFormBilling2JSON(ajaxData, idOverlayInfoBilling); + ajaxData[key_code_currency] = getCurrencySelected(); + // ajaxData[keyIsSubscription] = false; // only checkout one-time payment items for now + + ajaxJSONData('checkout session', mapHashToController(hashPageDogCheckout), ajaxData, handleResponseCheckout, false); + }); + }); + } + + handleResponseCheckout(response) { + // let tmpData = {}; + // tmpData[keyIdCheckout] = response.data[keyIdCheckout] + // goToPage(hashPageDogCheckoutSession, tmpData); + window.location.href = response.data[keyUrlCheckout] + } + + hookupButtonFormBillingCopy() { + + // let elButton = document.querySelectorAll(idButtonFormBillingCopy); + + Events.initialiseEventHandler(idButtonFormBillingCopy, flagInitialised, function() { + document.querySelectorAll(idButtonFormBillingCopy).addEventListener("click", function (event) { + + let keys = [keyNameFull, keyPhoneNumber, keyPostcode, keyAddress1, keyAddress2, keyCity, keyCounty]; + + let elFormBilling = document.querySelectorAll(idOverlayInfoBilling).querySelector('form'); + let elFormDelivery = document.querySelectorAll(idOverlayInfoDelivery).querySelector('form'); + + for (var k in keys) { + elFormBilling.querySelector('#' + keys[k]).value = getElementValueCurrent(elFormDelivery.querySelector('#' + keys[k])); + } + }); + }); + } + + + leave() { + super.leave(); + } +} diff --git a/static/js/pages/dog/commands.js b/static/js/pages/dog/commands.js new file mode 100644 index 0000000..8a2a235 --- /dev/null +++ b/static/js/pages/dog/commands.js @@ -0,0 +1,143 @@ + +import Events from "../../lib/events.js"; +import TableBasePage from "../base_table.js"; +import API from "../../api.js"; +import DOM from "../../dom.js"; +import DogTableMixinPage from "./mixin_table.js"; +import Utils from "../../lib/utils.js"; + +export default class PageDogCommands extends TableBasePage { + static hash = hashPageDogCommands; + static attrIdRowObject = attrIdCommand; + callSaveTableContent = API.saveCommands; + + constructor(router) { + super(router); + this.dogMixin = new DogTableMixinPage(this); + } + + initialize() { + this.sharedInitialize(); + } + + hookupFilters() { + this.sharedHookupFilters(); + this.hookupFilterDog(); + this.hookupFilterIsNotEmpty(); + this.hookupFilterActive(); + } + hookupFilterDog() { + this.hookupFilter(flagDog); + } + + loadRowTable(rowJson) { + return; + if (rowJson == null) return; + let row = _rowBlank.cloneNode(true); + row.classList.remove(flagRowNew); + row.classList.remove(flagInitialised); + row.querySelectorAll('.' + flagInitialised).forEach(function(element) { + element.classList.remove(flagInitialised); + }); + let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); + let tdDog = row.querySelector('td.' + flagDog); + let divDog = tdDog.querySelector('div.' + flagDog); + let textareaName = row.querySelector('td.' + flagName + ' textarea'); + let tdAccessLevel = row.querySelector('td.' + flagAccessLevel); + let divAccessLevel = tdAccessLevel.querySelector('div.' + flagAccessLevel); + let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]'); + + DOM.setElementValuesCurrentAndPrevious(sliderDisplayOrder, rowJson[flagDisplayOrder]); + DOM.setElementValuesCurrentAndPrevious(textareaCode, rowJson[flagCode]); + DOM.setElementValuesCurrentAndPrevious(textareaName, rowJson[flagName]); + DOM.setElementValuesCurrentAndPrevious(textareaDescription, rowJson[flagDescription]); + tdAccessLevel.setAttribute(attrIdAccessLevel, rowJson[attrIdAccessLevel]); + tdAccessLevel.setAttribute(flagAccessLevelRequired, rowJson[flagAccessLevelRequired]); + divAccessLevel.setAttribute(attrIdAccessLevel, rowJson[attrIdAccessLevel]); + DOM.setElementValuesCurrentAndPrevious(divAccessLevel, rowJson[attrIdAccessLevel]); + divAccessLevel.textContent = rowJson[flagAccessLevelRequired]; + DOM.setElementValuesCurrentAndPrevious(inputActive, rowJson[flagActive]); + row.setAttribute(rowJson[flagKeyPrimary], rowJson[rowJson[flagKeyPrimary]]); + + let table = TableBasePage.getTableMain(); + let bodyTable = table.querySelector('tbody'); + bodyTable.appendChild(row); + } + getJsonRow(row) { + if (row == null) return; + let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); + let tdDog = row.querySelector('td.' + flagDog); + let textareaName = row.querySelector('td.' + flagName + ' textarea'); + // let tdCommandVariations = row.querySelector('td.' + flagCommandVariations); + let inputHasVariations = row.querySelector('td.' + flagHasVariations + ' input[type="checkbox"]'); + let tdAccessLevel = row.querySelector('td.' + flagAccessLevel); + let buttonActive = row.querySelector(':scope > td.' + flagActive + ' button'); + + let jsonCommand = {}; + jsonCommand[attrIdCommand] = row.getAttribute(attrIdCommand); + jsonCommand[attrIdDog] = DOM.getElementAttributeValueCurrent(tdDog); + jsonCommand[flagName] = DOM.getElementAttributeValueCurrent(textareaName); + // jsonRow[flagCommandVariations] = DOM.getElementAttributeValueCurrent(tdCommandVariations); + // jsonRow[flagHasVariations] = jsonRow[flagCommandVariations] != ''; + jsonCommand[flagHasVariations] = DOM.getElementAttributeValueCurrent(inputHasVariations); + // jsonCommand[flagAccessLevelRequired] = tdAccessLevel.getAttribute(flagAccessLevelRequired); + jsonCommand[attrIdAccessLevel] = DOM.getElementAttributeValueCurrent(tdAccessLevel); + jsonCommand[flagActive] = buttonActive.classList.contains(flagDelete); + jsonCommand[flagDisplayOrder] = DOM.getElementAttributeValueCurrent(sliderDisplayOrder); + return jsonCommand; + } + initialiseRowNew(tbody, row) { + if (row == null) return; + this.initialiseSliderDisplayOrderRowNew(tbody, row); + } + + hookupTableMain() { + super.hookupTableMain(); + this.hookupSlidersDisplayOrderTable(); + this.hookupTdsDog(); + this.hookupTextareasNameTable(); + this.hookupInputsHasVariationsTable(); + this.hookupTdsAccessLevel(); + this.hookupFieldsActive(); + } + hookupTdsDog() { + let cellSelector = idTableMain + ' tbody td.' + flagDog; + this.hookupTableCellDdlPreviews(cellSelector, Utils.getListFromDict(filterDogs)); + } + hookupInputsHasVariationsTable() { + let cellSelector = idTableMain + ' tbody td.' + flagHasVariations + ' input[type="checkbox"]'; + this.hookupChangeHandlerTableCells(cellSelector); + } + + /* + isDirtyRow(row) { + if (row == null) return false; + console.log("Command Command isDirtyRow"); + console.log("row: ", row); + let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder); + let inputCode = row.querySelector('td.' + flagCode + ' textarea'); + let inputName = row.querySelector('td.' + flagName + ' textarea'); + let inputDescription = row.querySelector('td.' + flagDescription + ' textarea'); + let tdAccessLevel = row.querySelector('td.' + flagAccessLevel); + let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]'); + let isDirty = sliderDisplayOrder.classList.contains(flagDirty) || inputCode.classList.contains(flagDirty) || inputName.classList.contains(flagDirty) || + inputDescription.classList.contains(flagDirty) || tdAccessLevel.classList.contains(flagDirty) || inputActive.classList.contains(flagDirty); + DOM.handleDirtyElement(row, isDirty); + return isDirty; + } + */ + + leave() { + super.leave(); + } + + /* + getFiltersDefaults() { + filters = {}; + filters.flagIsNotEmpty = true; + filters.flagActive = true; + return filters; + } + */ +} + diff --git a/static/js/pages/dog/dog_command_links.js b/static/js/pages/dog/dog_command_links.js new file mode 100644 index 0000000..66c658b --- /dev/null +++ b/static/js/pages/dog/dog_command_links.js @@ -0,0 +1,184 @@ + +import API from "../../api.js"; +import BusinessObjects from "../../lib/business_objects/business_objects.js"; +import DOM from "../../dom.js"; +import Events from "../../lib/events.js"; +import TableBasePage from "../base_table.js"; +import Utils from "../../lib/utils.js"; +import Validation from "../../lib/validation.js"; +import DogTableMixinPage from "./mixin_table.js"; + +export default class PageDogDogCommandLinks extends TableBasePage { + static hash = hashPageDogDogCommandLinks; + static attrIdRowObject = attrIdDogCommandLink; + callSaveTableContent = API.saveDogCommandLinks; + + constructor(router) { + super(router); + this.dogMixin = new DogTableMixinPage(this); + } + + initialize() { + this.sharedInitialize(); + } + + hookupFilters() { + this.sharedHookupFilters(); + this.hookupFilterDog(); + this.hookupFilterCommand(); + } + hookupFilterDog() { + this.hookupFilter(attrIdDog); + /*, (event, filterDog) => { + // loadDogCommandLinks(); + // let wasDirtyFilter = filterDog.classList.contains(flagDirty); + PageDogDogCommandLinks.isDirtyFilter(filterDog); + let isDirtyFilter = filterDog.classList.contains(flagDirty); + let idDog = DOM.getElementValueCurrent(filterDog); + let commands = dogs[idDog]; + let filterCommand = document.querySelector(idFormFilters + ' .' + flagCommand); + let idCommandPrevious = filterCommand.getAttribute(attrValuePrevious); + filterCommand.innerHTML = ''; + let optionJson, option; + option = DOM.createOption(null); + filterCommand.appendChild(option); + commands.forEach((command) => { + optionJson = BusinessObjects.getOptionJsonFromObjectJson(command, idCommandPrevious); + option = DOM.createOption(optionJson); + filterCommand.appendChild(option); + }); + filterCommand.dispatchEvent(new Event('change')); + }); + */ + } + hookupFilterCommand() { + this.hookupFilter(attrIdCommand); + } + + loadRowTable(rowJson) { + if (rowJson == null) return; + if (_verbose) { console.log("applying data row: ", rowJson); } + /* + let tableMain = TableBasePage.getTableMain(); + let row = _rowBlank.cloneNode(true); + row.classList.remove(flagRowNew); + let dllDog = row.querySelector('td.' + flagDog + ' select'); + dllDog.value = rowJson[attrIdDog]; + let ddlCommand = row.querySelector('td.' + flagCommand + ' select'); + let optionJson, option; + listCommands.forEach(function(command) { + if (command[attrIdDog] != rowJson[attrIdDog]) return; + optionJson = BusinessObjects.getOptionJsonFromObjectJson(command); + option = DOM.createOption(optionJson, rowJson[attrIdCommand]); + ddlCommand.appendChild(option); + }); + ddlCommand.value = rowJson[attrIdCommand]; + row.querySelector('td.' + flagCommandVariations + ' textarea').value = rowJson[flagCommandVariations]; + let tdCommandVariations = row.querySelector('td.' + flagCommandVariations); + let textareaCommandVariations = tdCommandVariations.querySelector('textarea'); + DOM.setElementValuesCurrentAndPrevious(textareaCommandVariations, rowJson[flagCommandVariations]); + let thCommandVariations = row.querySelector('td.' + flagCommandVariations); + if (!thCommandVariations.classList.contains(flagCollapsed)) tdCommandVariations.classList.remove(flagCollapsed); + let inputDescription = row.querySelector('td.' + flagDescription + ' textarea'); + DOM.setElementValuesCurrentAndPrevious(inputDescription, rowJson[flagDescription]); + let inputCostLocal = row.querySelector('td.' + flagCostLocal + ' input'); + DOM.setElementValuesCurrentAndPrevious(inputCostLocal, rowJson[flagCostLocal]); + let tdCurrencyCost = row.querySelector('td.' + flagCurrencyCost); + DOM.setElementAttributesValuesCurrentAndPrevious(tdCurrencyCost, rowJson[flagCurrencyCost]); + let ddlCurrencyCost = tdCurrencyCost.querySelector('select'); + DOM.setElementValuesCurrentAndPrevious(ddlCurrencyCost, rowJson[flagCurrencyCost]); + let inputProfitLocalMin = row.querySelector('td.' + flagProfitLocalMin + ' input'); + DOM.setElementValuesCurrentAndPrevious(inputProfitLocalMin, rowJson[flagProfitLocalMin]); + let inputLatencyManufactureDays = row.querySelector('td.' + flagLatencyManufacture + ' input'); + DOM.setElementValuesCurrentAndPrevious(inputLatencyManufactureDays, rowJson[flagLatencyManufacture]); + let inputQuantityStock = row.querySelector('td.' + flagQuantityStock + ' input'); + DOM.setElementValuesCurrentAndPrevious(inputQuantityStock, rowJson[flagQuantityStock]); + let inputQuantityMin = row.querySelector('td.' + flagQuantityMin + ' input'); + DOM.setElementValuesCurrentAndPrevious(inputQuantityMin, rowJson[flagQuantityMin]); + let inputQuantityMax = row.querySelector('td.' + flagQuantityMax + ' input'); + DOM.setElementValuesCurrentAndPrevious(inputQuantityMax, rowJson[flagQuantityMax]); + let inputQuantityStep = row.querySelector('td.' + flagCountUnitMeasurementPerQuantityStep + ' input'); + DOM.setElementValuesCurrentAndPrevious(inputQuantityStep, rowJson[flagCountUnitMeasurementPerQuantityStep]); + + + + row.querySelector('td.' + flagQuantityStock + ' input').value = rowJson[flagQuantityStock]; + row.querySelector('td.' + flagQuantityMin + ' input').value = rowJson[flagQuantityMin]; + row.querySelector('td.' + flagQuantityMax + ' input').value = rowJson[flagQuantityMax]; + row.querySelector('td.' + flagCostLocal).innerHTML = rowJson[flagCostLocal]; + row.setAttribute(attrIdDog, rowJson[flagDog]); + row.setAttribute(attrIdCommand, rowJson[flagCommand]); + row.setAttribute(attrIdDogCommandLink, rowJson[attrIdDogCommandLink]); + let tbody = tableMain.querySelector('tbody'); + tbody.appendChild(row); + */ + } + getJsonRow(row) { + if (row == null) return; + let tdDog = row.querySelector('td.' + flagDog); + let tdCommand = row.querySelector('td.' + flagCommand); + let inputHandSignalDescription = row.querySelector('td.' + flagHandSignalDescription + ' textarea'); + let inputNotes = row.querySelector('td.' + flagNotes + ' textarea'); + let buttonActive = row.querySelector(':scope > td.' + flagActive + ' button'); + + let jsonRow = {}; + jsonRow[attrIdDogCommandLink] = row.getAttribute(attrIdDogCommandLink); + jsonRow[attrIdDog] = tdDog.getAttribute(attrValueCurrent); + jsonRow[attrIdCommand] = tdCommand.getAttribute(attrValueCurrent); + jsonRow[flagHandSignalDescription] = inputHandSignalDescription.getAttribute(attrValueCurrent); + jsonRow[flagNotes] = inputNotes.getAttribute(attrValueCurrent); + jsonRow[flagActive] = buttonActive.classList.contains(flagDelete); + return jsonRow; + } + initialiseRowNew(tbody, row) { + this.initialiseRowNewDdlsDogAndCommand(row); + /* + let checkboxIsSubscription = row.querySelector('td.' + flagIsSubscription + ' input'); + let checkboxDoesExpireFasterOnceUnsealed = row.querySelector('td.' + flagDoesExpireFasterOnceUnsealed + ' input'); + this.handleChangeCheckboxDoesExpireFasterOnceUnsealed(null, checkboxDoesExpireFasterOnceUnsealed); + this.handleChangeCheckboxIsSubscription(null, checkboxIsSubscription); + */ + } + initialiseRowNewDdlsDogAndCommand(row) { + let ddlDogFilter = document.querySelector(idFormFilters + ' #' + attrIdDog); + let idDogFilter = DOM.getElementValueCurrent(ddlDogFilter); + let hasDogFilter = !(Validation.isEmpty(idDogFilter) || idDogFilter == '0'); + let ddlCommandFilter = document.querySelector(idFormFilters + ' #' + attrIdCommand); + let idCommandFilter = DOM.getElementValueCurrent(ddlCommandFilter); + let hasCommandFilter = !(Validation.isEmpty(idCommandFilter) || idCommandFilter == '0'); + if (_verbose) { + console.log("initialiseRowNew: ", row); + console.log({ddlDogFilter, idDogFilter, hasDogFilter, ddlCommandFilter, idCommandFilter, hasCommandFilter}); + } + if (!hasDogFilter && !hasCommandFilter) return; + if (hasDogFilter) { + let ddlDog = row.querySelector('td.' + flagDog + ' select'); + DOM.setElementValuesCurrentAndPrevious(ddlDog, idDogFilter); + this.handleChangeDogDdl(null, ddlDog); + } + if (hasCommandFilter) { + let ddlCommand = row.querySelector('td.' + flagCommand + ' select'); + DOM.setElementValuesCurrentAndPrevious(ddlCommand, idCommandFilter); + } + } + + hookupTableMain() { + super.hookupTableMain(); + this.hookupFieldsDog(); + this.hookupFieldsCommand(); + this.hookupTextareasHandSignalDescription(); + this.hookupTextareasNotes(); + this.hookupFieldsActive(); + } + hookupTextareasHandSignalDescription() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagHandSignalDescription + ' textarea'); + } + hookupTextareasNotes() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagNotes + ' textarea'); + } + + leave() { + super.leave(); + } +} + diff --git a/static/js/pages/dog/dogs.js b/static/js/pages/dog/dogs.js new file mode 100644 index 0000000..609b1f5 --- /dev/null +++ b/static/js/pages/dog/dogs.js @@ -0,0 +1,132 @@ + +import Events from "../../lib/events.js"; +import TableBasePage from "../base_table.js"; +import API from "../../api.js"; +import DOM from "../../dom.js"; +import DogTableMixinPage from "./mixin_table.js"; + +export default class PageDogDogs extends TableBasePage { + static hash = hashPageDogDogs; + static attrIdRowObject = attrIdDog; + callSaveTableContent = API.saveDogs; + + constructor(router) { + super(router); + this.dogMixin = new DogTableMixinPage(this); + } + + initialize() { + this.sharedInitialize(); + } + + hookupFilters() { + this.sharedHookupFilters(); + this.hookupFilterIsNotEmpty(); + this.hookupFilterActive(); + } + hookupFilterIsNotEmpty() { + this.hookupEventHandler("change", idFormFilters + ' .' + flagIsNotEmpty, (event, filter) => { + PageDogDogs.isDirtyFilter(filter); + }); + } + + loadRowTable(rowJson) { + if (rowJson == null) return; + if (_verbose) { console.log("applying data row: ", rowJson); } + let row = _rowBlank.cloneNode(true); + row.classList.remove(flagRowNew); + row.classList.remove(flagInitialised); + row.querySelectorAll('.' + flagInitialised).forEach(function(element) { + element.classList.remove(flagInitialised); + }); + let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); + let textareaCode = row.querySelector('td.' + flagCode + ' textarea'); + let textareaName = row.querySelector('td.' + flagName + ' textarea'); + let textareaDescription = row.querySelector('td.' + flagDescription + ' textarea'); + let tdAccessLevel = row.querySelector('td.' + flagAccessLevel); + let divAccessLevel = tdAccessLevel.querySelector('div.' + flagAccessLevel); + let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]'); + + DOM.setElementValuesCurrentAndPrevious(sliderDisplayOrder, rowJson[flagDisplayOrder]); + DOM.setElementValuesCurrentAndPrevious(textareaCode, rowJson[flagCode]); + DOM.setElementValuesCurrentAndPrevious(textareaName, rowJson[flagName]); + DOM.setElementValuesCurrentAndPrevious(textareaDescription, rowJson[flagDescription]); + tdAccessLevel.setAttribute(attrIdAccessLevel, rowJson[attrIdAccessLevel]); + tdAccessLevel.setAttribute(flagAccessLevelRequired, rowJson[flagAccessLevelRequired]); + divAccessLevel.setAttribute(attrIdAccessLevel, rowJson[attrIdAccessLevel]); + DOM.setElementValuesCurrentAndPrevious(divAccessLevel, rowJson[attrIdAccessLevel]); + divAccessLevel.textContent = rowJson[flagAccessLevelRequired]; + DOM.setElementValuesCurrentAndPrevious(inputActive, rowJson[flagActive]); + row.setAttribute(rowJson[flagKeyPrimary], rowJson[rowJson[flagKeyPrimary]]); + + let table = TableBasePage.getTableMain(); + let bodyTable = table.querySelector('tbody'); + bodyTable.appendChild(row); + } + getJsonRow(row) { + if (row == null) return; + let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); + let textareaCode = row.querySelector('td.' + flagCode + ' textarea'); + let textareaName = row.querySelector('td.' + flagName + ' textarea'); + let textareaDescription = row.querySelector('td.' + flagDescription + ' textarea'); + let tdAccessLevel = row.querySelector('td.' + flagAccessLevel); + let buttonActive = row.querySelector(':scope > td.' + flagActive + ' button'); + + let jsonDog = {}; + jsonDog[attrIdDog] = row.getAttribute(attrIdDog); + jsonDog[flagCode] = DOM.getElementAttributeValueCurrent(textareaCode); + jsonDog[flagName] = DOM.getElementAttributeValueCurrent(textareaName); + jsonDog[flagDescription] = DOM.getElementAttributeValueCurrent(textareaDescription); + // jsonDog[flagAccessLevelRequired] = tdAccessLevel.getAttribute(flagAccessLevelRequired); + jsonDog[attrIdAccessLevel] = DOM.getElementAttributeValueCurrent(tdAccessLevel); + jsonDog[flagActive] = buttonActive.classList.contains(flagDelete); + jsonDog[flagDisplayOrder] = DOM.getElementAttributeValueCurrent(sliderDisplayOrder); + return jsonDog; + } + initialiseRowNew(tbody, row) { + if (row == null) return; + this.initialiseSliderDisplayOrderRowNew(tbody, row); + } + + hookupTableMain() { + super.hookupTableMain(); + this.hookupSlidersDisplayOrderTable(); + this.hookupTextareasCodeTable(); + this.hookupTextareasNameTable(); + this.hookupTextareasDescriptionTable(); + this.hookupTdsAccessLevel(); + this.hookupFieldsActive(); + } + + /* + isDirtyRow(row) { + if (row == null) return false; + console.log("Product Dog isDirtyRow"); + console.log("row: ", row); + let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder); + let inputCode = row.querySelector('td.' + flagCode + ' textarea'); + let inputName = row.querySelector('td.' + flagName + ' textarea'); + let inputDescription = row.querySelector('td.' + flagDescription + ' textarea'); + let tdAccessLevel = row.querySelector('td.' + flagAccessLevel); + let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]'); + let isDirty = sliderDisplayOrder.classList.contains(flagDirty) || inputCode.classList.contains(flagDirty) || inputName.classList.contains(flagDirty) || + inputDescription.classList.contains(flagDirty) || tdAccessLevel.classList.contains(flagDirty) || inputActive.classList.contains(flagDirty); + DOM.handleDirtyElement(row, isDirty); + return isDirty; + } + */ + + leave() { + super.leave(); + } + + /* + getFiltersDefaults() { + filters = {}; + filters.flagIsNotEmpty = true; + filters.flagActive = true; + return filters; + } + */ +} + diff --git a/static/js/pages/dog/home.js b/static/js/pages/dog/home.js new file mode 100644 index 0000000..7f017a8 --- /dev/null +++ b/static/js/pages/dog/home.js @@ -0,0 +1,20 @@ + +import BasePage from "../base.js"; + +export default class PageDogHome extends BasePage { + static hash = hashPageDogHome; + + constructor(router) { + super(router); + } + + initialize() { + this.sharedInitialize(); + this.hookupFiltersDog(); + this.hookupDogHome(); + } + + leave() { + super.leave(); + } +} diff --git a/static/js/pages/dog/manufacturing_purchase_orders.js b/static/js/pages/dog/manufacturing_purchase_orders.js new file mode 100644 index 0000000..815c1c0 --- /dev/null +++ b/static/js/pages/dog/manufacturing_purchase_orders.js @@ -0,0 +1,509 @@ + +import API from "../../api.js"; +import BusinessObjects from "../../lib/business_objects/business_objects.js"; +import DOM from "../../dom.js"; +import Events from "../../lib/events.js"; +import ProductPermutation from "../../lib/business_objects/dog/product_permutation.js"; +import TableBasePage from "../base_table.js"; +import Utils from "../../lib/utils.js"; +import Validation from "../../lib/validation.js"; +import DogTableMixinPage from "./mixin_table.js"; + +export default class PageDogManufacturingPurchaseOrders extends TableBasePage { + static hash = hashPageDogManufacturingPurchaseOrders; + static attrIdRowObject = attrIdManufacturingPurchaseOrder; + callSaveTableContent = API.saveManufacturingPurchaseOrders; + + constructor(router) { + super(router); + this.dogMixin = new DogTableMixinPage(this); + } + + initialize() { + this.sharedInitialize(); + } + + hookupFilters() { + this.sharedHookupFilters(); + this.hookupFilterActive(); + } + + loadRowTable(rowJson) { + } + getJsonRow(row) { + if (row == null) return; + let tdCurrency = row.querySelector('td.' + flagCurrency); + let inputCostTotalLocalVatExcl = row.querySelector('td.' + flagCostTotalLocalVatExcl + ' input'); + let inputCostTotalLocalVatIncl = row.querySelector('td.' + flagCostTotalLocalVatIncl + ' input'); + let inputPriceTotalLocalVatExcl = row.querySelector('td.' + flagPriceTotalLocalVatExcl + ' input'); + let inputPriceTotalLocalVatIncl = row.querySelector('td.' + flagPriceTotalLocalVatIncl + ' input'); + let trsPurchaseOrderItem = row.querySelectorAll('tr.' + flagOrderItems); + let buttonActive = row.querySelector(':scope > td.' + flagActive + ' button'); + + let jsonRow = {}; + jsonRow[attrIdManufacturingPurchaseOrder] = row.getAttribute(attrIdManufacturingPurchaseOrder); + jsonRow[attrIdCurrency] = DOM.getElementAttributeValueCurrent(tdCurrency); + jsonRow[flagCostTotalLocalVatExcl] = DOM.getElementAttributeValueCurrent(inputCostTotalLocalVatExcl); + jsonRow[flagCostTotalLocalVatIncl] = DOM.getElementAttributeValueCurrent(inputCostTotalLocalVatIncl); + jsonRow[flagPriceTotalLocalVatExcl] = DOM.getElementAttributeValueCurrent(inputPriceTotalLocalVatExcl); + jsonRow[flagPriceTotalLocalVatIncl] = DOM.getElementAttributeValueCurrent(inputPriceTotalLocalVatIncl); + let orderItems = []; + if (trsPurchaseOrderItem != null) { + trsPurchaseOrderItem.forEach((tr) => { + orderItems.push(this.getJsonRowOrderItem(tr)); + }); + } + jsonRow[flagOrderItems] = orderItems; + jsonRow[flagActive] = buttonActive.classList.contains(flagDelete); + return jsonRow; + } + getJsonRowOrderItem(tr) { + let inputDisplayOrder = tr.querySelector('td.' + flagDisplayOrder + ' input'); + let tdCategory = tr.querySelector('td.' + flagProductCategory); + let tdProduct = tr.querySelector('td.' + flagProduct); + let tdVariations = tr.querySelector('td.' + flagProductVariations); + let tdUnitQuantity = tr.querySelector('td.' + flagUnitMeasurementQuantity); + let inputQuantityUsed = tr.querySelector('td.' + flagQuantityUsed + ' input'); + let inputQuantityProduced = tr.querySelector('td.' + flagQuantityProduced + ' input'); + let tdUnitMeasurementLatencyManufacture = tr.querySelector('td.' + flagUnitMeasurementLatencyManufacture); + let inputLatencyManufacture = tr.querySelector('td.' + flagLatencyManufacture + ' input'); + let buttonActive = tr.querySelector(':scope > td.' + flagActive + ' button'); + + let jsonRow = {}; + jsonRow[attrIdManufacturingPurchaseOrder] = tr.getAttribute(attrIdManufacturingPurchaseOrder); + jsonRow[attrIdManufacturingPurchaseOrderProductLink] = tr.getAttribute(attrIdManufacturingPurchaseOrderProductLink); + jsonRow[flagDisplayOrder] = DOM.getElementAttributeValueCurrent(inputDisplayOrder); + jsonRow[attrIdProductCategory] = DOM.getElementAttributeValueCurrent(tdCategory); + jsonRow[attrIdProduct] = DOM.getElementAttributeValueCurrent(tdProduct); + jsonRow[flagProductVariations] = DOM.getElementAttributeValueCurrent(tdVariations); + jsonRow[attrIdUnitMeasurementQuantity] = DOM.getElementAttributeValueCurrent(tdUnitQuantity); + jsonRow[flagQuantityUsed] = DOM.getElementAttributeValueCurrent(inputQuantityUsed); + jsonRow[flagQuantityProduced] = DOM.getElementAttributeValueCurrent(inputQuantityProduced); + jsonRow[attrIdUnitMeasurementLatencyManufacture] = DOM.getElementAttributeValueCurrent(tdUnitMeasurementLatencyManufacture); + jsonRow[flagLatencyManufacture] = DOM.getElementAttributeValueCurrent(inputLatencyManufacture); + jsonRow[flagActive] = buttonActive.classList.contains(flagDelete); + + return jsonRow; + } + initialiseRowNew(tbody, row) { + super.initialiseRowNew(tbody, row); + } + + hookupTableMain() { + super.hookupTableMain(); + this.hookupCurrencyFields(); + this.hookupCostAndPriceInputs(); + this.hookupOrderItemsFields(); + this.hookupFieldsActive(); + } + hookupCostAndPriceInputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostTotalLocalVatExcl + ' input'); + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostTotalLocalVatIncl + ' input'); + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagPriceTotalLocalVatExcl + ' input'); + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagPriceTotalLocalVatIncl + ' input'); + } + hookupOrderItemsFields() { + this.hookupOrderItemsPreviews(); + this.hookupFieldsOrderItemDisplayOrder(); + this.hookupFieldsOrderItemProductCategory(); + this.hookupFieldsOrderItemProduct(); + this.hookupFieldsOrderItemProductVariations(); + this.hookupFieldsOrderItemUnitQuantity(); + this.hookupFieldsOrderItemQuantityUsed(); + this.hookupFieldsOrderItemQuantityProduced(); + this.hookupFieldsOrderItemUnitMeasurementLatencyManufacture(); + this.hookupFieldsOrderItemLatencyManufacture(); + this.hookupFieldsOrderItemActive(); + this.hookupFieldsOrderItemAddDelete(); + this.hookupButtonsOrderItemAdd(); + } + hookupOrderItemsPreviews() { + this.hookupEventHandler("click", idTableMain + ' td.' + flagOrderItems, (event, td) => { + if (!td.classList.contains(flagCollapsed)) return; + this.handleClickOrderItemsPreview(event, td); + }); + } + handleClickOrderItemsPreview(event, element) { + if (_verbose) { console.log("click order items preview"); } + this.toggleColumnHeaderCollapsed(flagOrderItems, false); + element.classList.remove(flagCollapsed); + let row = DOM.getRowFromElement(element); + let idManufacturingPurchaseOrder = row.getAttribute(attrIdManufacturingPurchaseOrder); + let manufacturingPurchaseOrder = idManufacturingPurchaseOrder > 0 ? manufacturingPurchaseOrders[idManufacturingPurchaseOrder] : { + [flagOrderItems]: [], + }; + let tblOrderItems = document.createElement("table"); + tblOrderItems.classList.add(flagOrderItems); + let thead = document.createElement("thead"); + let tr = document.createElement("tr"); + + let thDisplayOrder = document.createElement("th"); + thDisplayOrder.classList.add(flagDisplayOrder); + thDisplayOrder.textContent = 'Display Order'; + let thCategory = document.createElement("th"); + thCategory.classList.add(flagProductCategory); + thCategory.textContent = 'Category'; + let thProduct = document.createElement("th"); + thProduct.classList.add(flagProduct); + thProduct.textContent = 'Product'; + let thVariations = document.createElement("th"); + thVariations.classList.add(flagProductVariations); + thVariations.classList.add(flagCollapsed); + thVariations.textContent = 'Variations'; + let thUnitQuantity = document.createElement("th"); + thUnitQuantity.classList.add(flagUnitMeasurementQuantity); + thUnitQuantity.textContent = 'Unit Quantity'; + let thQuantityUsed = document.createElement("th"); + thQuantityUsed.classList.add(flagQuantityUsed); + thQuantityUsed.textContent = 'Quantity Used'; + let thQuantityProduced = document.createElement("th"); + thQuantityProduced.classList.add(flagQuantityProduced); + thQuantityProduced.textContent = 'Quantity Produced'; + /* + let thCostTotalLocalVatExcl = document.createElement("th"); + thCostTotalLocalVatExcl.classList.add(flagCostTotalLocalVatExcl); + thCostTotalLocalVatExcl.textContent = 'Cost Total Local VAT Excl'; + let thCostTotalLocalVatIncl = document.createElement("th"); + thCostTotalLocalVatIncl.classList.add(flagCostTotalLocalVatIncl); + thCostTotalLocalVatIncl.textContent = 'Cost Total Local VAT Incl'; + let thCostUnitLocalVatExcl = document.createElement("th"); + thCostUnitLocalVatExcl.classList.add(flagCostUnitLocalVatExcl); + thCostUnitLocalVatExcl.textContent = 'Cost Unit Local VAT Excl'; + let thCostUnitLocalVatIncl = document.createElement("th"); + thCostUnitLocalVatIncl.classList.add(flagCostUnitLocalVatIncl); + thCostUnitLocalVatIncl.textContent = 'Cost Unit Local VAT Incl'; + */ + let thUnitMeasurementLatencyManufacture = document.createElement("th"); + thUnitMeasurementLatencyManufacture.classList.add(flagUnitMeasurementLatencyManufacture); + thUnitMeasurementLatencyManufacture.textContent = 'Unit Measurement Latency Manufacture'; + let thLatencyManufacture = document.createElement("th"); + thLatencyManufacture.classList.add(flagLatencyManufacture); + thLatencyManufacture.textContent = 'Latency Manufacture'; + let thActive = document.createElement("th"); + thActive.classList.add(flagActive); + thActive.textContent = 'Active'; + let thAddDelete = document.createElement("th"); + thAddDelete.classList.add(flagAdd); + let buttonAdd = document.createElement("button"); + buttonAdd.classList.add(flagAdd); + buttonAdd.textContent = '+'; + thAddDelete.appendChild(buttonAdd); + + tr.appendChild(thDisplayOrder); + tr.appendChild(thCategory); + tr.appendChild(thProduct); + tr.appendChild(thVariations); + tr.appendChild(thUnitQuantity); + tr.appendChild(thQuantityUsed); + tr.appendChild(thQuantityProduced); + /* + tr.appendChild(thCostTotalLocalVatExcl); + tr.appendChild(thCostTotalLocalVatIncl); + tr.appendChild(thCostUnitLocalVatExcl); + tr.appendChild(thCostUnitLocalVatIncl); + */ + tr.appendChild(thUnitMeasurementLatencyManufacture); + tr.appendChild(thLatencyManufacture); + tr.appendChild(thActive); + tr.appendChild(thAddDelete); + thead.appendChild(tr); + tblOrderItems.appendChild(thead); + + let tbody = document.createElement("tbody"); + manufacturingPurchaseOrder[flagOrderItems].forEach((orderItem, index) => { + this.addRowManufacturingPurchaseOrderItem(tbody, orderItem); + }); + tblOrderItems.appendChild(tbody); + + let cell = DOM.getCellFromElement(element); + let cellNew = cell.cloneNode(false); + cellNew.appendChild(tblOrderItems); + row.replaceChild(cellNew, cell); + if (_verbose) { console.log("tblOrderItems: ", tblOrderItems); } + this.hookupOrderItemsFields(); + } + addRowManufacturingPurchaseOrderItem(tbody, orderItem) { // productVariationTypeOptions, productVariationOptions, productCategoryOptions, productOptions, unitMeasurementOptions, + if (_verbose) { console.log("addRowManufacturingPurchaseOrderItem: ", orderItem); } + let tdDisplayOrder = document.createElement("td"); + tdDisplayOrder.classList.add(flagDisplayOrder); + let inputDisplayOrder = document.createElement("input"); + inputDisplayOrder.classList.add(flagDisplayOrder); + inputDisplayOrder.type = 'number'; + inputDisplayOrder.step = 1; + DOM.setElementValuesCurrentAndPrevious(inputDisplayOrder, orderItem[flagDisplayOrder]); + tdDisplayOrder.appendChild(inputDisplayOrder); + + let tdCategory = document.createElement("td"); + tdCategory.classList.add(flagProductCategory); + DOM.setElementAttributesValuesCurrentAndPrevious(tdCategory, orderItem[attrIdProductCategory]); + let divCategory = document.createElement("div"); + divCategory.classList.add(flagProductCategory); + // DOM.setElementAttributesValuesCurrentAndPrevious(divCategory, orderItem[attrIdProductCategory]); + let productCategory = productCategories[orderItem[attrIdProductCategory]]; + divCategory.textContent = BusinessObjects.getObjectText(productCategory); + tdCategory.appendChild(divCategory); + + let tdProduct = document.createElement("td"); + tdProduct.classList.add(flagProduct); + DOM.setElementAttributesValuesCurrentAndPrevious(tdProduct, orderItem[attrIdProductCategory]); + let divProduct = document.createElement("div"); + divProduct.classList.add(flagProduct); + // DOM.setElementAttributesValuesCurrentAndPrevious(divProduct, orderItem[attrIdProduct]); + let product = products[orderItem[attrIdProduct]]; + divProduct.textContent = BusinessObjects.getObjectText(product); + tdProduct.appendChild(divProduct); + + let tdVariations = document.createElement("td"); + tdVariations.classList.add(flagProductVariations); + tdVariations.classList.add(flagCollapsed); + DOM.setElementAttributesValuesCurrentAndPrevious(tdVariations, orderItem[attrIdProductCategory]); + let divVariations = document.createElement("div"); + divVariations.classList.add(flagProductVariations); + // DOM.setElementAttributesValuesCurrentAndPrevious(divVariations, orderItem[attrIdProductVariation]); + let variationsText = ProductPermutation.getProductVariationsPreviewFromIdCsv(orderItem[flagProductVariations]); + divVariations.textContent = variationsText; + tdVariations.appendChild(divVariations); + + let tdUnitQuantity = document.createElement("td"); + tdUnitQuantity.classList.add(flagUnitMeasurementQuantity); + DOM.setElementAttributesValuesCurrentAndPrevious(tdUnitQuantity, orderItem[attrIdProductCategory]); + let divUnitQuantity = document.createElement("div"); + divUnitQuantity.classList.add(flagUnitMeasurementQuantity); + // DOM.setElementValuesCurrentAndPrevious(divUnitQuantity, orderItem[flagUnitMeasurementQuantity]); + let unitQuantity = unitMeasurements[orderItem[attrIdUnitMeasurementQuantity]]; + divUnitQuantity.textContent = BusinessObjects.getObjectText(unitQuantity); + tdUnitQuantity.appendChild(divUnitQuantity); + + let tdQuantityUsed = document.createElement("td"); + tdQuantityUsed.classList.add(flagQuantityUsed); + let inputQuantityUsed = document.createElement("input"); + inputQuantityUsed.classList.add(flagQuantityUsed); + inputQuantityUsed.type = 'number'; + DOM.setElementValuesCurrentAndPrevious(inputQuantityUsed, orderItem[flagQuantityUsed]); + tdQuantityUsed.appendChild(inputQuantityUsed); + + let tdQuantityProduced = document.createElement("td"); + tdQuantityProduced.classList.add(flagQuantityProduced); + let inputQuantityProduced = document.createElement("input"); + inputQuantityProduced.classList.add(flagQuantityProduced); + inputQuantityProduced.type = 'number'; + DOM.setElementValuesCurrentAndPrevious(inputQuantityProduced, orderItem[flagQuantityProduced]); + tdQuantityProduced.appendChild(inputQuantityProduced); + + /* + let tdCostTotalLocalVatExcl = document.createElement("td"); + tdCostTotalLocalVatExcl.classList.add(flagCostTotalLocalVatExcl); + let inputCostTotalLocalVatExcl = document.createElement("input"); + inputCostTotalLocalVatExcl.classList.add(flagCostTotalLocalVatExcl); + inputCostTotalLocalVatExcl.type = 'number'; + inputCostTotalLocalVatExcl.step = 0.01; + DOM.setElementAttributesValuesCurrentAndPrevious(inputCostTotalLocalVatExcl, orderItem[flagCostTotalLocalVatExcl]); + tdCostTotalLocalVatExcl.appendChild(inputCostTotalLocalVatExcl); + + let tdCostTotalLocalVatIncl = document.createElement("td"); + tdCostTotalLocalVatIncl.classList.add(flagCostTotalLocalVatIncl); + let inputCostTotalLocalVatIncl = document.createElement("input"); + inputCostTotalLocalVatIncl.classList.add(flagCostTotalLocalVatIncl); + inputCostTotalLocalVatIncl.type = 'number'; + inputCostTotalLocalVatIncl.step = 0.01; + DOM.setElementAttributesValuesCurrentAndPrevious(inputCostTotalLocalVatIncl, orderItem[flagCostTotalLocalVatIncl]); + tdCostTotalLocalVatIncl.appendChild(inputCostTotalLocalVatIncl); + + let tdCostUnitLocalVatExcl = document.createElement("td"); + tdCostUnitLocalVatExcl.classList.add(flagCostUnitLocalVatExcl); + let divCostUnitLocalVatExcl = document.createElement("div"); + divCostUnitLocalVatExcl.classList.add(flagCostUnitLocalVatExcl); + DOM.setElementValuesCurrentAndPrevious(divCostUnitLocalVatExcl, orderItem[flagCostUnitLocalVatExcl]); + tdCostUnitLocalVatExcl.appendChild(divCostUnitLocalVatExcl); + + let tdCostUnitLocalVatIncl = document.createElement("td"); + tdCostUnitLocalVatIncl.classList.add(flagCostUnitLocalVatIncl); + let divCostUnitLocalVatIncl = document.createElement("div"); + divCostUnitLocalVatIncl.classList.add(flagCostUnitLocalVatIncl); + DOM.setElementValuesCurrentAndPrevious(divCostUnitLocalVatIncl, orderItem[flagCostUnitLocalVatIncl]); + tdCostUnitLocalVatIncl.appendChild(divCostUnitLocalVatIncl); + */ + + let tdUnitMeasurementLatencyManufacture = document.createElement("td"); + tdUnitMeasurementLatencyManufacture.classList.add(flagUnitMeasurementLatencyManufacture); + DOM.setElementAttributesValuesCurrentAndPrevious(tdUnitMeasurementLatencyManufacture, orderItem[attrIdUnitMeasurementLatencyManufacture]); + let divUnitMeasurementLatencyManufacture = document.createElement("div"); + divUnitMeasurementLatencyManufacture.classList.add(flagUnitMeasurementLatencyManufacture); + // DOM.setElementValuesCurrentAndPrevious(divUnitMeasurementLatencyManufacture, orderItem[flagUnitMeasurementLatencyManufacture]); + let unitMeasurementLatencyManufacture = unitMeasurementsTime[orderItem[attrIdUnitMeasurementLatencyManufacture]]; + divUnitMeasurementLatencyManufacture.textContent = BusinessObjects.getObjectText(unitMeasurementLatencyManufacture); + tdUnitMeasurementLatencyManufacture.appendChild(divUnitMeasurementLatencyManufacture); + + let tdLatencyManufacture = document.createElement("td"); + tdLatencyManufacture.classList.add(flagLatencyManufacture); + let inputLatencyManufacture = document.createElement("input"); + inputLatencyManufacture.classList.add(flagLatencyManufacture); + inputLatencyManufacture.type = 'number'; + inputLatencyManufacture.step = 1; + DOM.setElementValuesCurrentAndPrevious(inputLatencyManufacture, orderItem[flagLatencyManufacture]); + tdLatencyManufacture.appendChild(inputLatencyManufacture); + + let tdActive = this.createTdActive(orderItem[flagActive]); + + let tr = document.createElement("tr"); + tr.classList.add(flagOrderItems); + tr.setAttribute(attrIdManufacturingPurchaseOrder, orderItem[attrIdManufacturingPurchaseOrder]); + tr.setAttribute(attrIdManufacturingPurchaseOrderProductLink, orderItem[attrIdManufacturingPurchaseOrderProductLink]); + tr.appendChild(tdDisplayOrder); + tr.appendChild(tdCategory); + tr.appendChild(tdProduct); + tr.appendChild(tdVariations); + tr.appendChild(tdUnitQuantity); + tr.appendChild(tdQuantityUsed); + tr.appendChild(tdQuantityProduced); + /* + tr.appendChild(tdCostTotalLocalVatExcl); + tr.appendChild(tdCostTotalLocalVatIncl); + tr.appendChild(tdCostUnitLocalVatExcl); + tr.appendChild(tdCostUnitLocalVatIncl); + */ + tr.appendChild(tdUnitMeasurementLatencyManufacture); + tr.appendChild(tdLatencyManufacture); + tr.appendChild(tdActive); + tbody.appendChild(tr); + } + hookupFieldsOrderItemDisplayOrder() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagOrderItems + ' td.' + flagDisplayOrder + ' input'); + } + hookupFieldsOrderItemProductCategory() { + this.hookupTableCellDdlPreviews( + idTableMain + ' td.' + flagOrderItems + ' td.' + flagProductCategory + , Utils.getListFromDict(productCategories) + , (cellSelector) => { this.hookupProductCategoryDdls(cellSelector); } + ); + } + hookupFieldsOrderItemProduct() { + this.hookupTableCellDdlPreviews(idTableMain + ' td.' + flagOrderItems + ' td.' + flagProduct, Utils.getListFromDict(products)); + } + hookupFieldsOrderItemProductVariations() { + this.hookupEventHandler("click", idTableMain + ' td.' + flagOrderItems + ' td.' + flagProductVariations, (event, element) => this.handleClickProductPermutationVariationsPreview(event, element)); + } + hookupFieldsOrderItemUnitQuantity() { + this.hookupTableCellDdlPreviews(idTableMain + ' td.' + flagOrderItems + ' td.' + flagUnitMeasurementQuantity, Utils.getListFromDict(unitMeasurements)); + } + hookupFieldsOrderItemQuantityUsed() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagOrderItems + ' td.' + flagQuantityUsed + ' input'); + } + hookupFieldsOrderItemQuantityProduced() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagOrderItems + ' td.' + flagQuantityProduced + ' input'); + } + /* + hookupFieldsOrderItemPriceTotalLocalVatExcl() { + this.hookupChangeHandlerTableCells( + idTableMain + ' td.' + flagOrderItems + ' td.' + flagPriceTotalLocalVatExcl + ' input' + , (event, element) => { + this.handleChangeNestedElementCellTable(event, element); + this.updateFieldsPriceUnitLocalVatExcl(element); + } + ); + } + hookupFieldsOrderItemPriceTotalLocalVatIncl() { + this.hookupChangeHandlerTableCells( + idTableMain + ' td.' + flagOrderItems + ' td.' + flagPriceTotalLocalVatIncl + ' input' + , (event, element) => { + this.handleChangeNestedElementCellTable(event, element); + this.updateFieldsPriceUnitLocalVatIncl(element); + } + ); + } + updateFieldsPriceUnitLocalVatExcl(elementChanged) { + let row = elementChanged.closest('tr.' + flagOrderItems); + let inputPriceTotalLocalVatExcl = row.querySelector('td.' + flagPriceTotalLocalVatExcl + ' input'); + let priceTotalLocalVatExcl = DOM.getElementValueCurrent(inputPriceTotalLocalVatExcl); + let inputQuantityUsed = row.querySelector('td.' + flagQuantityUsed + ' input'); + let quantityUsed = DOM.getElementValueCurrent(inputQuantityUsed); + + let divPriceUnitLocalVatExcl = row.querySelector('td.' + flagPriceUnitLocalVatExcl + ' div'); + let priceUnitLocalVatExcl = quantityUsed == 0 ? 0 : priceTotalLocalVatExcl / quantityUsed; + DOM.setElementValuesCurrentAndPrevious(divPriceUnitLocalVatExcl, priceUnitLocalVatExcl); + + let rowManufacturingPurchaseOrder = row.closest(idTableMain + ' > tbody > tr'); + let divPriceGrandTotalLocalVatExcl = rowManufacturingPurchaseOrder.querySelector('td.' + flagPriceTotalLocalVatExcl + ' div'); + let inputsPriceTotalLocalVatExcl = rowManufacturingPurchaseOrder.querySelectorAll('td.' + flagOrderItems + ' td.' + flagPriceTotalLocalVatExcl + ' input'); + let priceGrandTotalLocalVatExcl = Array.from(inputsPriceTotalLocalVatExcl).reduce((acc, input) => acc + Number(DOM.getElementValueCurrent(input)), 0); + DOM.setElementValueCurrent(divPriceGrandTotalLocalVatExcl, priceGrandTotalLocalVatExcl); + } + updateFieldsPriceUnitLocalVatIncl(elementChanged) { + let row = elementChanged.closest('tr.' + flagOrderItems); + let inputPriceTotalLocalVatIncl = row.querySelector('td.' + flagPriceTotalLocalVatIncl + ' input'); + let priceTotalLocalVatIncl = DOM.getElementValueCurrent(inputPriceTotalLocalVatIncl); + let inputQuantityUsed = row.querySelector('td.' + flagQuantityUsed + ' input'); + let quantityUsed = DOM.getElementValueCurrent(inputQuantityUsed); + + let divPriceUnitLocalVatIncl = row.querySelector('td.' + flagPriceUnitLocalVatIncl + ' div'); + let priceUnitLocalVatIncl = quantityUsed == 0 ? 0 : priceTotalLocalVatIncl / quantityUsed; + DOM.setElementValuesCurrentAndPrevious(divPriceUnitLocalVatIncl, priceUnitLocalVatIncl); + + let rowManufacturingPurchaseOrder = row.closest(idTableMain + ' > tbody > tr'); + let divPriceGrandTotalLocalVatIncl = rowManufacturingPurchaseOrder.querySelector('td.' + flagPriceTotalLocalVatIncl + ' div'); + let inputsPriceTotalLocalVatIncl = rowManufacturingPurchaseOrder.querySelectorAll('td.' + flagOrderItems + ' td.' + flagPriceTotalLocalVatIncl + ' input'); + let priceGrandTotalLocalVatIncl = Array.from(inputsPriceTotalLocalVatIncl).reduce((acc, input) => acc + Number(DOM.getElementValueCurrent(input)), 0); + DOM.setElementValueCurrent(divPriceGrandTotalLocalVatIncl, priceGrandTotalLocalVatIncl); + } + hookupFieldsOrderItemPriceUnitLocalVatExcl() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagOrderItems + ' td.' + flagPriceUnitLocalVatExcl + ' input'); + } + hookupFieldsOrderItemPriceUnitLocalVatIncl() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagOrderItems + ' td.' + flagPriceUnitLocalVatIncl + ' input'); + } + */ + hookupFieldsOrderItemUnitMeasurementLatencyManufacture() { + this.hookupTableCellDdlPreviews(idTableMain + ' td.' + flagOrderItems + ' td.' + flagUnitMeasurementLatencyManufacture, Utils.getListFromDict(unitMeasurementsTime)); + } + hookupFieldsOrderItemLatencyManufacture() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagOrderItems + ' td.' + flagLatencyManufacture + ' input'); + } + hookupFieldsOrderItemActive() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagOrderItems + ' input.' + flagActive); + } + hookupFieldsOrderItemAddDelete() { + let selectorButton = idTableMain + ' td.' + flagOrderItems + ' td.' + flagOrderItems + ' button'; + let selectorButtonDelete = selectorButton + '.' + flagDelete; + let selectorButtonUndelete = selectorButton + '.' + flagAdd; + this.hookupButtonsRowDelete(selectorButtonDelete, selectorButtonUndelete); + this.hookupButtonsRowUndelete(selectorButtonDelete, selectorButtonUndelete); + this.hookupButtonsOrderItemAdd(); + } + hookupButtonsOrderItemAdd() { + this.hookupEventHandler("click", idTableMain + ' td.' + flagOrderItems + ' th button.' + flagAdd, (event, element) => { + let row = element.closest(idTableMain + ' > tbody > tr'); + let idManufacturingPurchaseOrder = row.getAttribute(attrIdManufacturingPurchaseOrder); + // let hasActiveOrderItem = row.querySelectorAll('td.' + flagOrderItems + ' input.' + flagActive + ':checked').length > 0; + let countManufacturingOrderItems = row.querySelectorAll('td.' + flagOrderItems + ' td.' + flagManufacturingPurchaseOrder).length; + let manufacturingPurchaseOrderItem = { + [attrIdManufacturingPurchaseOrder]: idManufacturingPurchaseOrder, + [attrIdManufacturingPurchaseOrderProductLink]: -1 - countManufacturingOrderItems, + [attrIdProductCategory]: 0, + [attrIdProduct]: 0, + [flagProductVariations]: '', + [attrIdUnitMeasurementQuantity]: 0, + [flagQuantityUsed]: '', + [flagQuantityProduced]: '', + [attrIdUnitMeasurementLatencyManufacture]: 0, + [flagLatencyManufacture]: '', + [flagDisplayOrder]: countManufacturingOrderItems + 1, + [flagActive]: true, // !hasActiveOrderItem, + }; + let tbody = row.querySelector('td.' + flagOrderItems + ' table tbody'); + this.addRowManufacturingPurchaseOrderItem(tbody, manufacturingPurchaseOrderItem); + /* + if (!hasActiveOrderItem) { + let tdOrderItem = row.querySelector('td.' + flagOrderItems); + // tdOrderItem.setAttribute(attrIdManufacturingOrderItem, manufacturingPurchaseOrderItem[attrIdManufacturingOrderItem]); + DOM.setElementAttributeValueCurrent(tdOrderItem, manufacturingPurchaseOrderItem[attrIdManufacturingOrderItem]); + } + */ + this.hookupOrderItemsFields(); + }); + } + + leave() { + super.leave(); + } +} + diff --git a/static/js/pages/dog/mixin.js b/static/js/pages/dog/mixin.js new file mode 100644 index 0000000..4610d39 --- /dev/null +++ b/static/js/pages/dog/mixin.js @@ -0,0 +1,54 @@ + +import Events from "../../lib/events.js"; +import LocalStorage from "../../lib/local_storage.js"; +import Validation from "../../lib/validation.js"; +// import BasePage from "../base.js"; +import DOM from "../../dom.js"; +import { isEmpty } from "../../lib/utils.js"; +import TableBasePage from "../base_table.js"; + +export default class DogMixinPage { + constructor(pageCurrent) { + this.page = pageCurrent; + } + + initialize() { + console.log('hookup dog start for ', this.page.hash); + this.hookupFilters(); + this.hookupLocalStorageDog(); + } + hookupFilters() { + } + hookupLocalStorageDog() { + + } + + /* + hookupDogCardsProduct() { + + let d; // , lsShared; + let selectorCardProduct = '.card.subcard'; + Events.initialiseEventHandler(selectorCardProduct, flagInitialised, function(cardProduct) { + if (_verbose) { console.log("initialising product card: ", cardProduct); } + cardProduct.addEventListener("click", function(event) { + // d = { keyIdProduct: product.getAttribute(attrIdProduct) } + var elemClicked = event.target; + if (elemClicked.id != 'submit') { // disable for submit buttons + if (_verbose) { + console.log("product click: " + cardProduct.getAttribute(attrIdProduct)); + console.log("permutation click: " + cardProduct.getAttribute(attrIdPermutation)); + } + var d = {} + d[keyIdProduct] = cardProduct.getAttribute(attrIdProduct) + d[keyIdPermutation] = cardProduct.getAttribute(attrIdPermutation) + // send quantity requested + goToPage(hashPageDogProduct, d); + } + }); + if (_verbose) { console.log("click method added for product ID: " + cardProduct.getAttribute(attrIdProduct) + ', permutation ID: ', cardProduct.getAttribute(attrIdPermutation)); } + }); + } + */ + + leave() {} +} diff --git a/static/js/pages/dog/mixin_table.js b/static/js/pages/dog/mixin_table.js new file mode 100644 index 0000000..d835352 --- /dev/null +++ b/static/js/pages/dog/mixin_table.js @@ -0,0 +1,25 @@ + +import Events from "../../lib/events.js"; +import LocalStorage from "../../lib/local_storage.js"; +import Validation from "../../lib/validation.js"; +// import BasePage from "../base.js"; +import DOM from "../../dom.js"; +import { isEmpty } from "../../lib/utils.js"; +import DogMixinPage from "./mixin.js"; + +export default class DogTableMixinPage extends DogMixinPage { + constructor(pageCurrent) { + super(pageCurrent); + } + initialize() { + super.initialize(); + this.hookupFilters(); + this.hookupTable(); + } + hookupFilters() { + // Implement filter-specific functionality here + } + hookupTable() { + // Implement table-specific functionality here + } +} \ No newline at end of file diff --git a/static/js/pages/dog/product_variations.js b/static/js/pages/dog/product_variations.js new file mode 100644 index 0000000..88a639b --- /dev/null +++ b/static/js/pages/dog/product_variations.js @@ -0,0 +1,240 @@ + +import API from "../../api.js"; +import BusinessObjects from "../../lib/business_objects/business_objects.js"; +import DOM from "../../dom.js"; +import Events from "../../lib/events.js"; +import TableBasePage from "../base_table.js"; +import Utils from "../../lib/utils.js"; +import Validation from "../../lib/validation.js"; +import DogTableMixinPage from "./mixin_table.js"; + +export default class PageDogProductVariations extends TableBasePage { + static hash = hashPageDogProductVariations; + static attrIdRowObject = attrIdProductVariationType; + callSaveTableContent = API.saveProductVariations; + + constructor(router) { + super(router); + this.dogMixin = new DogTableMixinPage(this); + } + + initialize() { + this.sharedInitialize(); + } + + hookupFilters() { + this.sharedHookupFilters(); + this.hookupFilterActive(); + this.hookupFilterIsNotEmpty(); + } + + loadRowTable(rowJson) { + } + getJsonRow(row) { + if (row == null) return; + let inputDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' input'); + let textareaCode = row.querySelector('td.' + flagCode + ' textarea'); + let textareaName = row.querySelector('td.' + flagName + ' textarea'); + let textareaNamePlural = row.querySelector('td.' + flagNamePlural + ' textarea'); + let tdProductVariations = row.querySelector('td.' + flagProductVariations); + let buttonActive = row.querySelector(':scope > td.' + flagActive + ' button'); + + let jsonRow = {}; + jsonRow[attrIdProductVariationType] = row.getAttribute(attrIdProductVariationType); + if (Validation.isEmpty(jsonRow[attrIdProductVariationType])) jsonRow[attrIdProductVariationType] = -1; + jsonRow[flagDisplayOrder] = DOM.getElementAttributeValueCurrent(inputDisplayOrder); + jsonRow[flagCode] = DOM.getElementAttributeValueCurrent(textareaCode); + jsonRow[flagName] = DOM.getElementAttributeValueCurrent(textareaName); + jsonRow[flagNamePlural] = DOM.getElementAttributeValueCurrent(textareaNamePlural); + + let variations = []; + if (tdProductVariations.classList.contains(flagDirty)) { + let trsProductVariation = tdProductVariations.querySelectorAll('tr.' + flagProductVariation + '.' + flagDirty); + if (trsProductVariation != null) { + trsProductVariation.forEach((tr, indexRow) => { + variations.push(this.getJsonRowProductVariation(tr, indexRow)); + }); + } + } + else { + // variations = BusinessObjects.getListObjectsFromIdDictAndCsv(productVariationTypes, DOM.getElementAttributeValueCurrent(tdProductVariations)); + } + jsonRow[flagProductVariations] = variations; + jsonRow[flagActive] = buttonActive.classList.contains(flagDelete); + return jsonRow; + } + getJsonRowProductVariation(tr, indexRow) { + let inputDisplayOrder = tr.querySelector('td.' + flagDisplayOrder + ' input'); + let textareaCode = tr.querySelector('td.' + flagCode + ' textarea'); + let textareaName = tr.querySelector('td.' + flagName + ' textarea'); + // let checkboxActive = tr.querySelector('td.' + flagActive + ' input'); + let buttonActive = tr.querySelector(':scope > td.' + flagActive + ' button'); + + let jsonRow = {}; + jsonRow[attrIdProductVariation] = tr.getAttribute(attrIdProductVariation); + if (Validation.isEmpty(jsonRow[attrIdProductVariation])) jsonRow[attrIdProductVariation] = -1 - indexRow; + jsonRow[attrIdProductVariationType] = tr.getAttribute(attrIdProductVariationType); + jsonRow[flagDisplayOrder] = DOM.getElementAttributeValueCurrent(inputDisplayOrder); + jsonRow[flagCode] = DOM.getElementAttributeValueCurrent(textareaCode); + jsonRow[flagName] = DOM.getElementAttributeValueCurrent(textareaName); + jsonRow[flagActive] = buttonActive.classList.contains(flagDelete); + + return jsonRow; + } + initialiseRowNew(tbody, row) { + super.initialiseRowNew(tbody, row); + this.initialiseSliderDisplayOrderRowNew(tbody, row); + } + + hookupTableMain() { + super.hookupTableMain(); + this.hookupSlidersDisplayOrderTable(); + this.hookupTextareasCodeTable(); + this.hookupTextareasNameTable(); + this.hookupTextareasNamePluralTable(); + this.hookupFieldsProductVariation(); + this.hookupFieldsActive(); + } + hookupTextareasNamePluralTable() { + this.hookupChangeHandlerTableCells(idTableMain + ' tbody tr td.' + flagNamePlural + ' textarea'); + } + hookupFieldsProductVariation() { + this.hookupProductVariationsPreviews(); + this.hookupFieldsProductVariationDisplayOrder(); + this.hookupFieldsProductVariationCode(); + this.hookupFieldsProductVariationName(); + this.hookupFieldsProductVariationActive(); + } + hookupProductVariationsPreviews() { + this.hookupEventHandler("click", idTableMain + ' td.' + flagProductVariations + ' div', (event, element) => { + let td = DOM.getCellFromElement(element); + if (!td.classList.contains(flagCollapsed)) return; + this.handleClickProductVariationsPreview(event, element); + }); + } + handleClickProductVariationsPreview(event, element) { + if (_verbose) { console.log("click order items preview"); } + let row = DOM.getRowFromElement(element); + let idProductVariationType = row.getAttribute(attrIdProductVariationType); + let productVariationType = productVariationTypes[idProductVariationType]; + if (productVariationType == null) productVariationType = { + [flagProductVariations]: [], + }; + let tblProductVariations = document.createElement("table"); + tblProductVariations.classList.add(flagProductVariations); + let thead = document.createElement("thead"); + let tr = document.createElement("tr"); + + let thDisplayOrder = document.createElement("th"); + thDisplayOrder.classList.add(flagDisplayOrder); + thDisplayOrder.textContent = 'Display Order'; + let thCode = document.createElement("th"); + thCode.classList.add(flagCode); + thCode.textContent = 'Code'; + let thName = document.createElement("th"); + thName.classList.add(flagName); + thName.textContent = 'Name'; + let thActive = document.createElement("th"); + thActive.classList.add(flagActive); + // thActive.textContent = 'Active'; + let buttonAdd = document.createElement("button"); + buttonAdd.classList.add(flagActive); + buttonAdd.classList.add(flagAdd); + buttonAdd.textContent = '+'; + thActive.appendChild(buttonAdd); + + tr.appendChild(thDisplayOrder); + tr.appendChild(thCode); + tr.appendChild(thName); + tr.appendChild(thActive); + thead.appendChild(tr); + tblProductVariations.appendChild(thead); + + let tbody = document.createElement("tbody"); + productVariationType[flagProductVariations].forEach((productVariation, index) => { + this.addRowProductVariation(tbody, productVariation); + }); + tblProductVariations.appendChild(tbody); + + let cell = DOM.getCellFromElement(element); + let cellNew = cell.cloneNode(false); + cellNew.appendChild(tblProductVariations); + cellNew.classList.remove(flagCollapsed); + row.replaceChild(cellNew, cell); + if (_verbose) { console.log("tblProductVariations: ", tblProductVariations); } + this.toggleColumnHeaderCollapsed(flagProductVariations, false); + this.hookupFieldsProductVariation(); + } + addRowProductVariation(tbody, productVariation) { + if (_verbose) { console.log("addRowProductVariation: ", productVariation); } + + let tdDisplayOrder = document.createElement("td"); + tdDisplayOrder.classList.add(flagDisplayOrder); + let inputDisplayOrder = document.createElement("input"); + inputDisplayOrder.classList.add(flagDisplayOrder); + inputDisplayOrder.type = 'number'; + inputDisplayOrder.step = 1; + DOM.setElementValuesCurrentAndPrevious(inputDisplayOrder, productVariation[flagDisplayOrder]); + tdDisplayOrder.appendChild(inputDisplayOrder); + + let tdCode = document.createElement("td"); + tdCode.classList.add(flagCode); + let textareaCode = document.createElement("textarea"); + textareaCode.classList.add(flagCode); + DOM.setElementValuesCurrentAndPrevious(textareaCode, productVariation[flagCode]); + tdCode.appendChild(textareaCode); + + let tdName = document.createElement("td"); + tdName.classList.add(flagName); + let textareaName = document.createElement("textarea"); + textareaName.classList.add(flagName); + DOM.setElementValuesCurrentAndPrevious(textareaName, productVariation[flagName]); + tdName.appendChild(textareaName); + + let tdActive = this.createTdActive(productVariation[flagActive]); + + let tr = document.createElement("tr"); + tr.classList.add(flagProductVariation); + tr.setAttribute(attrIdProductVariationType, productVariation[attrIdProductVariationType]); + tr.setAttribute(attrIdProductVariation, productVariation[attrIdProductVariation]); + tr.appendChild(tdDisplayOrder); + tr.appendChild(tdCode); + tr.appendChild(tdName); + tr.appendChild(tdActive); + tbody.appendChild(tr); + } + hookupFieldsProductVariationDisplayOrder() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagProductVariations + ' td.' + flagDisplayOrder + ' input'); + } + hookupFieldsProductVariationCode() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagProductVariations + ' textarea.' + flagCode); + } + hookupFieldsProductVariationName() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagProductVariations + ' textarea.' + flagName); + } + hookupFieldsProductVariationActive() { + this.hookupFieldsActive(flagProductVariations, (event, element) => { this.hookupButtonsProductVariationAdd(event, element); }); + } + hookupButtonsProductVariationAdd(event, element) { + let row = element.closest(idTableMain + ' > tbody > tr'); + let idProductVariationType = row.getAttribute(attrIdProductVariationType); + let idProductVariation = row.getAttribute(attrIdProductVariation); + let countProductVariations = row.querySelectorAll('td.' + flagProductVariations + ' tr').length; + let productVariation = { + [attrIdProductVariationType]: idProductVariationType, + [attrIdProductVariation]: idProductVariation, + [flagCode]: '', + [flagName]: '', + [flagDisplayOrder]: countProductVariations, + [flagActive]: true, + }; + let tbody = row.querySelector('td.' + flagProductVariations + ' table tbody'); + this.addRowProductVariation(tbody, productVariation); + this.hookupFieldsProductVariation(); + } + + leave() { + super.leave(); + } +} + diff --git a/static/js/pages/dog/stock_items.js b/static/js/pages/dog/stock_items.js new file mode 100644 index 0000000..7b33c58 --- /dev/null +++ b/static/js/pages/dog/stock_items.js @@ -0,0 +1,355 @@ + +import API from "../../api.js"; +import BusinessObjects from "../../lib/business_objects/business_objects.js"; +import DOM from "../../dom.js"; +import Events from "../../lib/events.js"; +import TableBasePage from "../base_table.js"; +import Utils from "../../lib/utils.js"; +import Validation from "../../lib/validation.js"; +import DogTableMixinPage from "./mixin_table.js"; + +export default class PageDogStockItems extends TableBasePage { + static hash = hashPageDogStockItems; + static attrIdRowObject = attrIdStockItem; + callSaveTableContent = API.saveStockItems; + + constructor(router) { + super(router); + this.dogMixin = new DogTableMixinPage(this); + } + + initialize() { + this.sharedInitialize(); + } + + hookupFilters() { + this.sharedHookupFilters(); + this.hookupFilterProductCategory(); + this.hookupFilterProduct(); + this.hookupFilterOutOfStock(); + this.hookupFilterMinStock(); + this.hookupFilterMaxStock(); + } + hookupFilterProductCategory() { + this.hookupFilter(flagProductCategory, (event, filterCategory) => { + // loadPermutations(); + // let wasDirtyFilter = filterCategory.classList.contains(flagDirty); + PageDogStockItems.isDirtyFilter(filterCategory); + let isDirtyFilter = filterCategory.classList.contains(flagDirty); + let idProductCategory = DOM.getElementValueCurrent(filterCategory); + let products = productCategories[idProductCategory]; + let filterProduct = document.querySelector(idFormFilters + ' .' + flagProduct); + let idProductPrevious = filterProduct.getAttribute(attrValuePrevious); + filterProduct.innerHTML = ''; + let optionJson, option; + option = DOM.createOption(null); + filterProduct.appendChild(option); + products.forEach((product) => { + optionJson = BusinessObjects.getOptionJsonFromObjectJson(product, idProductPrevious); + option = DOM.createOption(optionJson); + filterProduct.appendChild(option); + }); + filterProduct.dispatchEvent(new Event('change')); + }); + } + hookupFilterProduct() { + this.hookupFilter(flagProduct); + } + hookupFilterOutOfStock() { + this.hookupFilter(flagIsOutOfStock); + } + hookupFilterMinStock() { + this.hookupFilter(flagQuantityMin); + } + hookupFilterMaxStock() { + this.hookupFilter(flagQuantityMax); + } + + loadRowTable(rowJson) { + } + getJsonRow(row) { + if (row == null) return; + let tdProductCategory = row.querySelector('td.' + flagProductCategory); + let tdProduct = row.querySelector('td.' + flagProduct); + let tdProductVariations = row.querySelector('td.' + flagProductVariations); + let tdCurrencyCost = row.querySelector('td.' + flagCurrencyCost); + let inputCostLocalVatExcl = row.querySelector('td.' + flagCostUnitLocalVatExcl + ' input'); + let inputCostLocalVatIncl = row.querySelector('td.' + flagCostUnitLocalVatIncl + ' input'); + let inputDatePurchased = row.querySelector('td.' + flagDatePurchased + ' input'); + let inputDateReceived = row.querySelector('td.' + flagDateReceived + ' input'); + let tdStorageLocation = row.querySelector('td.' + flagStorageLocation); + let inputIsSealed = row.querySelector('td.' + flagIsSealed + ' input'); + let inputDateUnsealed = row.querySelector('td.' + flagDateUnsealed + ' input'); + let inputDateExpiration = row.querySelector('td.' + flagDateExpiration + ' input'); + let inputIsConsumed = row.querySelector('td.' + flagIsConsumed + ' input'); + let inputDateConsumed = row.querySelector('td.' + flagDateConsumed + ' input'); + let buttonActive = row.querySelector(':scope > td.' + flagActive + ' button'); + + let jsonRow = {}; + jsonRow[attrIdStockItem] = row.getAttribute(attrIdStockItem); + jsonRow[attrIdProductPermutation] = tdProductVariations.getAttribute(attrIdProductPermutation); + jsonRow[attrIdProductCategory] = DOM.getElementAttributeValueCurrent(tdProductCategory); + jsonRow[attrIdProduct] = DOM.getElementAttributeValueCurrent(tdProduct); + jsonRow[flagProductVariations] = DOM.getElementAttributeValueCurrent(tdProductVariations); + jsonRow[flagHasVariations] = jsonRow[flagProductVariations] != ''; + jsonRow[flagCurrencyCost] = DOM.getElementAttributeValueCurrent(tdCurrencyCost); + jsonRow[flagCostUnitLocalVatExcl] = DOM.getElementAttributeValueCurrent(inputCostLocalVatExcl); + jsonRow[flagCostUnitLocalVatIncl] = DOM.getElementAttributeValueCurrent(inputCostLocalVatIncl); + jsonRow[flagDatePurchased] = DOM.getElementAttributeValueCurrent(inputDatePurchased); + jsonRow[flagDateReceived] = DOM.getElementAttributeValueCurrent(inputDateReceived); + jsonRow[attrIdStorageLocation] = DOM.getElementAttributeValueCurrent(tdStorageLocation); + jsonRow[flagIsSealed] = DOM.getElementAttributeValueCurrent(inputIsSealed); + jsonRow[flagDateUnsealed] = DOM.getElementAttributeValueCurrent(inputDateUnsealed); + jsonRow[flagDateExpiration] = DOM.getElementAttributeValueCurrent(inputDateExpiration); + jsonRow[flagIsConsumed] = DOM.getElementAttributeValueCurrent(inputIsConsumed); + jsonRow[flagDateConsumed] = DOM.getElementAttributeValueCurrent(inputDateConsumed); + jsonRow[flagActive] = buttonActive.classList.contains(flagDelete); + return jsonRow; + } + initialiseRowNew(tbody, row) { + super.initialiseRowNew(tbody, row); + let ddlCategoryFilter = document.querySelector(idFormFilters + ' #' + attrIdProductCategory); + let idProductCategoryFilter = DOM.getElementValueCurrent(ddlCategoryFilter); + let hasCategoryFilter = !(Validation.isEmpty(idProductCategoryFilter) || idProductCategoryFilter == '0'); + let ddlProductFilter = document.querySelector(idFormFilters + ' #' + attrIdProduct); + let idProductFilter = DOM.getElementValueCurrent(ddlProductFilter); + let hasProductFilter = !(Validation.isEmpty(idProductFilter) || idProductFilter == '0'); + if (_verbose) { + console.log("initialiseRowNew: ", row); + console.log({ddlCategoryFilter, idProductCategoryFilter, hasCategoryFilter, ddlProductFilter, idProductFilter, hasProductFilter}); + } + if (!hasCategoryFilter && !hasProductFilter) return; + if (hasCategoryFilter) { + let ddlCategory = row.querySelector('td.' + flagProductCategory + ' select'); + DOM.setElementValuesCurrentAndPrevious(ddlCategory, idProductCategoryFilter); + this.handleChangeProductCategoryDdl(null, ddlCategory); + } + if (hasProductFilter) { + let ddlProduct = row.querySelector('td.' + flagProduct + ' select'); + DOM.setElementValuesCurrentAndPrevious(ddlProduct, idProductFilter); + } + } + + hookupTableMain() { + super.hookupTableMain(); + this.hookupProductCategoryFields(); + this.hookupProductFields(); + this.hookupFieldsProductPermutationVariation(); + this.hookupCurrencyCostFields(); + this.hookupCostInputs(); + this.hookupOrderDateInputs(); + this.hookupStorageLocationFields(); + this.hookupSealingInputs(); + this.hookupExpirationDateInputs(); + this.hookupConsumationInputs(); + this.hookupFieldsActive(); + } + hookupProductCategoryFields() { + this.hookupTableCellDdlPreviews( + idTableMain + ' td.' + flagProductCategory + , Utils.getListFromDict(productCategories) + , (event, element) => { this.hookupProductCategoryDdls(event, element); } + ); + } + hookupProductFields() { + this.hookupTableCellDdlPreviews(idTableMain + ' td.' + flagProduct, Utils.getListFromDict(products)); + } + + /* + handleClickProductPermutationVariationsPreview(event, element) { + let row = DOM.getRowFromElement(element); + let tdProduct = row.querySelector('td.' + flagProduct); + let idProduct = DOM.getElementValueCurrent(tdProduct); + let product = products[idProduct]; + if (!product[flagHasVariations]) return; + super.handleClickProductPermutationVariationsPreview(event, element); + } + */ + handleClickButtonProductPermutationVariationsAdd(event, element) { + let row = DOM.getRowFromElement(element); + let tbody = row.querySelector('tbody'); + let permutationVariation = PageDogStockItems.createOptionUnselectedProductVariation(); + this.addProductPermutationVariationRow(tbody, permutationVariation); + } + + hookupCurrencyCostFields(){ + this.hookupTableCellDdlPreviews(idTableMain + ' td.' + flagCurrencyCost, Utils.getListFromDict(currencies)); + } + hookupCostInputs(){ + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostUnitLocalVatExcl + ' input'); + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostUnitLocalVatIncl + ' input'); + } + hookupOrderDateInputs(){ + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagDatePurchased + ' input'); + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagDateReceived + ' input'); + } + + hookupStorageLocationFields(){ + this.hookupEventHandler( + "click", + idTableMain + ' td.' + flagStorageLocation + ' div', + (event, element) => this.handleClickStorageLocationPreview(event, element) + ); + } + handleClickStorageLocationPreview(event, element) { + this.toggleColumnCollapsed(flagStorageLocation, false); + let idPlant = element.getAttribute(attrIdPlant); + let idStorageLocation = element.getAttribute(attrIdStorageLocation); + let tblStorageLocation = document.createElement("table"); + tblStorageLocation.classList.add(flagStorageLocation); + let thead = document.createElement("thead"); + let thPlant = document.createElement("th"); + thPlant.textContent = 'Plant'; + let thLocation = document.createElement("th"); + thLocation.textContent = 'Location'; + let trHead = document.createElement("tr"); + trHead.appendChild(thPlant); + trHead.appendChild(thLocation); + thead.appendChild(trHead); + tblStorageLocation.appendChild(thead); + let tbody = document.createElement("tbody"); + + let plant, optionPlantJson, optionPlant, storageLocation, optionStorageLocationJson, optionStorageLocation; + let plantKeys = Object.keys(plants); + let storageLocationKeys = Object.keys(storageLocations); + + debugger; + let plantJson = idPlant != null ? plants[idPlant] : { + [attrIdPlant]: null, + }; + let storageLocationJson = idStorageLocation != null ? storageLocations[idStorageLocation] : { + [attrIdStorageLocation]: null, + }; + + let tdPlant = document.createElement("td"); + tdPlant.classList.add(flagPlant); + DOM.setElementAttributesValuesCurrentAndPrevious(tdPlant, plantJson[attrIdPlant]); + + let ddlPlant = document.createElement("select"); + ddlPlant.classList.add(flagPlant); + DOM.setElementAttributesValuesCurrentAndPrevious(ddlPlant, plantJson[attrIdPlant]); + + optionPlant = DOM.createOption(null); + if (_verbose) { console.log("optionPlant: ", optionPlant); } + ddlPlant.appendChild(optionPlant); + + plantKeys.forEach((plantKey) => { + plant = plants[plantKey]; + optionPlantJson = BusinessObjects.getOptionJsonFromObjectJson( + plant, // objectJson + plantJson[attrIdPlant] // valueSelected + ); + optionPlant = DOM.createOption(optionPlantJson); + if (_verbose) { console.log("optionPlant: ", optionPlant); } + ddlPlant.appendChild(optionPlant); + }); + + let tdStorageLocation = document.createElement("td"); + tdStorageLocation.classList.add(flagStorageLocation); + DOM.setElementAttributesValuesCurrentAndPrevious(tdStorageLocation, storageLocationJson[attrIdStorageLocation]); + + let ddlStorageLocation = document.createElement("select"); + ddlStorageLocation.classList.add(flagStorageLocation); + DOM.setElementAttributesValuesCurrentAndPrevious(ddlStorageLocation, storageLocationJson[attrIdStorageLocation]); + + optionStorageLocation = DOM.createOption(null); + if (_verbose) { console.log("optionStorageLocation: ", optionStorageLocation); } + ddlStorageLocation.appendChild(optionStorageLocation); + + storageLocationKeys.forEach((StorageLocationKey) => { + storageLocation = storageLocations[StorageLocationKey]; + optionStorageLocationJson = BusinessObjects.getOptionJsonFromObjectJson( + storageLocation, // objectJson + storageLocationJson[attrIdStorageLocation] // valueSelected + ); + optionStorageLocation = DOM.createOption(optionStorageLocationJson); + if (_verbose) { console.log("optionStorageLocation: ", optionStorageLocation); } + ddlStorageLocation.appendChild(optionStorageLocation); + }); + + let trBody = document.createElement("tr"); + tdPlant.appendChild(ddlPlant); + trBody.appendChild(tdPlant); + tdStorageLocation.appendChild(ddlStorageLocation); + trBody.appendChild(tdStorageLocation); + tbody.appendChild(trBody); + + tblStorageLocation.appendChild(tbody); + let tdParent = DOM.getCellFromElement(element); + tdParent.innerHTML = ''; + tdParent.appendChild(tblStorageLocation); + if (_verbose) { console.log("tblStorageLocation: ", tblStorageLocation); } + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagPlant + ' select', (event, element) => { this.handleChangeStoragePlantDdl(event, element); }); + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagStorageLocation + ' select', (event, element) => { this.handleChangeStorageLocationDdl(event, element); }); + } + handleChangeStoragePlantDdl(event, ddlPlant) { + this.handleChangeNestedElementCellTable(event, ddlPlant); + let row = DOM.getRowFromElement(ddlPlant); + let ddlStorageLocation = row.querySelector('td.' + flagStorageLocation + ' select'); + ddlStorageLocation.innerHTML = ''; + ddlStorageLocation.appendChild(DOM.createOption(null)); + let idPlant = DOM.getElementValueCurrent(ddlPlant); + let storageLocations = plants[idPlant][flagStorageLocations]; + let optionJson, option; + storageLocations.forEach((storageLocation) => { + optionJson = BusinessObjects.getOptionJsonFromObjectJson(storageLocation); + option = DOM.createOption(optionJson); + ddlStorageLocation.appendChild(option); + }); + this.handleChangeNestedElementCellTable(event, ddlStorageLocation); + } + handleChangeStorageLocationDdl(event, ddlStorageLocation) { + this.handleChangeNestedElementCellTable(event, ddlStorageLocation); + } + + hookupSealingInputs() { + this.hookupIsSealedFields(); + this.hookupDateUnsealedInputs(); + } + hookupIsSealedFields(){ + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagIsSealed + ' input', (event, element) => { + this.handleChangeNestedElementCellTable(event, element); + let isSealed = DOM.getElementValueCurrent(element); + let row = DOM.getRowFromElement(element); + let inputDateUnsealed = row.querySelector('td.' + flagDateUnsealed + ' input'); + if (isSealed) { + inputDateUnsealed.classList.add(flagCollapsed); + } else { + inputDateUnsealed.classList.remove(flagCollapsed); + } + }); + } + hookupDateUnsealedInputs(){ + this.hookupChangeHandlerTableCellsWhenNotCollapsed("change", idTableMain + ' td.' + flagDateUnsealed + ' input'); + } + + hookupExpirationDateInputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagDateExpiration + ' input'); + } + + hookupConsumationInputs() { + this.hookupIsConsumedFields(); + this.hookupDateConsumedInputs(); + } + hookupIsConsumedFields(){ + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagIsConsumed + ' input', (event, element) => { + this.handleChangeNestedElementCellTable(event, element); + let isConsumed = DOM.getElementValueCurrent(element); + let row = DOM.getRowFromElement(element); + let inputDateConsumed = row.querySelector('td.' + flagDateConsumed + ' input'); + if (isConsumed) { + inputDateConsumed.classList.remove(flagCollapsed); + } else { + inputDateConsumed.classList.add(flagCollapsed); + } + }); + } + hookupDateConsumedInputs(){ + this.hookupChangeHandlerTableCellsWhenNotCollapsed("change", idTableMain + ' td.' + flagDateConsumed + ' input'); + } + + leave() { + super.leave(); + } +} + diff --git a/static/js/pages/dog/supplier_purchase_orders.js b/static/js/pages/dog/supplier_purchase_orders.js new file mode 100644 index 0000000..550b0b5 --- /dev/null +++ b/static/js/pages/dog/supplier_purchase_orders.js @@ -0,0 +1,509 @@ + +import API from "../../api.js"; +import BusinessObjects from "../../lib/business_objects/business_objects.js"; +import DOM from "../../dom.js"; +import Events from "../../lib/events.js"; +import ProductPermutation from "../../lib/business_objects/dog/product_permutation.js"; +import TableBasePage from "../base_table.js"; +import Utils from "../../lib/utils.js"; +import Validation from "../../lib/validation.js"; +import DogTableMixinPage from "./mixin_table.js"; + +export default class PageDogSupplierPurchaseOrders extends TableBasePage { + static hash = hashPageDogSupplierPurchaseOrders; + static attrIdRowObject = attrIdSupplierPurchaseOrder; + callSaveTableContent = API.saveSupplierPurchaseOrders; + + constructor(router) { + super(router); + this.dogMixin = new DogTableMixinPage(this); + } + + initialize() { + this.sharedInitialize(); + } + + hookupFilters() { + this.sharedHookupFilters(); + this.hookupFilterActive(); + } + + loadRowTable(rowJson) { + } + getJsonRow(row) { + if (row == null) return; + let tdSupplier = row.querySelector('td.' + flagSupplier); + let tdCurrency = row.querySelector('td.' + flagCurrency); + let inputCostTotalLocalVatExcl = row.querySelector('td.' + flagCostTotalLocalVatExcl + ' input'); + let inputCostTotalLocalVatIncl = row.querySelector('td.' + flagCostTotalLocalVatIncl + ' input'); + let trsPurchaseOrderItem = row.querySelectorAll('tr.' + flagOrderItems); + let buttonActive = tr.querySelector(':scope > td.' + flagActive + ' button'); + + let jsonRow = {}; + jsonRow[attrIdSupplierPurchaseOrder] = row.getAttribute(attrIdSupplierPurchaseOrder); + jsonRow[attrIdSupplier] = DOM.getElementAttributeValueCurrent(tdSupplier); + jsonRow[attrIdCurrency] = DOM.getElementAttributeValueCurrent(tdCurrency); + jsonRow[flagCostTotalLocalVatExcl] = DOM.getElementAttributeValueCurrent(inputCostTotalLocalVatExcl); + jsonRow[flagCostTotalLocalVatIncl] = DOM.getElementAttributeValueCurrent(inputCostTotalLocalVatIncl); + // jsonRow[flagOrderItems] = DOM.getElementAttributeValueCurrent(tdItems); + let orderItems = []; + if (trsPurchaseOrderItem != null) { + trsPurchaseOrderItem.forEach((tr) => { + orderItems.push(this.getJsonRowOrderItem(tr)); + }); + } + jsonRow[flagOrderItems] = orderItems; + jsonRow[flagActive] = buttonActive.classList.contains(flagDelete); + return jsonRow; + } + getJsonRowOrderItem(tr) { + let inputDisplayOrder = tr.querySelector('td.' + flagDisplayOrder + ' input'); + let tdCategory = tr.querySelector('td.' + flagProductCategory); + let tdProduct = tr.querySelector('td.' + flagProduct); + let tdVariations = tr.querySelector('td.' + flagProductVariations); + let tdUnitQuantity = tr.querySelector('td.' + flagUnitMeasurementQuantity); + let inputQuantityOrdered = tr.querySelector('td.' + flagQuantityOrdered + ' input'); + let inputQuantityReceived = tr.querySelector('td.' + flagQuantityReceived + ' input'); + let inputCostTotalLocalVatExcl = tr.querySelector('td.' + flagCostTotalLocalVatExcl + ' input'); + let inputCostTotalLocalVatIncl = tr.querySelector('td.' + flagCostTotalLocalVatIncl + ' input'); + let inputLatencyDeliveryDays = tr.querySelector('td.' + flagLatencyDeliveryDays + ' input'); + let buttonActive = tr.querySelector(':scope > td.' + flagActive + ' button'); + + let jsonRow = {}; + jsonRow[attrIdSupplierPurchaseOrder] = tr.getAttribute(attrIdSupplierPurchaseOrder); + jsonRow[attrIdSupplierPurchaseOrderProductLink] = tr.getAttribute(attrIdSupplierPurchaseOrderProductLink); + jsonRow[flagDisplayOrder] = DOM.getElementAttributeValueCurrent(inputDisplayOrder); + jsonRow[attrIdProductCategory] = DOM.getElementAttributeValueCurrent(tdCategory); + jsonRow[attrIdProduct] = DOM.getElementAttributeValueCurrent(tdProduct); + jsonRow[flagProductVariations] = DOM.getElementAttributeValueCurrent(tdVariations); + jsonRow[attrIdUnitMeasurementQuantity] = DOM.getElementAttributeValueCurrent(tdUnitQuantity); + jsonRow[flagQuantityOrdered] = DOM.getElementAttributeValueCurrent(inputQuantityOrdered); + jsonRow[flagQuantityReceived] = DOM.getElementAttributeValueCurrent(inputQuantityReceived); + jsonRow[flagCostTotalLocalVatExcl] = DOM.getElementAttributeValueCurrent(inputCostTotalLocalVatExcl); + jsonRow[flagCostTotalLocalVatIncl] = DOM.getElementAttributeValueCurrent(inputCostTotalLocalVatIncl); + jsonRow[flagLatencyDeliveryDays] = DOM.getElementAttributeValueCurrent(inputLatencyDeliveryDays); + jsonRow[flagActive] = buttonActive.classList.contains(flagDelete); + + return jsonRow; + } + initialiseRowNew(tbody, row) { + super.initialiseRowNew(tbody, row); + } + + hookupTableMain() { + super.hookupTableMain(); + this.hookupSupplierFields(); + this.hookupCurrencyFields(); + this.hookupCostInputs(); + this.hookupOrderItemsFields(); + this.hookupFieldsActive(); + } + hookupSupplierFields() { + this.hookupTableCellDdlPreviews(idTableMain + ' td.' + flagSupplier, Utils.getListFromDict(suppliers)); + } + hookupCostInputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostTotalLocalVatExcl + ' input'); + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagCostTotalLocalVatIncl + ' input'); + } + hookupOrderItemsFields() { + this.hookupOrderItemsPreviews(); + this.hookupFieldsOrderItemDisplayOrder(); + this.hookupFieldsOrderItemProductCategory(); + this.hookupFieldsOrderItemProduct(); + // this.hookupFieldsOrderItemProductVariations(); + this.hookupFieldsProductPermutationVariation(); + this.hookupFieldsOrderItemUnitQuantity(); + this.hookupFieldsOrderItemQuantityOrdered(); + this.hookupFieldsOrderItemQuantityReceived(); + this.hookupFieldsOrderItemCostTotalLocalVatExcl(); + this.hookupFieldsOrderItemCostTotalLocalVatIncl(); + this.hookupFieldsOrderItemLatencyDeliveryDays(); + this.hookupFieldsOrderItemActive(); + this.hookupFieldsOrderItemAddDelete(); + } + hookupOrderItemsPreviews() { + this.hookupEventHandler("click", idTableMain + ' > tbody > tr > td.' + flagOrderItems + ' > div', (event, div) => { + let td = DOM.getCellFromElement(div); + if (!td.classList.contains(flagCollapsed)) return; + this.handleClickOrderItemsPreview(event, div); + }); + } + handleClickOrderItemsPreview(event, element) { + if (_verbose) { console.log("click order items preview"); } + this.toggleColumnHeaderCollapsed(flagOrderItems, false); + /* + let td = DOM.getCellFromElement(element); + td.classList.remove(flagCollapsed); + */ + + let row = DOM.getRowFromElement(element); + let idSupplierPurchaseOrder = row.getAttribute(attrIdSupplierPurchaseOrder); + // if (idSupplierPurchaseOrder == null || idSupplierPurchaseOrder < 1) return; + let supplierPurchaseOrder = supplierPurchaseOrders[idSupplierPurchaseOrder]; + if (supplierPurchaseOrder == null) supplierPurchaseOrder = { + [flagOrderItems]: [], + }; + let tblOrderItems = document.createElement("table"); + tblOrderItems.classList.add(flagOrderItems); + let thead = document.createElement("thead"); + let tr = document.createElement("tr"); + + let thDisplayOrder = document.createElement("th"); + thDisplayOrder.classList.add(flagDisplayOrder); + thDisplayOrder.textContent = 'Display Order'; + let thCategory = document.createElement("th"); + thCategory.classList.add(flagProductCategory); + thCategory.textContent = 'Category'; + let thProduct = document.createElement("th"); + thProduct.classList.add(flagProduct); + thProduct.textContent = 'Product'; + let thVariations = document.createElement("th"); + thVariations.classList.add(flagProductVariations); + thVariations.classList.add(flagCollapsed); + thVariations.textContent = 'Variations'; + let thUnitQuantity = document.createElement("th"); + thUnitQuantity.classList.add(flagUnitMeasurementQuantity); + thUnitQuantity.textContent = 'Unit Quantity'; + let thQuantityOrdered = document.createElement("th"); + thQuantityOrdered.classList.add(flagQuantityOrdered); + thQuantityOrdered.textContent = 'Quantity Ordered'; + let thQuantityReceived = document.createElement("th"); + thQuantityReceived.classList.add(flagQuantityReceived); + thQuantityReceived.textContent = 'Quantity Received'; + let thCostTotalLocalVatExcl = document.createElement("th"); + thCostTotalLocalVatExcl.classList.add(flagCostTotalLocalVatExcl); + thCostTotalLocalVatExcl.textContent = 'Cost Total Local VAT Excl'; + let thCostTotalLocalVatIncl = document.createElement("th"); + thCostTotalLocalVatIncl.classList.add(flagCostTotalLocalVatIncl); + thCostTotalLocalVatIncl.textContent = 'Cost Total Local VAT Incl'; + let thCostUnitLocalVatExcl = document.createElement("th"); + thCostUnitLocalVatExcl.classList.add(flagCostUnitLocalVatExcl); + thCostUnitLocalVatExcl.textContent = 'Cost Unit Local VAT Excl'; + let thCostUnitLocalVatIncl = document.createElement("th"); + thCostUnitLocalVatIncl.classList.add(flagCostUnitLocalVatIncl); + thCostUnitLocalVatIncl.textContent = 'Cost Unit Local VAT Incl'; + let thLatencyDeliveryDays = document.createElement("th"); + thLatencyDeliveryDays.classList.add(flagLatencyDeliveryDays); + thLatencyDeliveryDays.textContent = 'Latency Delivery (Days)'; + let thActive = document.createElement("th"); + thActive.classList.add(flagActive); + thActive.textContent = 'Active'; + let thAddDelete = document.createElement("th"); + thAddDelete.classList.add(flagAdd); + let buttonAdd = document.createElement("button"); + buttonAdd.classList.add(flagAdd); + buttonAdd.textContent = '+'; + thAddDelete.appendChild(buttonAdd); + + tr.appendChild(thDisplayOrder); + tr.appendChild(thCategory); + tr.appendChild(thProduct); + tr.appendChild(thVariations); + tr.appendChild(thUnitQuantity); + tr.appendChild(thQuantityOrdered); + tr.appendChild(thQuantityReceived); + tr.appendChild(thCostTotalLocalVatExcl); + tr.appendChild(thCostTotalLocalVatIncl); + tr.appendChild(thCostUnitLocalVatExcl); + tr.appendChild(thCostUnitLocalVatIncl); + tr.appendChild(thLatencyDeliveryDays); + tr.appendChild(thActive); + tr.appendChild(thAddDelete); + thead.appendChild(tr); + tblOrderItems.appendChild(thead); + + let tbody = document.createElement("tbody"); + supplierPurchaseOrder[flagOrderItems].forEach((orderItem, index) => { + this.addRowSupplierPurchaseOrderItem(tbody, orderItem); + }); + tblOrderItems.appendChild(tbody); + + let cell = DOM.getCellFromElement(element); + let cellNew = cell.cloneNode(false); + cellNew.appendChild(tblOrderItems); + cellNew.classList.remove(flagCollapsed); + row.replaceChild(cellNew, cell); + if (_verbose) { console.log("tblOrderItems: ", tblOrderItems); } + this.hookupOrderItemsFields(); + } + addRowSupplierPurchaseOrderItem(tbody, orderItem) { // productVariationTypeOptions, productVariationOptions, productCategoryOptions, productOptions, unitMeasurementOptions, + if (_verbose) { console.log("addRowSupplierPurchaseOrderItem: ", orderItem); } + + let tdDisplayOrder = document.createElement("td"); + tdDisplayOrder.classList.add(flagDisplayOrder); + let inputDisplayOrder = document.createElement("input"); + inputDisplayOrder.classList.add(flagDisplayOrder); + inputDisplayOrder.type = 'number'; + inputDisplayOrder.step = 1; + DOM.setElementValuesCurrentAndPrevious(inputDisplayOrder, orderItem[flagDisplayOrder]); + tdDisplayOrder.appendChild(inputDisplayOrder); + + let tdCategory = document.createElement("td"); + tdCategory.classList.add(flagProductCategory); + DOM.setElementAttributesValuesCurrentAndPrevious(tdCategory, orderItem[attrIdProductCategory]); + let divCategory = document.createElement("div"); + divCategory.classList.add(flagProductCategory); + DOM.setElementAttributesValuesCurrentAndPrevious(divCategory, orderItem[attrIdProductCategory]); + // divCategory.textContent = orderItem[flagProductCategory]; + let productCategory = productCategories[orderItem[attrIdProductCategory]]; + divCategory.textContent = BusinessObjects.getObjectText(productCategory); + tdCategory.appendChild(divCategory); + + let tdProduct = document.createElement("td"); + tdProduct.classList.add(flagProduct); + DOM.setElementAttributesValuesCurrentAndPrevious(tdProduct, orderItem[attrIdProduct]); + let divProduct = document.createElement("div"); + divProduct.classList.add(flagProduct); + DOM.setElementAttributesValuesCurrentAndPrevious(divProduct, orderItem[attrIdProduct]); + // divProduct.textContent = orderItem[flagProduct]; + let product = products[orderItem[attrIdProduct]]; + divProduct.textContent = BusinessObjects.getObjectText(product); + tdProduct.appendChild(divProduct); + + let tdVariations = document.createElement("td"); + tdVariations.classList.add(flagProductVariations); + tdVariations.classList.add(flagCollapsed); + DOM.setElementAttributesValuesCurrentAndPrevious(tdVariations, orderItem[flagProductVariations]); + let divVariations = document.createElement("div"); + divVariations.classList.add(flagProductVariations); + DOM.setElementAttributesValuesCurrentAndPrevious(divVariations, orderItem[flagProductVariations]); + // divVariations.textContent = orderItem[flagProductVariations]; + let variationsText = ProductPermutation.getProductVariationsPreviewFromIdCsv(orderItem[flagProductVariations]); + divVariations.textContent = variationsText; + tdVariations.appendChild(divVariations); + + let tdUnitQuantity = document.createElement("td"); + tdUnitQuantity.classList.add(flagUnitMeasurementQuantity); + DOM.setElementAttributesValuesCurrentAndPrevious(tdUnitQuantity, orderItem[attrIdUnitMeasurementQuantity]); + let divUnitQuantity = document.createElement("div"); + divUnitQuantity.classList.add(flagUnitMeasurementQuantity); + DOM.setElementAttributesValuesCurrentAndPrevious(divUnitQuantity, orderItem[attrIdUnitMeasurementQuantity]); + let unitQuantity = unitMeasurements[orderItem[attrIdUnitMeasurementQuantity]]; + divUnitQuantity.textContent = BusinessObjects.getObjectText(unitQuantity); + tdUnitQuantity.appendChild(divUnitQuantity); + + let tdQuantityOrdered = document.createElement("td"); + tdQuantityOrdered.classList.add(flagQuantityOrdered); + let inputQuantityOrdered = document.createElement("input"); + inputQuantityOrdered.classList.add(flagQuantityOrdered); + inputQuantityOrdered.type = 'number'; + DOM.setElementValuesCurrentAndPrevious(inputQuantityOrdered, orderItem[flagQuantityOrdered]); + tdQuantityOrdered.appendChild(inputQuantityOrdered); + + let tdQuantityReceived = document.createElement("td"); + tdQuantityReceived.classList.add(flagQuantityReceived); + let inputQuantityReceived = document.createElement("input"); + inputQuantityReceived.classList.add(flagQuantityReceived); + inputQuantityReceived.type = 'number'; + DOM.setElementValuesCurrentAndPrevious(inputQuantityReceived, orderItem[flagQuantityReceived]); + tdQuantityReceived.appendChild(inputQuantityReceived); + + let tdCostTotalLocalVatExcl = document.createElement("td"); + tdCostTotalLocalVatExcl.classList.add(flagCostTotalLocalVatExcl); + let inputCostTotalLocalVatExcl = document.createElement("input"); + inputCostTotalLocalVatExcl.classList.add(flagCostTotalLocalVatExcl); + inputCostTotalLocalVatExcl.type = 'number'; + inputCostTotalLocalVatExcl.step = 0.01; + DOM.setElementValuesCurrentAndPrevious(inputCostTotalLocalVatExcl, orderItem[flagCostTotalLocalVatExcl]); + tdCostTotalLocalVatExcl.appendChild(inputCostTotalLocalVatExcl); + + let tdCostTotalLocalVatIncl = document.createElement("td"); + tdCostTotalLocalVatIncl.classList.add(flagCostTotalLocalVatIncl); + let inputCostTotalLocalVatIncl = document.createElement("input"); + inputCostTotalLocalVatIncl.classList.add(flagCostTotalLocalVatIncl); + inputCostTotalLocalVatIncl.type = 'number'; + inputCostTotalLocalVatIncl.step = 0.01; + DOM.setElementValuesCurrentAndPrevious(inputCostTotalLocalVatIncl, orderItem[flagCostTotalLocalVatIncl]); + tdCostTotalLocalVatIncl.appendChild(inputCostTotalLocalVatIncl); + + let tdCostUnitLocalVatExcl = document.createElement("td"); + tdCostUnitLocalVatExcl.classList.add(flagCostUnitLocalVatExcl); + let divCostUnitLocalVatExcl = document.createElement("div"); + divCostUnitLocalVatExcl.classList.add(flagCostUnitLocalVatExcl); + DOM.setElementValuesCurrentAndPrevious(divCostUnitLocalVatExcl, Validation.toFixedOrDefault(orderItem[flagCostUnitLocalVatExcl], 3, null)); + tdCostUnitLocalVatExcl.appendChild(divCostUnitLocalVatExcl); + + let tdCostUnitLocalVatIncl = document.createElement("td"); + tdCostUnitLocalVatIncl.classList.add(flagCostUnitLocalVatIncl); + let divCostUnitLocalVatIncl = document.createElement("div"); + divCostUnitLocalVatIncl.classList.add(flagCostUnitLocalVatIncl); + DOM.setElementValuesCurrentAndPrevious(divCostUnitLocalVatIncl, Validation.toFixedOrDefault(orderItem[flagCostUnitLocalVatIncl], 3, null)); + tdCostUnitLocalVatIncl.appendChild(divCostUnitLocalVatIncl); + + let tdLatencyDeliveryDays = document.createElement("td"); + tdLatencyDeliveryDays.classList.add(flagLatencyDeliveryDays); + let inputLatencyDeliveryDays = document.createElement("input"); + inputLatencyDeliveryDays.classList.add(flagLatencyDeliveryDays); + inputLatencyDeliveryDays.type = 'number'; + inputLatencyDeliveryDays.step = 1; + DOM.setElementValuesCurrentAndPrevious(inputLatencyDeliveryDays, orderItem[flagLatencyDeliveryDays]); + tdLatencyDeliveryDays.appendChild(inputLatencyDeliveryDays); + + let tdActive = this.createTdActive(orderItem[flagActive]); + + let tr = document.createElement("tr"); + tr.classList.add(flagOrderItems); + tr.setAttribute(attrIdSupplierPurchaseOrder, orderItem[attrIdSupplierPurchaseOrder]); + tr.setAttribute(attrIdSupplierPurchaseOrderProductLink, orderItem[attrIdSupplierPurchaseOrderProductLink]); + tr.appendChild(tdDisplayOrder); + tr.appendChild(tdCategory); + tr.appendChild(tdProduct); + tr.appendChild(tdVariations); + tr.appendChild(tdUnitQuantity); + tr.appendChild(tdQuantityOrdered); + tr.appendChild(tdQuantityReceived); + tr.appendChild(tdCostTotalLocalVatExcl); + tr.appendChild(tdCostTotalLocalVatIncl); + tr.appendChild(tdCostUnitLocalVatExcl); + tr.appendChild(tdCostUnitLocalVatIncl); + tr.appendChild(tdLatencyDeliveryDays); + tr.appendChild(tdActive); + tbody.appendChild(tr); + } + hookupFieldsOrderItemDisplayOrder() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagOrderItems + ' td.' + flagDisplayOrder + ' input'); + } + hookupFieldsOrderItemProductCategory() { + this.hookupTableCellDdlPreviews( + idTableMain + ' td.' + flagOrderItems + ' td.' + flagProductCategory + , Utils.getListFromDict(productCategories) + , (cellSelector) => { this.hookupProductCategoryDdls(cellSelector); } + ); + } + hookupFieldsOrderItemProduct() { + this.hookupTableCellDdlPreviews(idTableMain + ' td.' + flagOrderItems + ' td.' + flagProduct, Utils.getListFromDict(products)); + } + /* + hookupFieldsOrderItemProductVariations() { + this.hookupEventHandler("click", idTableMain + ' td.' + flagOrderItems + ' td.' + flagProductVariations, (event, element) => this.handleClickProductPermutationVariationsPreview(event, element)); + } + hookupDdlsProductPermutationVariation() { + this.hookupTableCellDdls(idTableMain + ' td.' + flagProductVariations + ' td.' + flagProductVariation); + } + hookupDdlsProductPermutationVariationType() { + this.hookupTableCellDdls(idTableMain + ' td.' + flagProductVariations + ' td.' + flagProductVariationType); + } + */ + hookupFieldsOrderItemUnitQuantity() { + this.hookupTableCellDdlPreviews( + idTableMain + ' td.' + flagOrderItems + ' td.' + flagUnitMeasurementQuantity + , Utils.getListFromDict(unitMeasurements) + ); + } + hookupFieldsOrderItemQuantityOrdered() { + this.hookupChangeHandlerTableCells( + idTableMain + ' td.' + flagOrderItems + ' td.' + flagQuantityOrdered + ' input' + ); + } + hookupFieldsOrderItemQuantityReceived() { + this.hookupChangeHandlerTableCells( + idTableMain + ' td.' + flagOrderItems + ' td.' + flagQuantityReceived + ' input' + ); + } + hookupFieldsOrderItemCostTotalLocalVatExcl() { + this.hookupChangeHandlerTableCells( + idTableMain + ' td.' + flagOrderItems + ' td.' + flagCostTotalLocalVatExcl + ' input' + , (event, element) => { + this.handleChangeNestedElementCellTable(event, element); // flagCostTotalLocalVatExcl); + this.updateFieldsCostUnitLocalVatExcl(element); + } + ); + } + hookupFieldsOrderItemCostTotalLocalVatIncl() { + this.hookupChangeHandlerTableCells( + idTableMain + ' td.' + flagOrderItems + ' td.' + flagCostTotalLocalVatIncl + ' input' + , (event, element) => { + this.handleChangeNestedElementCellTable(event, element); // flagCostTotalLocalVatIncl); + this.updateFieldsCostUnitLocalVatIncl(element); + } + ); + } + updateFieldsCostUnitLocalVatExcl(elementChanged) { + let row = elementChanged.closest('tr.' + flagOrderItems); + let inputCostTotalLocalVatExcl = row.querySelector('td.' + flagCostTotalLocalVatExcl + ' input'); + let costTotalLocalVatExcl = DOM.getElementValueCurrent(inputCostTotalLocalVatExcl); + let inputQuantityOrdered = row.querySelector('td.' + flagQuantityOrdered + ' input'); + let quantityOrdered = DOM.getElementValueCurrent(inputQuantityOrdered); + + let divCostUnitLocalVatExcl = row.querySelector('td.' + flagCostUnitLocalVatExcl + ' div'); + let costUnitLocalVatExcl = quantityOrdered == 0 ? 0 : costTotalLocalVatExcl / quantityOrdered; + DOM.setElementValuesCurrentAndPrevious(divCostUnitLocalVatExcl, costUnitLocalVatExcl.toFixed(3)); + + let rowSupplierPurchaseOrder = row.closest(idTableMain + ' > tbody > tr'); + let divCostGrandTotalLocalVatExcl = rowSupplierPurchaseOrder.querySelector('td.' + flagCostTotalLocalVatExcl + ' div'); + let inputsCostTotalLocalVatExcl = rowSupplierPurchaseOrder.querySelectorAll('td.' + flagOrderItems + ' td.' + flagCostTotalLocalVatExcl + ' input'); + let costGrandTotalLocalVatExcl = Array.from(inputsCostTotalLocalVatExcl).reduce((acc, input) => acc + Number(DOM.getElementValueCurrent(input)), 0); + DOM.setElementValueCurrent(divCostGrandTotalLocalVatExcl, costGrandTotalLocalVatExcl); + } + updateFieldsCostUnitLocalVatIncl(elementChanged) { + let row = elementChanged.closest('tr.' + flagOrderItems); + let inputCostTotalLocalVatIncl = row.querySelector('td.' + flagCostTotalLocalVatIncl + ' input'); + let costTotalLocalVatIncl = DOM.getElementValueCurrent(inputCostTotalLocalVatIncl); + let inputQuantityOrdered = row.querySelector('td.' + flagQuantityOrdered + ' input'); + let quantityOrdered = DOM.getElementValueCurrent(inputQuantityOrdered); + + let divCostUnitLocalVatIncl = row.querySelector('td.' + flagCostUnitLocalVatIncl + ' div'); + let costUnitLocalVatIncl = quantityOrdered == 0 ? 0 : costTotalLocalVatIncl / quantityOrdered; + DOM.setElementValuesCurrentAndPrevious(divCostUnitLocalVatIncl, costUnitLocalVatIncl.toFixed(3)); + + let rowSupplierPurchaseOrder = row.closest(idTableMain + ' > tbody > tr'); + let divCostGrandTotalLocalVatIncl = rowSupplierPurchaseOrder.querySelector('td.' + flagCostTotalLocalVatIncl + ' div'); + let inputsCostTotalLocalVatIncl = rowSupplierPurchaseOrder.querySelectorAll('td.' + flagOrderItems + ' td.' + flagCostTotalLocalVatIncl + ' input'); + let costGrandTotalLocalVatIncl = Array.from(inputsCostTotalLocalVatIncl).reduce((acc, input) => acc + Number(DOM.getElementValueCurrent(input)), 0); + DOM.setElementValueCurrent(divCostGrandTotalLocalVatIncl, costGrandTotalLocalVatIncl); + } + hookupFieldsOrderItemLatencyDeliveryDays() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagOrderItems + ' td.' + flagLatencyDeliveryDays + ' input'); + } + hookupFieldsOrderItemActive() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagOrderItems + ' input.' + flagActive); + } + hookupFieldsOrderItemAddDelete() { + let selectorButton = idTableMain + ' td.' + flagOrderItems + ' td.' + flagOrderItems + ' button'; + let selectorButtonDelete = selectorButton + '.' + flagDelete; + let selectorButtonUndelete = selectorButton + '.' + flagAdd; + this.hookupButtonsRowDelete(selectorButtonDelete, selectorButtonUndelete); + this.hookupButtonsRowUndelete(selectorButtonDelete, selectorButtonUndelete); + this.hookupButtonsOrderItemAdd(); + } + hookupButtonsOrderItemAdd() { + this.hookupEventHandler("click", idTableMain + ' td.' + flagOrderItems + ' th button.' + flagAdd, (event, element) => { + let row = element.closest(idTableMain + ' > tbody > tr'); + let idSupplierPurchaseOrder = row.getAttribute(attrIdSupplierPurchaseOrder); + // let hasActiveOrderItem = row.querySelectorAll('td.' + flagOrderItems + ' input.' + flagActive + ':checked').length > 0; + let countSupplierOrderItems = row.querySelectorAll('td.' + flagOrderItems + ' td.' + flagSupplierPurchaseOrder).length; + let supplierOrderItem = { + [attrIdSupplierPurchaseOrder]: idSupplierPurchaseOrder, + [attrIdSupplierPurchaseOrderProductLink]: -1 - countSupplierOrderItems, + [attrIdProductCategory]: 0, + [attrIdProduct]: 0, + [flagProductVariations]: '', + [attrIdUnitMeasurementQuantity]: 0, + [flagQuantityOrdered]: '', + [flagQuantityReceived]: '', + [flagCostTotalLocalVatExcl]: '', + [flagCostTotalLocalVatIncl]: '', + [flagCostUnitLocalVatExcl]: '', + [flagCostUnitLocalVatIncl]: '', + [flagLatencyDeliveryDays]: '', + [flagDisplayOrder]: countSupplierOrderItems + 1, + [flagActive]: true, // !hasActiveOrderItem, + }; + let tbody = row.querySelector('td.' + flagOrderItems + ' table tbody'); + this.addRowSupplierPurchaseOrderItem(tbody, supplierOrderItem); + /* + if (!hasActiveOrderItem) { + let tdOrderItem = row.querySelector('td.' + flagOrderItems); + // tdOrderItem.setAttribute(attrIdSupplierOrderItem, supplierOrderItem[attrIdSupplierOrderItem]); + DOM.setElementAttributeValueCurrent(tdOrderItem, supplierOrderItem[attrIdSupplierPurchaseOrderProductLink]); + } + */ + this.hookupOrderItemsFields(); + }); + } + + leave() { + super.leave(); + } +} + diff --git a/static/js/pages/dog/suppliers.js b/static/js/pages/dog/suppliers.js new file mode 100644 index 0000000..8b2de23 --- /dev/null +++ b/static/js/pages/dog/suppliers.js @@ -0,0 +1,381 @@ + +import API from "../../api.js"; +import BusinessObjects from "../../lib/business_objects/business_objects.js"; +import DOM from "../../dom.js"; +import Events from "../../lib/events.js"; +import TableBasePage from "../base_table.js"; +import Utils from "../../lib/utils.js"; +import Validation from "../../lib/validation.js"; +import DogTableMixinPage from "./mixin_table.js"; + +export default class PageDogSuppliers extends TableBasePage { + static hash = hashPageDogSuppliers; + static attrIdRowObject = attrIdSupplier; + callSaveTableContent = API.saveSuppliers; + + constructor(router) { + super(router); + this.dogMixin = new DogTableMixinPage(this); + } + + initialize() { + this.sharedInitialize(); + } + + hookupFilters() { + this.sharedHookupFilters(); + this.hookupFilterActive(); + } + + loadRowTable(rowJson) { + } + getJsonRow(row) { + if (row == null) return; + let textareaNameCompany = row.querySelector('td.' + flagNameCompany + ' textarea'); + let textareaNameContact = row.querySelector('td.' + flagNameContact + ' textarea'); + let textareaDepartmentContact = row.querySelector('td.' + flagDepartmentContact + ' textarea'); + let tdAddress = row.querySelector('td.' + flagAddress); + let textareaPhoneNumber = row.querySelector('td.' + flagPhoneNumber + ' textarea'); + let textareaFax = row.querySelector('td.' + flagFax + ' textarea'); + let textareaEmail = row.querySelector('td.' + flagEmail + ' textarea'); + let textareaWebsite = row.querySelector('td.' + flagWebsite + ' textarea'); + let tdCurrency = row.querySelector('td.' + flagCurrency); + let buttonActive = row.querySelector(':scope > td.' + flagActive + ' button'); + + let jsonRow = {}; + jsonRow[attrIdSupplier] = row.getAttribute(attrIdSupplier); + jsonRow[flagNameCompany] = DOM.getElementAttributeValueCurrent(textareaNameCompany); + jsonRow[flagNameContact] = DOM.getElementAttributeValueCurrent(textareaNameContact); + jsonRow[flagDepartmentContact] = DOM.getElementAttributeValueCurrent(textareaDepartmentContact); + jsonRow[attrIdSupplierAddress] = DOM.getElementAttributeValueCurrent(tdAddress); + jsonRow[flagSupplierAddress] = this.getSupplierAddressesFromRow(row); + jsonRow[flagPhoneNumber] = DOM.getElementAttributeValueCurrent(textareaPhoneNumber); + jsonRow[flagFax] = DOM.getElementAttributeValueCurrent(textareaFax); + jsonRow[flagEmail] = DOM.getElementAttributeValueCurrent(textareaEmail); + jsonRow[flagWebsite] = DOM.getElementAttributeValueCurrent(textareaWebsite); + jsonRow[attrIdCurrency] = DOM.getElementAttributeValueCurrent(tdCurrency); + jsonRow[flagActive] = buttonActive.classList.contains(flagDelete); + return jsonRow; + } + getSupplierAddressesFromRow(row) { + let supplierAddresses = []; + let trs = row.querySelectorAll('td.' + flagAddress + ' tbody tr'); + let address, inputPostcode, inputAddressLine1, inputAddressLine2, inputCity, inputCounty, ddlRegion, inputActive; + trs.forEach((tr) => { + inputPostcode = tr.querySelector('td.' + flagPostcode + ' textarea'); + inputAddressLine1 = tr.querySelector('td.' + flagAddressLine1 + ' textarea'); + inputAddressLine2 = tr.querySelector('td.' + flagAddressLine2 + ' textarea'); + inputCity = tr.querySelector('td.' + flagCity + ' textarea'); + inputCounty = tr.querySelector('td.' + flagCounty + ' textarea'); + ddlRegion = tr.querySelector('td.' + flagRegion + ' select'); + inputActive = tr.querySelector('td.' + flagActive + ' input'); + address = { + [attrIdSupplierAddress]: tr.getAttribute(attrIdSupplierAddress), + [attrIdSupplier]: row.getAttribute(attrIdSupplier), + [flagPostcode]: DOM.getElementAttributeValueCurrent(inputPostcode), + [flagAddressLine1]: DOM.getElementAttributeValueCurrent(inputAddressLine1), + [flagAddressLine2]: DOM.getElementAttributeValueCurrent(inputAddressLine2), + [flagCity]: DOM.getElementAttributeValueCurrent(inputCity), + [flagCounty]: DOM.getElementAttributeValueCurrent(inputCounty), + [attrIdRegion]: DOM.getElementAttributeValueCurrent(ddlRegion), + [flagActive]: DOM.getElementAttributeValueCurrent(inputActive), + }; + supplierAddresses.push(address); + }); + return supplierAddresses; + } + initialiseRowNew(tbody, row) { + super.initialiseRowNew(tbody, row); + } + + hookupTableMain() { + super.hookupTableMain(); + this.hookupNameCompanyInputs(); + this.hookupNameContactInputs(); + this.hookupDepartmentContactInputs(); + this.hookupAddressFields(); + this.hookupPhoneNumberInputs(); + this.hookupFaxInputs(); + this.hookupEmailInputs(); + this.hookupWebsiteInputs(); + this.hookupCurrencyFields(); + this.hookupFieldsActive(); + } + hookupNameCompanyInputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagNameCompany + ' textarea'); + } + hookupNameContactInputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagNameContact + ' textarea'); + } + hookupDepartmentContactInputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagDepartmentContact + ' textarea'); + } + + hookupAddressFields() { + this.hookupAddressPreviews(); + this.hookupAddressPostcodeInputs(); + this.hookupAddressLine1Inputs(); + this.hookupAddressLine2Inputs(); + this.hookupAddressCityInputs(); + this.hookupAddressCountyInputs(); + this.hookupAddressRegionDdls(); + this.hookupAddressActiveCheckboxes(); + this.hookupAddressDeleteButtons(); + this.hookupAddressUndeleteButtons(); + this.hookupAddressAddButtons(); + } + hookupAddressPreviews() { + this.hookupEventHandler("click", idTableMain + ' td.' + flagAddress, (event, td) => { + if (!td.classList.contains(flagCollapsed)) return; + this.handleClickAddressPreview(event, td); + }); + } + handleClickAddressPreview(event, element) { + if (_verbose) { console.log("click address preview"); } + this.toggleColumnHeaderCollapsed(flagAddress, false); + element.classList.remove(flagCollapsed); + let row = DOM.getRowFromElement(element); + let idSupplier = row.getAttribute(attrIdSupplier); + let supplierAddressList = idSupplier > 0 ? supplierAddresses[idSupplier] : []; + let tblAddresses = document.createElement("table"); + tblAddresses.classList.add(flagAddress); + let thead = document.createElement("thead"); + let tr = document.createElement("tr"); + let thPostcode = document.createElement("th"); + thPostcode.classList.add(flagPostcode); + thPostcode.textContent = 'Postcode'; + let thAddressLine1 = document.createElement("th"); + thAddressLine1.classList.add(flagAddressLine1); + thAddressLine1.textContent = 'Address Line 1'; + let thAddressLine2 = document.createElement("th"); + thAddressLine2.classList.add(flagAddressLine2); + thAddressLine2.textContent = 'Address Line 2'; + let thCity = document.createElement("th"); + thCity.classList.add(flagCity); + thCity.textContent = 'City'; + let thCounty = document.createElement("th"); + thCounty.classList.add(flagCounty); + thCounty.textContent = 'County'; + let thRegion = document.createElement("th"); + thRegion.classList.add(flagRegion); + thRegion.textContent = 'Region'; + let thActive = document.createElement("th"); + thActive.classList.add(flagActive); + thActive.textContent = 'Active'; + let thAddDelete = document.createElement("th"); + thAddDelete.classList.add(flagAdd); + let buttonAdd = document.createElement("button"); + buttonAdd.classList.add(flagAdd); + buttonAdd.textContent = '+'; + thAddDelete.appendChild(buttonAdd); + + tr.appendChild(thPostcode); + tr.appendChild(thAddressLine1); + tr.appendChild(thAddressLine2); + tr.appendChild(thCity); + tr.appendChild(thCounty); + tr.appendChild(thRegion); + tr.appendChild(thActive); + tr.appendChild(thAddDelete); + thead.appendChild(tr); + tblAddresses.appendChild(thead); + + let tbody = document.createElement("tbody"); + let regionOptions = Utils.getListFromDict(regions); + supplierAddressList.forEach((supplierAddress, index) => { + this.addRowSupplierAddress(tbody, supplierAddress, regionOptions); + }); + tblAddresses.appendChild(tbody); + + let cell = DOM.getCellFromElement(element); + let cellNew = cell.cloneNode(false); + cellNew.appendChild(tblAddresses); + row.replaceChild(cellNew, cell); + if (_verbose) { console.log("tblAddresses: ", tblAddresses); } + this.hookupAddressFields(); + } + addRowSupplierAddress(tbody, supplierAddress, regionOptions) { + if (_verbose) { console.log("addRowSupplierAddress: ", supplierAddress); } + let tdPostcode = document.createElement("td"); + tdPostcode.classList.add(flagPostcode); + let textareaPostcode = document.createElement("textarea"); + textareaPostcode.classList.add(flagPostcode); + DOM.setElementValuesCurrentAndPrevious(textareaPostcode, supplierAddress[flagPostcode]); + tdPostcode.appendChild(textareaPostcode); + + let tdAddressLine1 = document.createElement("td"); + tdAddressLine1.classList.add(flagAddressLine1); + let textareaAddressLine1 = document.createElement("textarea"); + textareaAddressLine1.classList.add(flagAddressLine1); + DOM.setElementValuesCurrentAndPrevious(textareaAddressLine1, supplierAddress[flagAddressLine1]); + tdAddressLine1.appendChild(textareaAddressLine1); + + let tdAddressLine2 = document.createElement("td"); + tdAddressLine2.classList.add(flagAddressLine2); + let textareaAddressLine2 = document.createElement("textarea"); + textareaAddressLine2.classList.add(flagAddressLine2); + DOM.setElementValuesCurrentAndPrevious(textareaAddressLine2, supplierAddress[flagAddressLine2]); + tdAddressLine2.appendChild(textareaAddressLine2); + + let tdCity = document.createElement("td"); + tdCity.classList.add(flagCity); + let textareaCity = document.createElement("textarea"); + textareaCity.classList.add(flagCity); + DOM.setElementValuesCurrentAndPrevious(textareaCity, supplierAddress[flagCity]); + tdCity.appendChild(textareaCity); + + let tdCounty = document.createElement("td"); + tdCounty.classList.add(flagCounty); + let textareaCounty = document.createElement("textarea"); + textareaCounty.classList.add(flagCounty); + DOM.setElementValuesCurrentAndPrevious(textareaCounty, supplierAddress[flagCounty]); + tdCounty.appendChild(textareaCounty); + + let region = supplierAddress[flagRegion]; + if (!region) region = {[attrIdRegion]: ''}; + let tdRegion = document.createElement("td"); + tdRegion.classList.add(flagRegion); + DOM.setElementAttributesValuesCurrentAndPrevious(tdRegion, region[attrIdRegion]); + let ddlRegion = document.createElement("select"); + ddlRegion.classList.add(flagRegion); + let optionJson, option; + option = DOM.createOption(null); + ddlRegion.appendChild(option); + regionOptions.forEach((regionOption) => { + optionJson = BusinessObjects.getOptionJsonFromObjectJson(regionOption); + option = DOM.createOption(optionJson); + ddlRegion.appendChild(option); + }); + DOM.setElementValuesCurrentAndPrevious(ddlRegion, region[attrIdRegion]); + tdRegion.appendChild(ddlRegion); + + let tdActive = this.createTdActive(supplierAddress[flagActive]); + + let tr = document.createElement("tr"); + tr.setAttribute(attrIdSupplierAddress, supplierAddress[attrIdSupplierAddress]); + tr.setAttribute(attrIdSupplier, supplierAddress[attrIdSupplier]); + tr.appendChild(tdPostcode); + tr.appendChild(tdAddressLine1); + tr.appendChild(tdAddressLine2); + tr.appendChild(tdCity); + tr.appendChild(tdCounty); + tr.appendChild(tdRegion); + tr.appendChild(tdActive); + tbody.appendChild(tr); + } + hookupAddressPostcodeInputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' textarea.' + flagPostcode); + } + hookupAddressLine1Inputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' textarea.' + flagAddressLine1); + } + hookupAddressLine2Inputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' textarea.' + flagAddressLine2); + } + hookupAddressCityInputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' textarea.' + flagCity); + } + hookupAddressCountyInputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' textarea.' + flagCounty); + } + hookupAddressRegionDdls() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' select.' + flagRegion); + } + hookupAddressActiveCheckboxes() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagAddress + ' input.' + flagActive, (event, element) => { + let rowSupplierAddress = element.closest('tr'); + let idAddress = rowSupplierAddress.getAttribute(attrIdSupplierAddress); + DOM.setElementAttributeValueCurrent(rowSupplierAddress, idAddress); + let rowSupplier = rowSupplierAddress.closest(idTableMain + ' > tbody > tr'); + let checkboxesActive = rowSupplier.querySelectorAll('td.' + flagAddress + ' input.' + flagActive); + let isActive = element.checked; + if (isActive) { + checkboxesActive.forEach((checkbox) => { + if (checkbox == element) return; + DOM.setElementValueCurrent(checkbox, false); + }); + } + /* + else if (checkboxesActive.length > 0) { + DOM.setElementValueCurrent(checkboxesActive[0], false); + } + */ + }); + } + hookupFieldsAddressAddDelete() { + let selectorButton = idTableMain + ' td.' + flagAddress + ' button'; + let selectorButtonDelete = selectorButton + '.' + flagDelete; + let selectorButtonUndelete = selectorButton + '.' + flagAdd; + this.hookupButtonsRowDelete(selectorButtonDelete, selectorButtonUndelete); + this.hookupButtonsRowUndelete(selectorButtonDelete, selectorButtonUndelete); + } + hookupAddressDeleteButtons() { + this.hookupEventHandler("click", idTableMain + ' td.' + flagAddress + ' button.' + flagDelete, (event, element) => { + let row = DOM.getRowFromElement(element); + row.classList.add(flagDelete); + + let buttonAdd = document.createElement("button"); + buttonAdd.classList.add(flagAdd); + buttonAdd.textContent = '+'; + element.replaceWith(buttonAdd); + this.hookupAddressUndeleteButtons(); + }); + } + hookupAddressUndeleteButtons() { + this.hookupEventHandler("click", idTableMain + ' td.' + flagAddress + ' td button.' + flagAdd, (event, element) => { + let row = DOM.getRowFromElement(element); + row.classList.remove(flagDelete); + + let buttonDelete = document.createElement("button"); + buttonDelete.classList.add(flagDelete); + buttonDelete.textContent = 'x'; + element.replaceWith(buttonDelete); + this.hookupAddressDeleteButtons(); + }); + } + hookupAddressAddButtons() { + this.hookupEventHandler("click", idTableMain + ' td.' + flagAddress + ' th button.' + flagAdd, (event, element) => { + let row = element.closest(idTableMain + ' > tbody > tr'); + let idSupplier = row.getAttribute(attrIdSupplier); + let hasActiveAddress = row.querySelectorAll('td.' + flagAddress + ' input.' + flagActive + ':checked').length > 0; + let countSupplierAddresses = row.querySelectorAll('td.' + flagAddress + ' td.' + flagAddress).length; + let supplierAddress = { + [attrIdSupplier]: idSupplier, + [attrIdSupplierAddress]: -1 - countSupplierAddresses, + [flagPostcode]: '', + [flagAddressLine1]: '', + [flagAddressLine2]: '', + [flagCity]: '', + [flagCounty]: '', + [attrIdRegion]: '', + [flagActive]: !hasActiveAddress, + }; + let tbody = row.querySelector('td.' + flagAddress + ' table tbody'); + this.addRowSupplierAddress(tbody, supplierAddress, Utils.getListFromDict(regions)); + if (!hasActiveAddress) { + let tdAddress = row.querySelector('td.' + flagAddress); + // tdAddress.setAttribute(attrIdSupplierAddress, supplierAddress[attrIdSupplierAddress]); + DOM.setElementAttributeValueCurrent(tdAddress, supplierAddress[attrIdSupplierAddress]); + } + this.hookupAddressFields(); + }); + } + + hookupPhoneNumberInputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagPhoneNumber + ' textarea'); + } + hookupFaxInputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagFax + ' textarea'); + } + hookupEmailInputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagEmail + ' textarea'); + } + hookupWebsiteInputs() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagWebsite + ' textarea'); + } + + leave() { + super.leave(); + } +} + diff --git a/static/js/router.js b/static/js/router.js index a47b05f..36cfcc6 100644 --- a/static/js/router.js +++ b/static/js/router.js @@ -2,6 +2,11 @@ // Pages // Core import PageHome from './pages/core/home.js'; +// Dog +import PageDogHome from './pages/dog/home.js'; +import PageDogCommands from './pages/dog/commands.js'; +import PageDogDogCommandLinks from './pages/dog/dog_command_links.js'; +import PageDogDogs from './pages/dog/dogs.js'; // Legal import PageAccessibilityReport from './pages/legal/accessibility_report.js'; import PageAccessibilityStatement from './pages/legal/accessibility_statement.js'; @@ -24,6 +29,11 @@ export default class Router { this.pages = {}; // Core this.pages[hashPageHome] = { name: 'PageHome', module: PageHome }; + // Dog + this.pages[hashPageDogHome] = { name: 'PageDogHome', module: PageDogHome }; + this.pages[hashPageDogCommands] = { name: 'PageDogCommands', module: PageDogCommands }; + this.pages[hashPageDogDogCommandLinks] = { name: 'PageDogDogCommandLinks', module: PageDogDogCommandLinks }; + this.pages[hashPageDogDogs] = { name: 'PageDogDogs', module: PageDogDogs }; // Legal this.pages[hashPageAccessibilityStatement] = { name: 'PageAccessibilityStatement', module: PageAccessibilityStatement }; this.pages[hashPageDataRetentionSchedule] = { name: 'PageDataRetentionSchedule', module: PageRetentionSchedule }; @@ -37,7 +47,11 @@ export default class Router { this.routes = {}; // Core this.routes[hashPageHome] = (isPopState = false) => this.navigateToHash(hashPageHome, isPopState); - this.routes[hashPageContact] = (isPopState = false) => this.navigateToHash(hashPageContact, isPopState); + // Dog + this.routes[hashPageDogHome] = (isPopState = false) => this.navigateToHash(hashPageDogHome, isPopState); + this.routes[hashPageDogCommands] = (isPopState = false) => this.navigateToHash(hashPageDogCommands, isPopState); + this.routes[hashPageDogDogCommandLinks] = (isPopState = false) => this.navigateToHash(hashPageDogDogCommandLinks, isPopState); + this.routes[hashPageDogDogs] = (isPopState = false) => this.navigateToHash(hashPageDogDogs, isPopState); // Legal this.routes[hashPageAccessibilityStatement] = (isPopState = false) => this.navigateToHash(hashPageAccessibilityStatement, isPopState); this.routes[hashPageDataRetentionSchedule] = (isPopState = false) => this.navigateToHash(hashPageDataRetentionSchedule, isPopState); diff --git a/templates/components/common/buttons/_icon_add.html b/templates/components/common/buttons/_icon_add.html new file mode 100644 index 0000000..50eabc4 --- /dev/null +++ b/templates/components/common/buttons/_icon_add.html @@ -0,0 +1,12 @@ + +{% if colour is not defined %} + {% set colour = model.COLOUR_PRIMARY %} +{% endif %} + + + + + \ No newline at end of file diff --git a/templates/components/common/buttons/_icon_hamburger.html b/templates/components/common/buttons/_icon_hamburger.html new file mode 100644 index 0000000..2de408f --- /dev/null +++ b/templates/components/common/buttons/_icon_hamburger.html @@ -0,0 +1,12 @@ + +{% if colour is not defined %} + {% set colour = model.COLOUR_PRIMARY %} +{% endif %} + + + + + \ No newline at end of file diff --git a/templates/components/common/buttons/_icon_trash.html b/templates/components/common/buttons/_icon_trash.html new file mode 100644 index 0000000..2986ea6 --- /dev/null +++ b/templates/components/common/buttons/_icon_trash.html @@ -0,0 +1,12 @@ + +{% if colour is not defined %} + {% set colour = model.COLOUR_PRIMARY %} +{% endif %} + + + + + \ No newline at end of file diff --git a/templates/components/common/temporary/_overlay_address.html b/templates/components/common/temporary/_overlay_address.html index e35992d..b38ce12 100644 --- a/templates/components/common/temporary/_overlay_address.html +++ b/templates/components/common/temporary/_overlay_address.html @@ -6,5 +6,5 @@ string overlay_title --> {% block overlay_body %} - {% include 'components/store/_address.html' %} + {% include 'components/dog/_address.html' %} {% endblock %} \ No newline at end of file diff --git a/templates/components/dog/_td_active.html b/templates/components/dog/_td_active.html index 9f72e3e..8fe37aa 100644 --- a/templates/components/dog/_td_active.html +++ b/templates/components/dog/_td_active.html @@ -5,9 +5,18 @@ {# #} + {# + #} + {% if active %} + {% set colour = model.COLOUR_ERROR %} + {% include 'components/common/buttons/_icon_trash.html' %} + {% else %} + {% set colour = model.COLOUR_PRIMARY %} + {% include 'components/common/buttons/_icon_add.html' %} + {% endif %} {% endwith %} \ No newline at end of file diff --git a/templates/js/sections/dog.js b/templates/js/sections/dog.js index b576a3b..9e7f903 100644 --- a/templates/js/sections/dog.js +++ b/templates/js/sections/dog.js @@ -1,155 +1,14 @@ var attrFormType = "{{ model.ATTR_FORM_TYPE }}"; -var attrIdCustomer = "{{ model.ATTR_ID_CUSTOMER }}"; -var attrIdCustomerAddress = "{{ model.ATTR_ID_CUSTOMER_ADDRESS }}"; -var attrIdCustomerSalesOrder = "{{ model.ATTR_ID_CUSTOMER_SALES_ORDER }}"; -var attrIdDiscount = "{{ model.ATTR_ID_DISCOUNT }}"; -var attrIdManufacturingPurchaseOrder = "{{ model.ATTR_ID_MANUFACTURING_PURCHASE_ORDER }}"; -var attrIdManufacturingPurchaseOrderProductLink = "{{ model.ATTR_ID_MANUFACTURING_PURCHASE_ORDER_PRODUCT_LINK }}"; -var attrIdPlant = "{{ model.ATTR_ID_PLANT }}"; -var attrIdProduct = "{{ model.ATTR_ID_PRODUCT }}"; -var attrIdProductCategory = "{{ model.ATTR_ID_PRODUCT_CATEGORY }}"; -var attrIdProductPermutation = "{{ model.ATTR_ID_PRODUCT_PERMUTATION }}"; -var attrIdProductPrice = "{{ model.ATTR_ID_PRODUCT_PRICE }}"; -var attrIdProductVariation = "{{ model.ATTR_ID_PRODUCT_VARIATION }}"; -var attrIdProductVariationType = "{{ model.ATTR_ID_PRODUCT_VARIATION_TYPE }}"; -var attrIdStockItem = "{{ model.ATTR_ID_STOCK_ITEM }}"; -var attrIdStorageLocation = "{{ model.ATTR_ID_STORAGE_LOCATION }}"; -var attrIdSupplier = "{{ model.ATTR_ID_SUPPLIER }}"; -var attrIdSupplierAddress = "{{ model.ATTR_ID_SUPPLIER_ADDRESS }}"; -var attrIdSupplierPurchaseOrder = "{{ model.ATTR_ID_SUPPLIER_PURCHASE_ORDER }}"; -var attrIdSupplierPurchaseOrderProductLink = "{{ model.ATTR_ID_SUPPLIER_PURCHASE_ORDER_PRODUCT_LINK }}"; -var attrIdUnitMeasurementLatencyManufacture = "{{ model.ATTR_ID_UNIT_MEASUREMENT_LATENCY_MANUFACTURE }}"; -var attrIdUnitMeasurementQuantity = "{{ model.ATTR_ID_UNIT_MEASUREMENT_QUANTITY }}"; +var attrIdCommand = "{{ model.ATTR_ID_COMMAND }}"; +var attrIdDog = "{{ model.ATTR_ID_DOG }}"; +var attrIdDogCommandLink = "{{ model.ATTR_ID_DOG_COMMAND_LINK }}"; var flagButtonBasketAdd = "{{ model.FLAG_BUTTON_BASKET_ADD }}"; var flagButtonBuyNow = "{{ model.FLAG_BUTTON_BUY_NOW }}"; -{# -var flagCostLocal = "{{ model.FLAG_COST_LOCAL }}"; -var flagCostLocalVatExcl = "{{ model.FLAG_COST_LOCAL_VAT_EXCL }}"; -var flagCostLocalVatIncl = "{{ model.FLAG_COST_LOCAL_VAT_INCL }}"; -#} -var flagCostTotalLocalVatExcl = "{{ model.FLAG_COST_TOTAL_LOCAL_VAT_EXCL }}"; -var flagCostTotalLocalVatIncl = "{{ model.FLAG_COST_TOTAL_LOCAL_VAT_INCL }}"; -var flagCostUnitLocalVatExcl = "{{ model.FLAG_COST_UNIT_LOCAL_VAT_EXCL }}"; -var flagCostUnitLocalVatIncl = "{{ model.FLAG_COST_UNIT_LOCAL_VAT_INCL }}"; -var flagCountUnitMeasurementIntervalExpirationUnsealed = "{{ model.FLAG_COUNT_UNIT_MEASUREMENT_INTERVAL_EXPIRATION_UNSEALED }}"; -var flagCountUnitMeasurementIntervalRecurrence = "{{ model.FLAG_COUNT_UNIT_MEASUREMENT_INTERVAL_RECURRENCE }}"; -var flagCountUnitMeasurementPerQuantityStep = "{{ model.FLAG_COUNT_UNIT_MEASUREMENT_PER_QUANTITY_STEP }}"; -var flagCurrencyCost = "{{ model.FLAG_CURRENCY_COST }}"; -var flagCustomer = "{{ model.FLAG_CUSTOMER }}"; -var flagCustomerAddress = "{{ model.FLAG_CUSTOMER_ADDRESS }}"; -var flagCustomerSalesOrder = "{{ model.FLAG_CUSTOMER_SALES_ORDER }}"; -var flagDateConsumed = "{{ model.FLAG_DATE_CONSUMED }}"; -var flagDateExpiration = "{{ model.FLAG_DATE_EXPIRATION }}"; -var flagDatePurchased = "{{ model.FLAG_DATE_PURCHASED }}"; -var flagDateReceived = "{{ model.FLAG_DATE_RECEIVED }}"; -var flagDateUnsealed = "{{ model.FLAG_DATE_UNSEALED }}"; -var flagDiscount = "{{ model.FLAG_DISCOUNT }}"; -var flagDoesExpireFasterOnceUnsealed = "{{ model.FLAG_DOES_EXPIRE_FASTER_ONCE_UNSEALED }}"; -var flagHasVariations = "{{ model.FLAG_HAS_VARIATIONS }}"; -var flagIdStripeProduct = "{{ model.FLAG_ID_STRIPE_PRODUCT }}"; -var flagIsConsumed = "{{ model.FLAG_IS_CONSUMED }}"; -var flagIsNotEmpty = "{{ model.FLAG_IS_NOT_EMPTY }}"; -var flagIsOutOfStock = "{{ model.FLAG_IS_OUT_OF_STOCK }}"; -var flagIsSealed = "{{ model.FLAG_IS_SEALED }}"; -var flagIsSubscription = "{{ model.FLAG_IS_SUBSCRIPTION }}"; -var flagLatencyDeliveryDays = "{{ model.FLAG_LATENCY_DELIVERY_DAYS }}"; -var flagLatencyManufacture = "{{ model.FLAG_LATENCY_MANUFACTURE }}"; -var flagManufacturingPurchaseOrder = "{{ model.FLAG_MANUFACTURING_PURCHASE_ORDER }}"; -var flagNamePluralUnitMeasurementIntervalExpirationUnsealed = "{{ model.FLAG_NAME_PLURAL_UNIT_MEASUREMENT_INTERVAL_EXPIRATION_UNSEALED }}"; -var flagNamePluralUnitMeasurementIntervalRecurrence = "{{ model.FLAG_NAME_PLURAL_UNIT_MEASUREMENT_INTERVAL_RECURRENCE }}"; -var flagNamePluralUnitMeasurementQuantity = "{{ model.FLAG_NAME_PLURAL_UNIT_MEASUREMENT_QUANTITY }}"; -var flagNameSingularUnitMeasurementIntervalExpirationUnsealed = "{{ model.FLAG_NAME_SINGULAR_UNIT_MEASUREMENT_INTERVAL_EXPIRATION_UNSEALED }}"; -var flagNameSingularUnitMeasurementIntervalRecurrence = "{{ model.FLAG_NAME_SINGULAR_UNIT_MEASUREMENT_INTERVAL_RECURRENCE }}"; -var flagNameSingularUnitMeasurementQuantity = "{{ model.FLAG_NAME_SINGULAR_UNIT_MEASUREMENT_QUANTITY }}"; -var flagOrderItems = "{{ model.FLAG_ORDER_ITEMS }}"; -var flagPlant = "{{ model.FLAG_PLANT }}"; -{# -var flagPriceLocalVatExcl = "{{ model.FLAG_PRICE_LOCAL_VAT_EXCL }}"; -var flagPriceLocalVatIncl = "{{ model.FLAG_PRICE_LOCAL_VAT_INCL }}"; -#} -var flagPriceTotalLocalVatExcl = "{{ model.FLAG_PRICE_TOTAL_LOCAL_VAT_EXCL }}"; -var flagPriceTotalLocalVatIncl = "{{ model.FLAG_PRICE_TOTAL_LOCAL_VAT_INCL }}"; -var flagPriceUnitLocalVatExcl = "{{ model.FLAG_PRICE_UNIT_LOCAL_VAT_EXCL }}"; -var flagPriceUnitLocalVatIncl = "{{ model.FLAG_PRICE_UNIT_LOCAL_VAT_INCL }}"; -var flagProduct = "{{ model.FLAG_PRODUCT }}"; -var flagProductCategory = "{{ model.FLAG_PRODUCT_CATEGORY }}"; -var flagProductPermutation = "{{ model.FLAG_PRODUCT_PERMUTATION }}"; -var flagProductPrice = "{{ model.FLAG_PRODUCT_PRICE }}"; -var flagProductVariation = "{{ model.FLAG_PRODUCT_VARIATION }}"; -var flagProductVariations = "{{ model.FLAG_PRODUCT_VARIATIONS }}"; -var flagProductVariationType = "{{ model.FLAG_PRODUCT_VARIATION_TYPE }}"; -var flagProfitLocalMin = "{{ model.FLAG_PROFIT_LOCAL_MIN }}"; -var flagQuantity = "{{ model.FLAG_QUANTITY }}"; -var flagQuantityMin = "{{ model.FLAG_QUANTITY_MIN }}"; -var flagQuantityMax = "{{ model.FLAG_QUANTITY_MAX }}"; -var flagQuantityOrdered = "{{ model.FLAG_QUANTITY_ORDERED }}"; -var flagQuantityReceived = "{{ model.FLAG_QUANTITY_RECEIVED }}"; -var flagQuantityStock = "{{ model.FLAG_QUANTITY_STOCK }}"; -var flagRegion = "{{ model.FLAG_REGION }}"; -var flagStockItem = "{{ model.FLAG_STOCK_ITEM }}"; -var flagStorageLocation = "{{ model.FLAG_STORAGE_LOCATION }}"; -var flagSupplier = "{{ model.FLAG_SUPPLIER }}"; -var flagSupplierAddress = "{{ model.FLAG_SUPPLIER_ADDRESS }}"; -var flagSupplierPurchaseOrder = "{{ model.FLAG_SUPPLIER_PURCHASE_ORDER }}"; -var flagSymbolCurrencyCost = "{{ model.FLAG_SYMBOL_CURRENCY_COST }}"; -var flagSymbolIsSuffixNotPrefixUnitMeasurementIntervalExpirationUnsealed = "{{ model.FLAG_SYMBOL_IS_SUFFIX_NOT_PREFIX_UNIT_INTERVAL_EXPIRATION_UNSEALED }}"; -var flagSymbolIsSuffixNotPrefixUnitMeasurementIntervalRecurrence = "{{ model.FLAG_SYMBOL_IS_SUFFIX_NOT_PREFIX_UNIT_MEASUREMENT_INTERVAL_RECURRENCE }}"; -var flagSymbolIsSuffixNotPrefixUnitMeasurementQuantity = "{{ model.FLAG_SYMBOL_IS_SUFFIX_NOT_PREFIX_UNIT_MEASUREMENT_QUANTITY }}"; -var flagSymbolUnitMeasurementIntervalExpirationUnsealed = "{{ model.FLAG_SYMBOL_UNIT_MEASUREMENT_INTERVAL_EXPIRATION_UNSEALED }}"; -var flagSymbolUnitMeasurementIntervalRecurrence = "{{ model.FLAG_SYMBOL_UNIT_MEASUREMENT_INTERVAL_RECURRENCE }}"; -var flagSymbolUnitMeasurementQuantity = "{{ model.FLAG_SYMBOL_UNIT_MEASUREMENT_QUANTITY }}"; -var flagUnitMeasurementIntervalExpirationUnsealed = "{{ model.FLAG_UNIT_MEASUREMENT_INTERVAL_EXPIRATION_UNSEALED }}"; -var flagUnitMeasurementIntervalRecurrence = "{{ model.FLAG_UNIT_MEASUREMENT_INTERVAL_RECURRENCE }}"; -var flagUnitMeasurementLatencyManufacture = "{{ model.FLAG_UNIT_MEASUREMENT_LATENCY_MANUFACTURE }}"; -var flagUnitMeasurementQuantity = "{{ model.FLAG_UNIT_MEASUREMENT_QUANTITY }}"; -{# - var hashGetStoreCustomerSalesOrder = "{{ model.HASH_GET_STORE_CUSTOMER_SALES_ORDER }}"; - var hashGetStoreManufacturingPurchaseOrder = "{{ model.HASH_GET_STORE_MANUFACTURING_PURCHASE_ORDER }}"; - var hashGetStoreProduct = "{{ model.HASH_GET_STORE_PRODUCT }}"; - var hashGetStoreProductCategory = "{{ model.HASH_GET_STORE_PRODUCT_CATEGORY }}"; - var hashGetStoreProductPermutation = "{{ model.HASH_GET_STORE_PRODUCT_PERMUTATION }}"; - var hashGetStoreProductVariation = "{{ model.HASH_GET_STORE_PRODUCT_VARIATION }}"; - var hashGetStoreStockItem = "{{ model.HASH_GET_STORE_STOCK_ITEM }}"; - var hashGetStoreSupplier = "{{ model.HASH_GET_STORE_SUPPLIER }}"; - var hashGetStoreSupplierPurchaseOrder = "{{ model.HASH_GET_STORE_SUPPLIER_PURCHASE_ORDER }}"; -#} -var hashSaveStoreCustomerSalesOrder = "{{ model.HASH_SAVE_STORE_CUSTOMER_SALES_ORDER }}"; -var hashSaveStoreManufacturingPurchaseOrder = "{{ model.HASH_SAVE_STORE_MANUFACTURING_PURCHASE_ORDER }}"; -var hashSaveStoreProduct = "{{ model.HASH_SAVE_STORE_PRODUCT }}"; -var hashSaveStoreProductCategory = "{{ model.HASH_SAVE_STORE_PRODUCT_CATEGORY }}"; -var hashSaveStoreProductPermutation = "{{ model.HASH_SAVE_STORE_PRODUCT_PERMUTATION }}"; -var hashSaveStoreProductVariation = "{{ model.HASH_SAVE_STORE_PRODUCT_VARIATION }}"; -var hashSaveStoreStockItem = "{{ model.HASH_SAVE_STORE_STOCK_ITEM }}"; -var hashSaveStoreSupplier = "{{ model.HASH_SAVE_STORE_SUPPLIER }}"; -var hashSaveStoreSupplierPurchaseOrder = "{{ model.HASH_SAVE_STORE_SUPPLIER_PURCHASE_ORDER }}"; -var hashStoreBasketAdd = "{{ model.HASH_STORE_BASKET_ADD }}"; -var hashStoreBasketDelete = "{{ model.HASH_STORE_BASKET_DELETE }}"; -var hashStoreBasketEdit = "{{ model.HASH_STORE_BASKET_EDIT }}"; -var hashStoreBasketLoad = "{{ model.HASH_STORE_BASKET_LOAD }}"; -var hashStoreSetCurrency = "{{ model.HASH_STORE_SET_CURRENCY }}"; -var hashStoreSetRegion = "{{ model.HASH_STORE_SET_REGION }}"; -var hashStoreSetIsIncludedVAT = "{{ model.HASH_STORE_SET_IS_INCLUDED_VAT }}"; -var hashPageStoreBasket = "{{ model.HASH_PAGE_STORE_BASKET }}"; +var flagCommand = "{{ model.FLAG_COMMAND }}"; +var flagDog = "{{ model.FLAG_DOG }}"; +var flagDogCommandLink = "{{ model.FLAG_DOG_COMMAND_LINK }}"; var idBasket = "#{{ model.ID_BASKET }}"; -var idBasketContainer = "#{{ model.ID_BASKET_CONTAINER }}"; -var idBasketTotal = "#{{ model.ID_BASKET_TOTAL }}"; -var idButtonBasketAdd = "#{{ model.ID_BUTTON_BASKET_ADD }}"; -var idButtonBuyNow = "#{{ model.ID_BUTTON_BUY_NOW }}"; -var idButtonCheckout = "#{{ model.ID_BUTTON_CHECKOUT }}"; -var idCurrency = "#{{ model.ID_CURRENCY }}"; -var idCurrencyDefault = "#{{ model.ID_CURRENCY_DEFAULT }}"; -var idLabelBasketEmpty = "#{{ model.ID_LABEL_BASKET_EMPTY }}"; -var idProductCategoryDefault = "{{ model.ID_PRODUCT_CATEGORY_DEFAULT }}"; -var idRegionDeliveryDefault = "{{ model.ID_REGION_DELIVERY_DEFAULT }}"; -{# - var keyIdCurrency = "{{ model.KEY_ID_CURRENCY }}"; - var keyItems = "{{ model.KEY_ITEMS }}"; - var keyIdRegionDelivery = "{{ model.KEY_ID_REGION_DELIVERY }}"; - var keyIsIncludedVAT = "{{ model.KEY_IS_INCLUDED_VAT }}"; - var keyNameVariation = "{{ model.KEY_NAME_VARIATION }}"; - var keyNameVariationType = "{{ model.KEY_NAME_VARIATION_TYPE }}"; -#} var typeFormBasketAdd = "{{ model.TYPE_FORM_BASKET_ADD }}"; var typeFormBasketEdit = "{{ model.TYPE_FORM_BASKET_EDIT }}"; diff --git a/templates/layouts/_dog_shared.html b/templates/layouts/_dog_shared.html index 59908b3..19fb831 100644 --- a/templates/layouts/_dog_shared.html +++ b/templates/layouts/_dog_shared.html @@ -5,27 +5,11 @@ {% elif block_id == 'checkout' %} {% endif %} \ No newline at end of file diff --git a/templates/layouts/layout.html b/templates/layouts/layout.html index 8d3591d..13dc2ee 100644 --- a/templates/layouts/layout.html +++ b/templates/layouts/layout.html @@ -3,7 +3,7 @@ - {{ model.title }} - {{ model.NAME_COMPANY_SHORT }} + {{ model.title }} - DOG @@ -14,7 +14,7 @@ "name": "{{ model.NAME_COMPANY }}", "url": "{{ model.get_url_host() }}", "logo": "{{ model.get_url_host() }}{{ url_for('static', filename='images/Logo.png') }}", - "description": "Explore our wide range of software engineering services. We specialize in various tech stacks including MySQL, Python, Microsoft SQL Server, C#, Firebase, Node.js, Java, HTML5, React, CSS3, Flask, JavaScript, MVC, and REST.", + "description": "Dog training management web app.", "address": { "@type": "PostalAddress", "streetAddress": "53 Alfred Green Close", @@ -38,15 +38,25 @@ diff --git a/templates/pages/core/_admin_home.html b/templates/pages/core/DEPRECATED_admin_home.html similarity index 100% rename from templates/pages/core/_admin_home.html rename to templates/pages/core/DEPRECATED_admin_home.html diff --git a/templates/pages/core/_home_portfolio.html b/templates/pages/core/DEPRECATED_home_portfolio.html similarity index 100% rename from templates/pages/core/_home_portfolio.html rename to templates/pages/core/DEPRECATED_home_portfolio.html diff --git a/templates/pages/core/_home.html b/templates/pages/core/_home.html index 9c2999c..a5e5cfd 100644 --- a/templates/pages/core/_home.html +++ b/templates/pages/core/_home.html @@ -6,8 +6,15 @@
-

We make websites, web apps, and desktop software

- {% set block_id = 'button_get_in_touch' %} - {% include 'components/common/buttons/_buttons_save_cancel.html' %} +

Dog Training!

+ {% if not model.user.get_is_logged_in() %} +
+ +
+ {% elif model.user.can_admin_dog %} +
+ Dog Home +
+ {% endif %}
{% endblock %} \ No newline at end of file diff --git a/templates/pages/dog/_dog_command_links.html b/templates/pages/dog/_dog_command_links.html index b71bfb4..e410f61 100644 --- a/templates/pages/dog/_dog_command_links.html +++ b/templates/pages/dog/_dog_command_links.html @@ -1,17 +1,33 @@ {% extends 'layouts/layout.html' %} {% block page_body %} - +
{{ model.form_filters.hidden_tag() }}
-
- {{ model.form_filters.active_only.label }} - {{ model.form_filters.active_only() }} - {% for error in model.form_filters.active_only.errors %} -

{{ error }}

- {% endfor %} +
+
+ {{ model.form_filters.id_dog.label }} + {{ model.form_filters.id_dog() }} + {% for error in model.form_filters.id_dog.errors %} +

{{ error }}

+ {% endfor %} +
+
+ {{ model.form_filters.id_command.label }} + {{ model.form_filters.id_command() }} + {% for error in model.form_filters.id_command.errors %} +

{{ error }}

+ {% endfor %} +
+
+ {{ model.form_filters.active_only.label }} + {{ model.form_filters.active_only() }} + {% for error in model.form_filters.active_only.errors %} +

{{ error }}

+ {% endfor %} +
{% set block_id = 'buttons_table_default' %} @@ -26,8 +42,8 @@ Hand Signal Notes - {% set block_id = 'button_add' %} - {% include 'components/common/buttons/_buttons_save_cancel.html' %} + {% set colour = model.COLOUR_PRIMARY %} + {% include 'components/common/buttons/_icon_add.html' %} @@ -48,9 +64,14 @@ {% endblock %} \ No newline at end of file diff --git a/templates/pages/dog/_home.html b/templates/pages/dog/_home.html index 970c008..1ca07b8 100644 --- a/templates/pages/dog/_home.html +++ b/templates/pages/dog/_home.html @@ -3,34 +3,19 @@ {% block title %}{{ model.title }}{% endblock %} {% block page_body %} - +
-

Store

+

Dog

- +
- +
- -
-
- -
-
- -
-
- -
-
- -
-
- +
diff --git a/templates/pages/user/_user.html b/templates/pages/user/_user.html index 5b0f028..c06815d 100644 --- a/templates/pages/user/_user.html +++ b/templates/pages/user/_user.html @@ -24,13 +24,6 @@
-
-
- - {% set currency = user.currency_default %} - {% include 'components/store/_preview_DDL_currency.html' %} -
-
diff --git a/todo.txt b/todo.txt index 672ef30..4880a18 100644 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,5 @@ -Dark mode / light mode +Command list random generator for assessment - and any other variables e.g. location, handler -git commit -m "Feat: \n 1. Contact Us page form submission success page created. \n 2. Contact Us page styling and CAPTCHA text content. \n 3. Removal of ERP, Google CAPTCHA, and ALTCHA API code and left over comments in JavaScript, Python." \ No newline at end of file +Dog Command Link +Last tested \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index a792af4..a8e5d32 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -8,8 +8,18 @@ module.exports = { path.resolve(__dirname, 'static/js/app.js'), path.resolve(__dirname, 'static/css/main.css'), path.resolve(__dirname, 'static/css/components/button.css'), + path.resolve(__dirname, 'static/css/components/card.css'), + path.resolve(__dirname, 'static/css/components/dialog.css'), + path.resolve(__dirname, 'static/css/components/form.css'), + path.resolve(__dirname, 'static/css/components/image.css'), + path.resolve(__dirname, 'static/css/components/label.css'), + path.resolve(__dirname, 'static/css/components/modal.css'), + path.resolve(__dirname, 'static/css/components/navigation.css'), + path.resolve(__dirname, 'static/css/components/overlay.css'), + path.resolve(__dirname, 'static/css/components/table.css'), path.resolve(__dirname, 'static/css/layouts/header.css'), path.resolve(__dirname, 'static/css/layouts/footer.css'), + path.resolve(__dirname, 'static/css/layouts/table-main.css'), path.resolve(__dirname, 'static/css/lib/reset.css'), path.resolve(__dirname, 'static/css/lib/typography.css'), path.resolve(__dirname, 'static/css/lib/utils.css'), @@ -22,9 +32,9 @@ module.exports = { path.resolve(__dirname, 'static/css/sections/core.css'), path.resolve(__dirname, 'static/css/pages/core/home.css') ], - core_contact: [ + core_admin_home: [ path.resolve(__dirname, 'static/css/sections/core.css'), - path.resolve(__dirname, 'static/css/pages/core/contact.css') + path.resolve(__dirname, 'static/css/pages/core/admin_home.css') ], // Legal /* @@ -50,6 +60,23 @@ module.exports = { path.resolve(__dirname, 'static/css/sections/legal.css'), path.resolve(__dirname, 'static/css/pages/legal/privacy_policy.css') ], + // Dog + dog_home: [ + path.resolve(__dirname, 'static/css/sections/dog.css'), + path.resolve(__dirname, 'static/css/pages/dog/home.css') + ], + dog_dogs: [ + path.resolve(__dirname, 'static/css/sections/dog.css'), + path.resolve(__dirname, 'static/css/pages/dog/dogs.css') + ], + dog_commands: [ + path.resolve(__dirname, 'static/css/sections/dog.css'), + path.resolve(__dirname, 'static/css/pages/dog/commands.css') + ], + dog_dog_command_links: [ + path.resolve(__dirname, 'static/css/sections/dog.css'), + path.resolve(__dirname, 'static/css/pages/dog/dog_command_links.css') + ], }, output: { filename: 'js/[name].bundle.js',