diff --git a/README.md b/README.md
index 1e486389..37bef582 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,12 @@ Website with online store
Powered by flask
+enter virtual environment:
+python -m venv VIRTUAL_ENVIRONMENT_NAME
+
+run module bundler:
+npm run build
+
host for machine:
python -m flask run
diff --git a/app.log b/app.log
index 06d4b320..383ef3ea 100644
--- a/app.log
+++ b/app.log
@@ -1,20 +1,4 @@
Traceback: Traceback (most recent call last):
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1967, in _exec_single_context
- self.dialect.do_execute(
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\default.py", line 924, in do_execute
- cursor.execute(statement, parameters)
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute
- res = self._query(mogrified_query)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query
- db.query(q)
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\connections.py", line 261, in query
- _mysql.connection.query(self, query)
-MySQLdb.OperationalError: (1318, 'Incorrect number of arguments for PROCEDURE partsltd_prod.p_shop_get_many_product_variation; expected 8, got 10')
-
-The above exception was the direct cause of the following exception:
-
-Traceback (most recent call last):
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 1473, in wsgi_app
response = self.full_dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -30,59 +14,33 @@ Traceback (most recent call last):
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 865, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\controllers\store\product.py", line 113, in products
- model = Model_View_Store_Product(form_filters)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\models\model_view_store_product.py", line 115, in __init__
- self.variation_types, self.variations, errors = self.get_many_product_variation()
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\models\model_view_store.py", line 454, in get_many_product_variation
- variation_types, variations, errors = DataStore_Store_Base().get_many_product_variation(variation_filters)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\datastores\datastore_store_base.py", line 290, in get_many_product_variation
- result = cls.db_procedure_execute('p_shop_get_many_product_variation', argument_dict_list)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\datastores\datastore_base.py", line 95, in db_procedure_execute
- result = db.session.execute(proc_string, argument_dict_list)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\orm\scoping.py", line 778, in execute
- return self._proxied.execute(
- ^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\orm\session.py", line 2351, in execute
- return self._execute_internal(
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\controllers\store\product.py", line 114, in products
+ return render_template('pages/store/_products.html', model = model)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\templating.py", line 150, in render_template
+ return _render(app, template, context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\templating.py", line 131, in _render
+ rv = template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\jinja2\environment.py", line 1304, in render
+ self.environment.handle_exception()
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\jinja2\environment.py", line 939, in handle_exception
+ raise rewrite_traceback_stack(source=source)
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\templates\pages\store\_products.html", line 1, in top-level template code
+ {% extends 'layouts/layout.html' %}
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\templates\layouts\layout.html", line 316, in top-level template code
+ {% block page_body %}{% endblock %}
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\templates\pages\store\_products.html", line 89, in block 'page_body'
+ {% include 'components/store/_row_product.html' %}
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\templates\components\store\_row_product.html", line 38, in top-level template code
+
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\jinja2\environment.py", line 487, in getattr
+ return getattr(obj, attribute)
^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\orm\session.py", line 2245, in _execute_internal
- result = conn.execute(
- ^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1418, in execute
- return meth(
- ^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\sql\elements.py", line 515, in _execute_on_connection
- return connection._execute_clauseelement(
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1640, in _execute_clauseelement
- ret = self._execute_context(
- ^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1846, in _execute_context
- return self._exec_single_context(
- ^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1986, in _exec_single_context
- self._handle_dbapi_exception(
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 2353, in _handle_dbapi_exception
- raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1967, in _exec_single_context
- self.dialect.do_execute(
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\default.py", line 924, in do_execute
- cursor.execute(statement, parameters)
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute
- res = self._query(mogrified_query)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query
- db.query(q)
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\connections.py", line 261, in query
- _mysql.connection.query(self, query)
-sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (1318, 'Incorrect number of arguments for PROCEDURE partsltd_prod.p_shop_get_many_product_variation; expected 8, got 10')
-[SQL: CALL p_shop_get_many_product_variation(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)]
-[parameters: (1, 0, True, False, False, '', True, False, False, '')]
-(Background on this error at: https://sqlalche.me/e/20/e3q8)
+jinja2.exceptions.UndefinedError: 'permutation' is undefined
diff --git a/app.log.1 b/app.log.1
index 38d9ee1c..c31f5f8b 100644
--- a/app.log.1
+++ b/app.log.1
@@ -1,3 +1,50 @@
+Exception on /store/products [GET]
+Traceback (most recent call last):
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 1473, in wsgi_app
+ response = self.full_dispatch_request()
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 882, in full_dispatch_request
+ rv = self.handle_user_exception(e)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask_cors\extension.py", line 178, in wrapped_function
+ return cors_after_request(app.make_response(f(*args, **kwargs)))
+ ^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 880, in full_dispatch_request
+ rv = self.dispatch_request()
+ ^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 865, in dispatch_request
+ return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\controllers\store\product.py", line 114, in products
+ return render_template('pages/store/_products.html', model = model)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\templating.py", line 150, in render_template
+ return _render(app, template, context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\templating.py", line 131, in _render
+ rv = template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\jinja2\environment.py", line 1304, in render
+ self.environment.handle_exception()
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\jinja2\environment.py", line 939, in handle_exception
+ raise rewrite_traceback_stack(source=source)
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\templates\pages\store\_products.html", line 1, in top-level template code
+ {% extends 'layouts/layout.html' %}
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\templates\layouts\layout.html", line 316, in top-level template code
+ {% block page_body %}{% endblock %}
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\templates\pages\store\_products.html", line 89, in block 'page_body'
+ {% include 'components/store/_row_product.html' %}
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\templates\components\store\_row_product.html", line 38, in top-level template code
+ |
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\jinja2\environment.py", line 487, in getattr
+ return getattr(obj, attribute)
+ ^^^^^^^^^^^^^^^^^^^^^^^
+jinja2.exceptions.UndefinedError: 'permutation' is undefined
+Server Error: 500 Internal Server Error: The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
Request: 127.0.0.1 GET http /store/products? Host: 127.0.0.1:5000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
diff --git a/app.log.2 b/app.log.2
index 8d58b086..b5df9777 100644
--- a/app.log.2
+++ b/app.log.2
@@ -1,89 +1,103 @@
-Exception on /store/products [GET]
-Traceback (most recent call last):
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1967, in _exec_single_context
- self.dialect.do_execute(
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\default.py", line 924, in do_execute
- cursor.execute(statement, parameters)
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute
- res = self._query(mogrified_query)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query
- db.query(q)
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\connections.py", line 261, in query
- _mysql.connection.query(self, query)
-MySQLdb.OperationalError: (1318, 'Incorrect number of arguments for PROCEDURE partsltd_prod.p_shop_get_many_product_variation; expected 8, got 10')
-
-The above exception was the direct cause of the following exception:
-
-Traceback (most recent call last):
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 1473, in wsgi_app
- response = self.full_dispatch_request()
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 882, in full_dispatch_request
- rv = self.handle_user_exception(e)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask_cors\extension.py", line 178, in wrapped_function
- return cors_after_request(app.make_response(f(*args, **kwargs)))
- ^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 880, in full_dispatch_request
- rv = self.dispatch_request()
- ^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 865, in dispatch_request
- return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\controllers\store\product.py", line 113, in products
- model = Model_View_Store_Product(form_filters)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\models\model_view_store_product.py", line 115, in __init__
- self.variation_types, self.variations, errors = self.get_many_product_variation()
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\models\model_view_store.py", line 454, in get_many_product_variation
- variation_types, variations, errors = DataStore_Store_Base().get_many_product_variation(variation_filters)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\datastores\datastore_store_base.py", line 290, in get_many_product_variation
- result = cls.db_procedure_execute('p_shop_get_many_product_variation', argument_dict_list)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\datastores\datastore_base.py", line 95, in db_procedure_execute
- result = db.session.execute(proc_string, argument_dict_list)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\orm\scoping.py", line 778, in execute
- return self._proxied.execute(
- ^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\orm\session.py", line 2351, in execute
- return self._execute_internal(
- ^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\orm\session.py", line 2245, in _execute_internal
- result = conn.execute(
- ^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1418, in execute
- return meth(
- ^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\sql\elements.py", line 515, in _execute_on_connection
- return connection._execute_clauseelement(
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1640, in _execute_clauseelement
- ret = self._execute_context(
- ^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1846, in _execute_context
- return self._exec_single_context(
- ^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1986, in _exec_single_context
- self._handle_dbapi_exception(
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 2353, in _handle_dbapi_exception
- raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1967, in _exec_single_context
- self.dialect.do_execute(
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\default.py", line 924, in do_execute
- cursor.execute(statement, parameters)
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute
- res = self._query(mogrified_query)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query
- db.query(q)
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\connections.py", line 261, in query
- _mysql.connection.query(self, query)
-sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (1318, 'Incorrect number of arguments for PROCEDURE partsltd_prod.p_shop_get_many_product_variation; expected 8, got 10')
-[SQL: CALL p_shop_get_many_product_variation(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)]
-[parameters: (1, 0, True, False, False, '', True, False, False, '')]
-(Background on this error at: https://sqlalche.me/e/20/e3q8)
-Server Error: 500 Internal Server Error: The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
+Exception on /store/products [GET]
+Traceback (most recent call last):
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 1473, in wsgi_app
+ response = self.full_dispatch_request()
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 882, in full_dispatch_request
+ rv = self.handle_user_exception(e)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask_cors\extension.py", line 178, in wrapped_function
+ return cors_after_request(app.make_response(f(*args, **kwargs)))
+ ^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 880, in full_dispatch_request
+ rv = self.dispatch_request()
+ ^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 865, in dispatch_request
+ return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\controllers\store\product.py", line 113, in products
+ model = Model_View_Store_Product(form_filters)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\models\model_view_store_product.py", line 101, in __init__
+ self.category_list_filters, errors_filters = datastore_store.get_many_product(
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\datastores\datastore_store_base.py", line 110, in get_many_product
+ category_list.add_product(new_product)
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\business_objects\store\product_category.py", line 337, in add_product
+ self.categories[index_category].add_product(product)
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\business_objects\store\product_category.py", line 100, in add_product
+ raise ValueError(f"{av.error_msg_str(product, 'product', _m, Product)}\nProduct already in category.")
+ValueError: Invalid Category.add_product argument product. Type = . Value = Product
+ id_product: 1
+ id_category: 1
+ name: Braille Keyboard Translator
+ display_order: 1
+ can_view: False
+ can_edit: False
+ can_admin: False
+ has_variations: True
+ permutations: []
+ variation trees: []
+
+Product already in category.
+Server Error: 500 Internal Server Error: The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
+Request: 127.0.0.1 GET http /store/products? Host: 127.0.0.1:5000
+User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
+Accept-Language: en-GB,en;q=0.5
+Accept-Encoding: gzip, deflate, br, zstd
+Dnt: 1
+Connection: keep-alive
+Cookie: session=.eJytVlmzqkgS_isdRnQ_9fGyKyfixoyKAh5BQWR7IaCqkGJXQIGe-9-n8Nzu2w89W8REuFCVReaXlV8uv83Crk2qO24QvDToPnv_bQbCMghhgcugaas7mr239w79-qft7nXwcxcVIc5n7zMEn-EdzgsMYY7aqmwK3CZ_v07SOaiK2a-zGN-btgwLonBmIQgHsodhALr7HZVgCCCKwy5vZ-9ll-cv0R1dcVX-heATAP3HczA5QRG9r_9_CPySiUQeLEUeUmK4oKKQpmIUTwab4IU4eKA7jjGCs_c4zBv0kuAS5B1EMLBX1g-rn34ScdPVxNSfnW-6-3eHtN_9fjtPjs--kftq7nHQVhkqJ2AxRECkKQQBtVjwUBRYCjIAiSwLUMwxgAc8omiRQOy-hyEEADXNHxrQsE8iGeAj3mehq-LDZp9HhTat11p6YUxK11X8xKGrj2pa4VAxKaBowmEQM9_12qiESTiqTz31cz_1q6OccxHmaTDwCXTNStvwacRQD7Wk5nP69pEeN63Xs9qCtY7SPNPvelBJyWjCRoVL5xS_qcch6jvTfFv64zBIvtZq7DFmesA01INmH8M1UvcX6oPpRemNH24tqHUlTNHxKGin8-3UFH2lItye1Kpiec9glm9e6Ny2fT_y8IFF-Tgm0nmzUFSLSx4XvEykeC1KciuiJyuBvJIr1ts-ojI5yZuyP-XVclPvW1PHhxJFHYkuXgyHoaUT0fKTzEhE1m-kYH3gtos8o07W6iOV2coJ-BAd1K0aLJPuiQqVF_L1QU7PV1_sKnUXMzGIrxqDW3e4sSPd2HveXudvzaa63xB73nXJ5ZwPmmr2sd0v8rTJ8JA8alzRwZFyVsYQO81eFV0uyNvjkG9OaprWhwwgq8TRfC3rqwh_SLorJ9ytrKWjtpQNQgPU1_iOmiAkFKQXzIJb8Cwl_NjHhBRLgaOoVxb8BUvOl1Gldaw2amnyYKMKala79oasi7b2p3VpP5DrX8yM46J0__CVK21nu4O2S2hz2ItzoqwLHf0eFbvWP5MXCjuDzG7wN3wbOmYWyTYVMfwYOTkVvhTzSeRcJuO5r8AEFEZHZJkv9zmUxQ4wdA3lZOUzdBI6z85jxHaiLJDzFCr28GkjoaCyHo94-SDULEGxYzzXTAD-pKfn-gmUd8NhvIy-pBdaalCaBDPdIs4yHqfL3qAzeqJJgNNHE_uSR51YTdSl63NfqiKQQeFLdAUV8wmGy2icL4OJybfQM5IOf06FXMuIrWJHee5-3Ft72XeMDsh8OWGG7jojuHJ_JyZwusxUfRIsrSZlrZb6Fy1VBc26CJqkdZqljs4UiMJuPSdvpvT0HZMlerNDQde-bDa-axIq621I7BsyfJ07FPojOv94z2X9HBR5ETp2pqZ14Tn96J__DylP_PHcSSfBRcEbcs3eymjXYBIrdJPeGslN5TvBzhLXcHb5OauFS5FNJaj2XAMf0y2rpWA8Slee-Dvh5SbCaRYY9NEYdCl7agOJM2vjyQaxRYXSeqmnF04jCac7Gne07EyT8kQf19iztk-_sIsXN5j8E5eja2gLlShLSv3SmtEWjkamF7aUqOedeNEKj7HovW6UYMLVEV6mLz5luu3IKuXRJqex9tYo7Ifv7lL74vVTqasUVbPtymBpJ6WuPCmoSu4bT4aT1Nj4uLjMVcq8K7nM5Iykw5PnYLg2WXtVNxQ2Y1nBNAu45hQssjcufabSJUJ8TDJsOCtKCarTIj6p5rgZF0bAhdZtw36sFXf4WIVUsQKatH8AihMUwHCHmw2b2CrDTblqgnO81LitVfHr5NzXYXuWRy5ERd3E-TVZ9fx221egdsL6Lm8Fz1oeOit-eLlB6tSmaSk6CPEu_bAt2G0dUX-uFS4By_gSX_lYZy05FAWmk-W3Rx7oMtrwxoe9Pev1oQ8_qrRopdUTq3WlC8qyHMaTE-_larMbvVawbCE7DXfTrg8nuiL9mKSgnqzMnbq-YWXTNGi8Bt6T1K8GVPXUGclvieFP9b2KcY5--pwXfp29ClbQDq8zaxTeSdP77H24jKtX_-tIc55d5XRob7rmbJIz7m_HBWMao604qxDt9yS_Z__LCPIvWj8pqd9rLMOJFEsK6u9Fl10uPzeahhhI2rZu3r98gejxVj7DjKEEAcVCssR9Oe-a-Wv6mEx9Iba-Dwb_GVSJQfbvDk9HqhJM8s3FjThg9WwnrVGFbuCyo4m4xqDtpkHtD4TN_HoPH2Eb3l9wPh-_8CxkY4bjqAXkGX4RL7mYWYCQWiwXXAQF7m_NV25J_XL_Wl9_gV9fun5mVz8zO_IBsPzhH1l_qmzIE4LzurxOEcdTwBA49LJcKlf-w8jlZr2JraWiBBYTC0dTW7-o0UX_zazW1TBsyTQ2BWPGUAz3RolvjGAxzDvNv1PsnGZYf_bt27d_Agdyo3I.ZvXc6g.WpR0PQjTMWhM_qBkpa9CVzq95M8
+Upgrade-Insecure-Requests: 1
+Sec-Fetch-Dest: document
+Sec-Fetch-Mode: navigate
+Sec-Fetch-Site: none
+Sec-Fetch-User: ?1
+Sec-Gpc: 1
+Priority: u=0, i
+
+
+Request data: b''
+Traceback: Traceback (most recent call last):
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 1473, in wsgi_app
+ response = self.full_dispatch_request()
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 882, in full_dispatch_request
+ rv = self.handle_user_exception(e)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask_cors\extension.py", line 178, in wrapped_function
+ return cors_after_request(app.make_response(f(*args, **kwargs)))
+ ^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 880, in full_dispatch_request
+ rv = self.dispatch_request()
+ ^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 865, in dispatch_request
+ return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\controllers\store\product.py", line 113, in products
+ model = Model_View_Store_Product(form_filters)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\models\model_view_store_product.py", line 101, in __init__
+ self.category_list_filters, errors_filters = datastore_store.get_many_product(
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\datastores\datastore_store_base.py", line 110, in get_many_product
+ category_list.add_product(new_product)
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\business_objects\store\product_category.py", line 337, in add_product
+ self.categories[index_category].add_product(product)
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\business_objects\store\product_category.py", line 100, in add_product
+ raise ValueError(f"{av.error_msg_str(product, 'product', _m, Product)}\nProduct already in category.")
+ValueError: Invalid Category.add_product argument product. Type = . Value = Product
+ id_product: 1
+ id_category: 1
+ name: Braille Keyboard Translator
+ display_order: 1
+ can_view: False
+ can_edit: False
+ can_admin: False
+ has_variations: True
+ permutations: []
+ variation trees: []
+
+Product already in category.
+
diff --git a/app.log.3 b/app.log.3
index 16b41917..c9275d8f 100644
--- a/app.log.3
+++ b/app.log.3
@@ -1,88 +1,103 @@
-Traceback: Traceback (most recent call last):
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1967, in _exec_single_context
- self.dialect.do_execute(
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\default.py", line 924, in do_execute
- cursor.execute(statement, parameters)
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute
- res = self._query(mogrified_query)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query
- db.query(q)
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\connections.py", line 261, in query
- _mysql.connection.query(self, query)
-MySQLdb.OperationalError: (1318, 'Incorrect number of arguments for PROCEDURE partsltd_prod.p_shop_get_many_product_variation; expected 8, got 9')
-
-The above exception was the direct cause of the following exception:
-
-Traceback (most recent call last):
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 1473, in wsgi_app
- response = self.full_dispatch_request()
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 882, in full_dispatch_request
- rv = self.handle_user_exception(e)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask_cors\extension.py", line 178, in wrapped_function
- return cors_after_request(app.make_response(f(*args, **kwargs)))
- ^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 880, in full_dispatch_request
- rv = self.dispatch_request()
- ^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 865, in dispatch_request
- return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\controllers\store\product.py", line 113, in products
- model = Model_View_Store_Product(form_filters)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\models\model_view_store_product.py", line 115, in __init__
- self.variation_types, self.variations, errors = self.get_many_product_variation()
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\models\model_view_store.py", line 454, in get_many_product_variation
- variation_types, variations, errors = DataStore_Store_Base().get_many_product_variation(variation_filters)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\datastores\datastore_store_base.py", line 289, in get_many_product_variation
- result = cls.db_procedure_execute('p_shop_get_many_product_variation', argument_dict_list)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\datastores\datastore_base.py", line 95, in db_procedure_execute
- result = db.session.execute(proc_string, argument_dict_list)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\orm\scoping.py", line 778, in execute
- return self._proxied.execute(
- ^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\orm\session.py", line 2351, in execute
- return self._execute_internal(
- ^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\orm\session.py", line 2245, in _execute_internal
- result = conn.execute(
- ^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1418, in execute
- return meth(
- ^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\sql\elements.py", line 515, in _execute_on_connection
- return connection._execute_clauseelement(
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1640, in _execute_clauseelement
- ret = self._execute_context(
- ^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1846, in _execute_context
- return self._exec_single_context(
- ^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1986, in _exec_single_context
- self._handle_dbapi_exception(
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 2353, in _handle_dbapi_exception
- raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 1967, in _exec_single_context
- self.dialect.do_execute(
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\sqlalchemy\engine\default.py", line 924, in do_execute
- cursor.execute(statement, parameters)
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute
- res = self._query(mogrified_query)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query
- db.query(q)
- File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\MySQLdb\connections.py", line 261, in query
- _mysql.connection.query(self, query)
-sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (1318, 'Incorrect number of arguments for PROCEDURE partsltd_prod.p_shop_get_many_product_variation; expected 8, got 9')
-[SQL: CALL p_shop_get_many_product_variation(%s, %s, %s, %s, %s, %s, %s, %s, %s)]
-[parameters: (1, True, False, False, '', True, False, False, '')]
-(Background on this error at: https://sqlalche.me/e/20/e3q8)
-
+Exception on /store/products [GET]
+Traceback (most recent call last):
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 1473, in wsgi_app
+ response = self.full_dispatch_request()
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 882, in full_dispatch_request
+ rv = self.handle_user_exception(e)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask_cors\extension.py", line 178, in wrapped_function
+ return cors_after_request(app.make_response(f(*args, **kwargs)))
+ ^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 880, in full_dispatch_request
+ rv = self.dispatch_request()
+ ^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 865, in dispatch_request
+ return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\controllers\store\product.py", line 113, in products
+ model = Model_View_Store_Product(form_filters)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\models\model_view_store_product.py", line 101, in __init__
+ self.category_list_filters, errors_filters = datastore_store.get_many_product(
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\datastores\datastore_store_base.py", line 109, in get_many_product
+ category_list.add_product(new_product)
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\business_objects\store\product_category.py", line 337, in add_product
+ self.categories[index_category].add_product(product)
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\business_objects\store\product_category.py", line 100, in add_product
+ raise ValueError(f"{av.error_msg_str(product, 'product', _m, Product)}\nProduct already in category.")
+ValueError: Invalid Category.add_product argument product. Type = . Value = Product
+ id_product: 1
+ id_category: 1
+ name: Braille Keyboard Translator
+ display_order: 1
+ can_view: False
+ can_edit: False
+ can_admin: False
+ has_variations: True
+ permutations: []
+ variation trees: []
+
+Product already in category.
+Server Error: 500 Internal Server Error: The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
+Request: 127.0.0.1 GET http /store/products? Host: 127.0.0.1:5000
+User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
+Accept-Language: en-GB,en;q=0.5
+Accept-Encoding: gzip, deflate, br, zstd
+Dnt: 1
+Connection: keep-alive
+Cookie: session=.eJytVlmzqkgS_isdRnQ_9fGyKyfixoyKAh5BQWR7IaCqkGJXQIGe-9-n8Nzu2w89W8REuFCVReaXlV8uv83Crk2qO24QvDToPnv_bQbCMghhgcugaas7mr239w79-qft7nXwcxcVIc5n7zMEn-EdzgsMYY7aqmwK3CZ_v07SOaiK2a-zGN-btgwLonBmIQgHsodhALr7HZVgCCCKwy5vZ-9ll-cv0R1dcVX-heATAP3HczA5QRG9r_9_CPySiUQeLEUeUmK4oKKQpmIUTwab4IU4eKA7jjGCs_c4zBv0kuAS5B1EMLBX1g-rn34ScdPVxNSfnW-6-3eHtN_9fjtPjs--kftq7nHQVhkqJ2AxRECkKQQBtVjwUBRYCjIAiSwLUMwxgAc8omiRQOy-hyEEADXNHxrQsE8iGeAj3mehq-LDZp9HhTat11p6YUxK11X8xKGrj2pa4VAxKaBowmEQM9_12qiESTiqTz31cz_1q6OccxHmaTDwCXTNStvwacRQD7Wk5nP69pEeN63Xs9qCtY7SPNPvelBJyWjCRoVL5xS_qcch6jvTfFv64zBIvtZq7DFmesA01INmH8M1UvcX6oPpRemNH24tqHUlTNHxKGin8-3UFH2lItye1Kpiec9glm9e6Ny2fT_y8IFF-Tgm0nmzUFSLSx4XvEykeC1KciuiJyuBvJIr1ts-ojI5yZuyP-XVclPvW1PHhxJFHYkuXgyHoaUT0fKTzEhE1m-kYH3gtos8o07W6iOV2coJ-BAd1K0aLJPuiQqVF_L1QU7PV1_sKnUXMzGIrxqDW3e4sSPd2HveXudvzaa63xB73nXJ5ZwPmmr2sd0v8rTJ8JA8alzRwZFyVsYQO81eFV0uyNvjkG9OaprWhwwgq8TRfC3rqwh_SLorJ9ytrKWjtpQNQgPU1_iOmiAkFKQXzIJb8Cwl_NjHhBRLgaOoVxb8BUvOl1Gldaw2amnyYKMKala79oasi7b2p3VpP5DrX8yM46J0__CVK21nu4O2S2hz2ItzoqwLHf0eFbvWP5MXCjuDzG7wN3wbOmYWyTYVMfwYOTkVvhTzSeRcJuO5r8AEFEZHZJkv9zmUxQ4wdA3lZOUzdBI6z85jxHaiLJDzFCr28GkjoaCyHo94-SDULEGxYzzXTAD-pKfn-gmUd8NhvIy-pBdaalCaBDPdIs4yHqfL3qAzeqJJgNNHE_uSR51YTdSl63NfqiKQQeFLdAUV8wmGy2icL4OJybfQM5IOf06FXMuIrWJHee5-3Ft72XeMDsh8OWGG7jojuHJ_JyZwusxUfRIsrSZlrZb6Fy1VBc26CJqkdZqljs4UiMJuPSdvpvT0HZMlerNDQde-bDa-axIq621I7BsyfJ07FPojOv94z2X9HBR5ETp2pqZ14Tn96J__DylP_PHcSSfBRcEbcs3eymjXYBIrdJPeGslN5TvBzhLXcHb5OauFS5FNJaj2XAMf0y2rpWA8Slee-Dvh5SbCaRYY9NEYdCl7agOJM2vjyQaxRYXSeqmnF04jCac7Gne07EyT8kQf19iztk-_sIsXN5j8E5eja2gLlShLSv3SmtEWjkamF7aUqOedeNEKj7HovW6UYMLVEV6mLz5luu3IKuXRJqex9tYo7Ifv7lL74vVTqasUVbPtymBpJ6WuPCmoSu4bT4aT1Nj4uLjMVcq8K7nM5Iykw5PnYLg2WXtVNxQ2Y1nBNAu45hQssjcufabSJUJ8TDJsOCtKCarTIj6p5rgZF0bAhdZtw36sFXf4WIVUsQKatH8AihMUwHCHmw2b2CrDTblqgnO81LitVfHr5NzXYXuWRy5ERd3E-TVZ9fx221egdsL6Lm8Fz1oeOit-eLlB6tSmaSk6CPEu_bAt2G0dUX-uFS4By_gSX_lYZy05FAWmk-W3Rx7oMtrwxoe9Pev1oQ8_qrRopdUTq3WlC8qyHMaTE-_larMbvVawbCE7DXfTrg8nuiL9mKSgnqzMnbq-YWXTNGi8Bt6T1K8GVPXUGclvieFP9b2KcY5--pwXfp29ClbQDq8zaxTeSdP77H24jKtX_-tIc55d5XRob7rmbJIz7m_HBWMao604qxDt9yS_Z__LCPIvWj8pqd9rLMOJFEsK6u9Fl10uPzeahhhI2rZu3r98gejxVj7DjKEEAcVCssR9Oe-a-Wv6mEx9Iba-Dwb_GVSJQfbvDk9HqhJM8s3FjThg9WwnrVGFbuCyo4m4xqDtpkHtD4TN_HoPH2Eb3l9wPh-_8CxkY4bjqAXkGX4RL7mYWYCQWiwXXAQF7m_NV25J_XL_Wl9_gV9fun5mVz8zO_IBsPzhH1l_qmzIE4LzurxOEcdTwBA49LJcKlf-w8jlZr2JraWiBBYTC0dTW7-o0UX_zazW1TBsyTQ2BWPGUAz3RolvjGAxzDvNv1PsnGZYf_bt27d_Agdyo3I.ZvXc6g.WpR0PQjTMWhM_qBkpa9CVzq95M8
+Upgrade-Insecure-Requests: 1
+Sec-Fetch-Dest: document
+Sec-Fetch-Mode: navigate
+Sec-Fetch-Site: none
+Sec-Fetch-User: ?1
+Sec-Gpc: 1
+Priority: u=0, i
+
+
+Request data: b''
+Traceback: Traceback (most recent call last):
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 1473, in wsgi_app
+ response = self.full_dispatch_request()
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 882, in full_dispatch_request
+ rv = self.handle_user_exception(e)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask_cors\extension.py", line 178, in wrapped_function
+ return cors_after_request(app.make_response(f(*args, **kwargs)))
+ ^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 880, in full_dispatch_request
+ rv = self.dispatch_request()
+ ^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 865, in dispatch_request
+ return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\controllers\store\product.py", line 113, in products
+ model = Model_View_Store_Product(form_filters)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\models\model_view_store_product.py", line 101, in __init__
+ self.category_list_filters, errors_filters = datastore_store.get_many_product(
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\datastores\datastore_store_base.py", line 109, in get_many_product
+ category_list.add_product(new_product)
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\business_objects\store\product_category.py", line 337, in add_product
+ self.categories[index_category].add_product(product)
+ File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\business_objects\store\product_category.py", line 100, in add_product
+ raise ValueError(f"{av.error_msg_str(product, 'product', _m, Product)}\nProduct already in category.")
+ValueError: Invalid Category.add_product argument product. Type = . Value = Product
+ id_product: 1
+ id_category: 1
+ name: Braille Keyboard Translator
+ display_order: 1
+ can_view: False
+ can_edit: False
+ can_admin: False
+ has_variations: True
+ permutations: []
+ variation trees: []
+
+Product already in category.
+
diff --git a/business_objects/__pycache__/sql_error.cpython-312.pyc b/business_objects/__pycache__/sql_error.cpython-312.pyc
index 6424161b..18727de8 100644
Binary files a/business_objects/__pycache__/sql_error.cpython-312.pyc and b/business_objects/__pycache__/sql_error.cpython-312.pyc differ
diff --git a/business_objects/__pycache__/user.cpython-312.pyc b/business_objects/__pycache__/user.cpython-312.pyc
index 112be66a..06e7cefe 100644
Binary files a/business_objects/__pycache__/user.cpython-312.pyc and b/business_objects/__pycache__/user.cpython-312.pyc differ
diff --git a/business_objects/sql_error.py b/business_objects/sql_error.py
index 91710c57..9429fa52 100644
--- a/business_objects/sql_error.py
+++ b/business_objects/sql_error.py
@@ -34,6 +34,7 @@ db = SQLAlchemy()
# CLASSES
class SQL_Error(db.Model):
display_order = db.Column(db.Integer, primary_key=True)
+ id_type = db.Column(db.Integer)
code = db.Column(db.String(50))
msg = db.Column(db.String(4000))
name = db.Column(db.String(500))
@@ -58,8 +59,9 @@ class SQL_Error(db.Model):
def from_DB_record(record):
error = SQL_Error()
error.display_order = record[0]
- error.code = record[1]
- error.msg = record[2]
- error.name = record[3]
- error.description = record[4]
+ error.id_type = record[1]
+ error.code = record[2]
+ error.msg = record[3]
+ error.name = record[4]
+ error.description = record[5]
return error
\ No newline at end of file
diff --git a/business_objects/store/__pycache__/product.cpython-312.pyc b/business_objects/store/__pycache__/product.cpython-312.pyc
index 0dba4c8a..979001ec 100644
Binary files a/business_objects/store/__pycache__/product.cpython-312.pyc and b/business_objects/store/__pycache__/product.cpython-312.pyc differ
diff --git a/business_objects/store/__pycache__/product_category.cpython-312.pyc b/business_objects/store/__pycache__/product_category.cpython-312.pyc
index 648d3ad8..2b5014df 100644
Binary files a/business_objects/store/__pycache__/product_category.cpython-312.pyc and b/business_objects/store/__pycache__/product_category.cpython-312.pyc differ
diff --git a/business_objects/store/__pycache__/product_variation.cpython-312.pyc b/business_objects/store/__pycache__/product_variation.cpython-312.pyc
index 189bfe60..62365a3e 100644
Binary files a/business_objects/store/__pycache__/product_variation.cpython-312.pyc and b/business_objects/store/__pycache__/product_variation.cpython-312.pyc differ
diff --git a/business_objects/store/__pycache__/store_base.cpython-312.pyc b/business_objects/store/__pycache__/store_base.cpython-312.pyc
index 2a48fe6b..bdb86d5e 100644
Binary files a/business_objects/store/__pycache__/store_base.cpython-312.pyc and b/business_objects/store/__pycache__/store_base.cpython-312.pyc differ
diff --git a/business_objects/store/product.py b/business_objects/store/product.py
index 785c4670..7f1e460d 100644
--- a/business_objects/store/product.py
+++ b/business_objects/store/product.py
@@ -56,7 +56,7 @@ class Enum_Status_Stock(Enum):
class Product(SQLAlchemy_ABC, Store_Base):
NAME_ATTR_OPTION_VALUE: ClassVar[str] = Store_Base.ATTR_ID_PRODUCT
NAME_ATTR_OPTION_TEXT = Store_Base.FLAG_NAME
- FLAG_HAS_VARIATIONS: ClassVar[str] = 'has-variations-product'
+ # FLAG_HAS_VARIATIONS: ClassVar[str] = 'has-variations-product'
FLAG_INDEX_PERMUTATION_SELECTED: ClassVar[str] = 'index-permutation-selected'
FLAG_PRODUCT_VARIATION_TREES: ClassVar[str] = 'variation-trees'
@@ -74,6 +74,12 @@ class Product(SQLAlchemy_ABC, Store_Base):
# has_variations: bool
# index_permutation_selected: int
+ """
+ permutations: list = None
+ permutation_index: dict = None
+ variation_trees: list = None
+ """
+
def __init__(self):
self.permutations = []
self.permutation_index = {}
@@ -179,10 +185,26 @@ class Product(SQLAlchemy_ABC, Store_Base):
permutation = Product_Permutation.from_DB_Stripe_price(query_row)
product = Product.from_permutation(permutation)
return product
+ """
def from_json(json_basket_item, key_id_product, key_id_permutation):
permutation = Product_Permutation.from_json(json_basket_item, key_id_product, key_id_permutation)
product = Product.from_permutation(permutation)
return product
+ """
+ @classmethod
+ def from_json(cls, json):
+ product = cls()
+ product.id_product = json[cls.ATTR_ID_PRODUCT]
+ product.display_order = json[cls.FLAG_DISPLAY_ORDER]
+ product.id_category = json[cls.ATTR_ID_PRODUCT_CATEGORY]
+ product.name = json[cls.FLAG_NAME]
+ product.has_variations = av.input_bool(json.get(cls.FLAG_HAS_VARIATIONS, None), cls.FLAG_HAS_VARIATIONS, f'{cls.__name__}.from_json')
+ product.id_access_level_required = json.get(cls.ATTR_ID_ACCESS_LEVEL, None)
+ product.active = av.input_bool(json.get(cls.FLAG_ACTIVE, None), cls.FLAG_ACTIVE, f'{cls.__name__}.from_json')
+ product.can_view = json.get(cls.FLAG_CAN_VIEW, None)
+ product.can_edit = json.get(cls.FLAG_CAN_EDIT, None)
+ product.can_admin = json.get(cls.FLAG_CAN_ADMIN, None)
+ return product
def get_permutation_selected(self):
try:
return self.permutations[self.index_permutation_selected]
@@ -288,6 +310,7 @@ class Product(SQLAlchemy_ABC, Store_Base):
for permutation in self.permutations:
list_rows.append(permutation.to_row_permutation())
return list_rows
+ """
@classmethod
def from_json(cls, json):
product = cls()
@@ -307,6 +330,7 @@ class Product(SQLAlchemy_ABC, Store_Base):
for json_tree in json[cls.FLAG_PRODUCT_VARIATION_TREES]:
product.variation_trees.append(Product_Variation_Tree.from_json(json_tree))
return product
+ """
def to_json(self):
return {
**self.get_shared_json_attributes(self),
@@ -422,7 +446,7 @@ class Parameters_Product(Get_Many_Parameters_Base):
def from_form_filters_product(form):
# if not (form is Filters_Product_Permutation): raise ValueError(f'Invalid form type: {type(form)}')
av.val_instance(form, 'form', 'Parameters_Product.from_form', Filters_Product)
- has_filter_category = not (form.id_category.data == '0' or form.id_category.data == '')
+ has_filter_category = not (form.id_category.data == '0' or form.id_category.data == '' or form.id_category.data is None)
is_not_empty = av.input_bool(form.is_not_empty.data, "is_not_empty", "Parameters_Product.from_form_filters_product")
active = av.input_bool(form.active.data, "active", "Parameters_Product.from_form_filters_product")
return Parameters_Product(
@@ -812,4 +836,50 @@ class Parameters_Product(Get_Many_Parameters_Base):
@classmethod
def from_filters_stock_item(cls, filters_stock_item):
return cls.from_form_filters_product_permutation(filters_stock_item)
-"""
\ No newline at end of file
+"""
+
+class Product_Temp(db.Model, Store_Base):
+ __tablename__ = 'Shop_Product_Temp'
+ __table_args__ = { 'extend_existing': True }
+ id_product: int = db.Column(db.Integer, primary_key=True)
+ id_category: int = db.Column(db.Integer)
+ name: str = db.Column(db.String(255))
+ has_variations: bool = db.Column(db.Boolean)
+ id_access_level_required: int = db.Column(db.Integer)
+ active: bool = db.Column(db.Boolean)
+ display_order: int = db.Column(db.Integer)
+ guid: str = db.Column(db.BINARY(36))
+ # created_on: datetime = db.Column(db.DateTime)
+ # created_by: int = db.Column(db.Integer)
+
+ @classmethod
+ def from_product(cls, product):
+ row = cls()
+ row.id_product = product.id_product[0] if isinstance(product.id_product, tuple) else product.id_product
+ row.id_category = product.id_category[0] if isinstance(product.id_category, tuple) else product.id_category
+ row.name = product.name[0] if isinstance(product.name, tuple) else product.name
+ row.has_variations = product.has_variations
+ row.id_access_level_required = product.id_access_level_required[0] if isinstance(product.id_access_level_required, tuple) else product.id_access_level_required
+ row.active = product.active
+ row.display_order = product.display_order
+ """
+ row.guid = product.guid
+ row.created_on = product.created_on
+ row.created_by = product.created_by
+ """
+ return row
+ def to_json(self):
+ return {
+ 'id_product': self.id_product,
+ 'id_category': self.id_category,
+ 'name': self.name,
+ 'has_variations': av.input_bool(self.has_variations, self.FLAG_HAS_VARIATIONS, f'{self.__class__.__name__}.to_json'),
+ 'id_access_level_required': self.id_access_level_required,
+ 'active': av.input_bool(self.active, self.FLAG_ACTIVE, f'{self.__class__.__name__}.to_json'),
+ 'display_order': self.display_order,
+ 'guid': self.guid,
+ }
+ """
+ 'created_on': self.created_on,
+ 'created_by': self.created_by
+ """
diff --git a/business_objects/store/product_category.py b/business_objects/store/product_category.py
index edad544d..cf000111 100644
--- a/business_objects/store/product_category.py
+++ b/business_objects/store/product_category.py
@@ -45,6 +45,12 @@ class Product_Category(SQLAlchemy_ABC, Store_Base):
can_admin = db.Column(db.Boolean)
created_on = db.Column(db.DateTime)
created_by = db.Column(db.Integer)
+
+ """
+ products: list = None # []
+ product_index: dict = None # {}
+ """
+
def __init__(self):
self.products = []
self.product_index = {}
@@ -95,6 +101,7 @@ class Product_Category(SQLAlchemy_ABC, Store_Base):
# self.product_index[Category.key_product_index_from_ids_product_permutation(product.id_product, product.id_permutation)] = len(self.products)
try:
self.get_index_product(product)
+ print(f'category: {self}')
raise ValueError(f"{av.error_msg_str(product, 'product', _m, Product)}\nProduct already in category.")
except KeyError:
self.product_index[product.id_product] = len(self.products)
@@ -441,7 +448,7 @@ class Table_Shop_Product_Category(db.Model):
created_by: int = db.Column(db.Integer)
id_change_set: int = db.Column(db.Integer)
"""
-class Product_Category_Temp(db.Model):
+class Product_Category_Temp(db.Model, Store_Base):
__tablename__ = 'Shop_Product_Category_Temp'
__table_args__ = { 'extend_existing': True }
id_category: int = db.Column(db.Integer, primary_key=True)
diff --git a/business_objects/store/product_variation.py b/business_objects/store/product_variation.py
index 45998b77..63f1e2a6 100644
--- a/business_objects/store/product_variation.py
+++ b/business_objects/store/product_variation.py
@@ -120,22 +120,22 @@ class Product_Variation(db.Model, Store_Base):
class Product_Variation_Filters():
get_all_variation_type: bool
get_inactive_variation_type: bool
- get_first_variation_type: bool
+ # get_first_variation_type: bool
ids_variation_type: str
get_all_variation: bool
get_inactive_variation: bool
- get_first_variation: bool
+ # get_first_variation: bool
ids_variation: str
def to_json(self):
return {
'a_get_all_variation_type': self.get_all_variation_type,
'a_get_inactive_variation_type': self.get_inactive_variation_type,
- 'a_get_first_variation_type': self.get_first_variation_type,
+ # 'a_get_first_variation_type': self.get_first_variation_type,
'a_ids_variation_type': self.ids_variation_type,
'a_get_all_variation': self.get_all_variation,
'a_get_inactive_variation': self.get_inactive_variation,
- 'a_get_first_variation': self.get_first_variation,
+ # 'a_get_first_variation': self.get_first_variation,
'a_ids_variation': self.ids_variation,
}
@@ -170,11 +170,11 @@ class Product_Variation_Filters():
return Product_Variation_Filters(
get_all_variation_type = True,
get_inactive_variation_type = False,
- get_first_variation_type = False,
+ # get_first_variation_type = False,
ids_variation_type = '',
get_all_variation = True,
get_inactive_variation = False,
- get_first_variation = False,
+ # get_first_variation = False,
ids_variation = ''
)
diff --git a/business_objects/user.py b/business_objects/user.py
index 9b15cbe5..d6b3f457 100644
--- a/business_objects/user.py
+++ b/business_objects/user.py
@@ -186,7 +186,7 @@ class User_Filters():
@staticmethod
def get_default(datastore_store):
- user = datastore_store.get_login_user()
+ user = datastore_store.get_user_session()
return User_Filters(
get_all_user = False,
get_inactive_user = False,
diff --git a/controllers/store/__pycache__/product.cpython-312.pyc b/controllers/store/__pycache__/product.cpython-312.pyc
index 08f1f1c8..26e3517c 100644
Binary files a/controllers/store/__pycache__/product.cpython-312.pyc and b/controllers/store/__pycache__/product.cpython-312.pyc differ
diff --git a/controllers/store/product.py b/controllers/store/product.py
index a75c452b..045b0bd5 100644
--- a/controllers/store/product.py
+++ b/controllers/store/product.py
@@ -158,7 +158,7 @@ def save_product():
objsProduct.append(Product.from_json(product))
# model_save = Model_View_Store_Product() # filters_product=filters_form)
print(f'objsProduct={objsProduct}')
- Model_View_Store_Product.save_products(data.get('comment', 'No comment'), objsProduct)
+ save_errors = Model_View_Store_Product.save_products(data.get('comment', 'No comment'), objsProduct)
model_return = Model_View_Store_Product(form_filters=form_filters)
print('nips')
diff --git a/datastores/__pycache__/datastore_store_base.cpython-312.pyc b/datastores/__pycache__/datastore_store_base.cpython-312.pyc
index a013c471..c1104160 100644
Binary files a/datastores/__pycache__/datastore_store_base.cpython-312.pyc and b/datastores/__pycache__/datastore_store_base.cpython-312.pyc differ
diff --git a/datastores/__pycache__/datastore_store_product_category.cpython-312.pyc b/datastores/__pycache__/datastore_store_product_category.cpython-312.pyc
index 2c962cc4..28cef3c1 100644
Binary files a/datastores/__pycache__/datastore_store_product_category.cpython-312.pyc and b/datastores/__pycache__/datastore_store_product_category.cpython-312.pyc differ
diff --git a/datastores/__pycache__/datastore_store_product_permutation.cpython-312.pyc b/datastores/__pycache__/datastore_store_product_permutation.cpython-312.pyc
index f4c9a94d..1016f588 100644
Binary files a/datastores/__pycache__/datastore_store_product_permutation.cpython-312.pyc and b/datastores/__pycache__/datastore_store_product_permutation.cpython-312.pyc differ
diff --git a/datastores/__pycache__/datastore_store_stock_item.cpython-312.pyc b/datastores/__pycache__/datastore_store_stock_item.cpython-312.pyc
index d1624db0..030ca917 100644
Binary files a/datastores/__pycache__/datastore_store_stock_item.cpython-312.pyc and b/datastores/__pycache__/datastore_store_stock_item.cpython-312.pyc differ
diff --git a/datastores/datastore_store_base.py b/datastores/datastore_store_base.py
index c798aa82..947b68dd 100644
--- a/datastores/datastore_store_base.py
+++ b/datastores/datastore_store_base.py
@@ -20,7 +20,7 @@ from business_objects.store.delivery_option import Delivery_Option
from business_objects.store.delivery_region import Delivery_Region
from business_objects.store.discount import Discount
from business_objects.store.order import Order
-from business_objects.store.product import Product, Product_Permutation, Product_Price, Parameters_Product
+from business_objects.store.product import Product, Product_Permutation, Parameters_Product
from business_objects.sql_error import SQL_Error
from business_objects.store.stock_item import Stock_Item
from business_objects.user import User, User_Filters, User_Permission_Evaluation
@@ -61,8 +61,15 @@ class DataStore_Store_Base(DataStore_Base):
av.val_instance(product_filters, 'product_filters', _m, Parameters_Product)
argument_dict = product_filters.to_json()
user = cls.get_user_session()
+ """
argument_dict['a_id_user'] = user.id_user # 'auth0|6582b95c895d09a70ba10fef' # id_user
argument_dict['a_debug'] = 0
+ """
+ argument_dict = {
+ 'a_id_user': user.id_user
+ , **argument_dict
+ , 'a_debug': 0
+ }
print(f'argument_dict: {argument_dict}')
print('executing p_shop_get_many_product')
result = cls.db_procedure_execute('p_shop_get_many_product', argument_dict)
@@ -71,77 +78,57 @@ class DataStore_Store_Base(DataStore_Base):
category_list = Product_Category_Container()
+ print(f'initial category_list: {category_list}')
+
# Categories
result_set_1 = cursor.fetchall()
print(f'raw categories: {result_set_1}')
- # categories = [Product_Category(row[0], row[1], row[2], row[3]) for row in result_set_1]
- # categories = []
- # category_index = {}
for row in result_set_1:
- new_category = Product_Category.from_DB_get_many_product_catalogue(row) # Product_Category(row[0], row[1], row[2], row[3])
- # category_index[new_category.id_category] = len(categories)
- # categories.append(new_category)
+ new_category = Product_Category.from_DB_get_many_product_catalogue(row)
+ print(f'new_category: {new_category}')
category_list.add_product_category(new_category)
- # print(f'categories: {[c.id_category for c in categories]}')
+
+ print(f'category-loaded category_list: {category_list}')
# Products
cursor.nextset()
result_set_2 = cursor.fetchall()
- # print(f'products: {result_set_2}')
- # products = [] # [Product(**row) for row in result_set_2]
- # product_index = {}
+ print(f'raw products: {result_set_2}')
for row in result_set_2:
- new_product = Product.from_DB_get_many_product_catalogue(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19])
- index_category = category_list.get_index_category_from_id(new_product.id_category)
- category = category_list.categories[index_category]
- category_list.add_product(new_product)
- # products.append(new_product)
- print(f'category_list: {category_list}')
+ print(f'row: {row}')
+ new_product = Product.from_DB_get_many_product_catalogue(row)
+ print(f'new_product: {new_product}')
+ try:
+ category_list.add_product(new_product)
+ except Exception as e:
+ print(f'Error adding product: {e}')
# Permutations
cursor.nextset()
result_set_3 = cursor.fetchall()
- # print(f'Permutations: {result_set_3}')
- permutations = [] # [Product(**row) for row in result_set_2]
- # permutation_index = {}
for row in result_set_3:
- new_permutation = Product_Permutation.from_DB_get_many_product_catalogue(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19])
- index_category = category_list.get_index_category_from_id(new_permutation.id_category)
- category = category_list.categories[index_category]
- category_list.add_product_permutation(new_permutation)
- print(f'category_list: {category_list}')
+ new_permutation = Product_Permutation.from_DB_get_many_product_catalogue(row)
+ try:
+ category_list.add_product_permutation(new_permutation)
+ except Exception as e:
+ print(f'Error adding permutation: {e}')
# Product_Variations
cursor.nextset()
result_set_4 = cursor.fetchall()
- # print(f'variations: {result_set_4}')
- # variations = [Product_Variation(**row) for row in result_set_4]
- variations = []
for row in result_set_4:
new_variation = Product_Variation.from_DB_get_many_product_catalogue(row)
- variations.append(new_variation)
- category_list.add_product_variation(new_variation)
- # print(f'variations: {variations}')
- # print(f'products: {[p.id_product for p in products]}')
+ try:
+ category_list.add_product_variation(new_variation)
+ except Exception as e:
+ print(f'Error adding variation: {e}')
# Images
cursor.nextset()
result_set_5 = cursor.fetchall()
- # print(f'images: {result_set_5}')
- # images = [Image(**row) for row in result_set_5]
- images = []
for row in result_set_5:
- new_image = Image.from_DB_get_many_product_catalogue(row) # (row[0], row[1], row[2], row[3], row[4])
- images.append(new_image)
- # products[product_index[new_image.id_product]].images.append(new_image)
- """
- index_category = category_index[new_image.id_category]
- index_product = categories[index_category].index_product_from_ids_product_permutation(new_image.id_product, new_image.id_permutation)
- categories[index_category].products[index_product].images.append(new_image)
- """
+ new_image = Image.from_DB_get_many_product_catalogue(row)
category_list.add_product_image(new_image)
- # print(f'images: {images}')
- # print(f'products: {[p.id_product for p in products]}')
# Errors
cursor.nextset()
@@ -181,6 +168,7 @@ class DataStore_Store_Base(DataStore_Base):
DataStore_Store_Base.db_cursor_clear(cursor)
cursor.close()
+ print(f'get many category_list: {category_list}')
return category_list, errors # categories, category_index
"""
@@ -283,8 +271,8 @@ class DataStore_Store_Base(DataStore_Base):
argument_dict_list = {
# 'a_guid': guid
'a_id_user': user.id_user
- , 'a_debug': 0
, **variation_filters.to_json()
+ , 'a_debug': 0
}
# argument_dict_list['a_guid'] = guid
result = cls.db_procedure_execute('p_shop_get_many_product_variation', argument_dict_list)
diff --git a/datastores/datastore_store_product.py b/datastores/datastore_store_product.py
index bdf25f78..6fcc8dc5 100644
--- a/datastores/datastore_store_product.py
+++ b/datastores/datastore_store_product.py
@@ -12,20 +12,8 @@ Datastore for Store Products
# internal
import lib.argument_validation as av
-from business_objects.store.basket import Basket, Basket_Item
-from business_objects.store.product_category import Product_Category_Container, Product_Category
-from business_objects.store.currency import Currency
-from business_objects.store.image import Image
-from business_objects.store.delivery_option import Delivery_Option
-from business_objects.store.delivery_region import Delivery_Region
-from business_objects.store.discount import Discount
-from business_objects.store.order import Order
-from business_objects.store.product import Product, Product_Permutation, Product_Price, Parameters_Product
from business_objects.sql_error import SQL_Error
-from business_objects.store.stock_item import Stock_Item
-from business_objects.user import User, User_Filters, User_Permission_Evaluation
-from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_Container
-# from datastores.datastore_base import Table_Shop_Product_Category, Table_Shop_Product_Category_Temp
+from business_objects.store.product import Product, Product_Permutation, Product_Price, Parameters_Product, Product_Temp
from datastores.datastore_store_base import DataStore_Store_Base
from helpers.helper_db_mysql import Helper_DB_MySQL
# from models.model_view_store_checkout import Model_View_Store_Checkout # circular!
@@ -56,6 +44,7 @@ class Table_Shop_Product_Category(db.Model):
created_by: int = db.Column(db.Integer)
id_change_set: int = db.Column(db.Integer)
"""
+"""
class Row_Shop_Product_Temp(db.Model):
__tablename__ = 'Shop_Product_Temp'
__table_args__ = { 'extend_existing': True }
@@ -80,50 +69,70 @@ class Row_Shop_Product_Temp(db.Model):
return row
def to_json(self):
return {
+ 'id_product': self.id_product,
'id_category': self.id_category,
'name': self.name,
+ 'has_variations': self.has_variations,
'id_access_level_required': self.id_access_level_required,
'active': av.input_bool(self.active, self.FLAG_ACTIVE, f'{self.__class__.__name__}.to_json'),
'display_order': self.display_order,
'guid': self.guid,
}
-
+"""
class DataStore_Store_Product(DataStore_Store_Base):
def __init__(self):
super().__init__()
@classmethod
- def save_categories(cls, comment, categories):
- _m = 'DataStore_Store_Product_Category.save_categories'
+ def save_products(cls, comment, products):
+ _m = 'DataStore_Store_Product.save_products'
print(f'{_m}\nstarting...')
- print(f'comment: {comment}\ncategories: {categories}')
- # av.val_str(comment, 'comment', _m)
- # av.val_list_instances(categories, 'categories', _m, Product_Category, 1)
+ print(f'comment: {comment}\nproducts: {products}')
guid = Helper_DB_MySQL.create_guid()
user = cls.get_user_session()
rows = []
- id_category_new = 0
- for category in categories:
- row = Row_Shop_Product_Temp.from_product(category)
- if row.id_category == '':
- id_category_new -= 1
- row.id_category = id_category_new
+ id_product_new = 0
+ for product in products:
+ row = Product_Temp.from_product(product)
+ if row.id_product == '':
+ id_product_new -= 1
+ row.id_product = id_product_new
else:
- print(f'row.id_category: {row.id_category}')
+ print(f'row.id_product: {row.id_product}')
row.guid = guid
rows.append(row)
print(f'rows: {rows}')
-
- DataStore_Store_Base.upload_bulk(rows, Row_Shop_Product_Temp, 1000)
+ DataStore_Store_Base.upload_bulk(Product_Temp.__tablename__, rows, 1000)
argument_dict_list = {
- 'a_id_user': user.id_user,
- 'a_guid': guid,
'a_comment': comment,
+ 'a_guid': guid,
+ 'a_id_user': user.id_user,
+ 'a_debug': 0,
}
save_result = cls.db_procedure_execute('p_shop_save_product', argument_dict_list)
+
+ cursor = save_result # .cursor
+ print('data received')
+
+ # Errors
+ # cursor.nextset()
+ result_set_e = cursor.fetchall()
+ print(f'raw errors: {result_set_e}')
+ errors = []
+ if len(result_set_e) > 0:
+ errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1])
+ for error in errors:
+ print(f"Error [{error.code}]: {error.msg}")
+ try:
+ DataStore_Store_Base.db_cursor_clear(cursor)
+ except Exception as e:
+ print(f'Error clearing cursor: {e}')
+ cursor.close()
+
save_result.close()
print('save procedure executed')
+ return errors
diff --git a/datastores/datastore_store_product_category.py b/datastores/datastore_store_product_category.py
index 3a2d103f..553615f7 100644
--- a/datastores/datastore_store_product_category.py
+++ b/datastores/datastore_store_product_category.py
@@ -89,9 +89,9 @@ class DataStore_Store_Product_Category(DataStore_Store_Base):
DataStore_Store_Base.upload_bulk(Product_Category_Temp.__tablename__, rows, 1000)
argument_dict_list = {
- 'a_id_user': user.id_user,
- 'a_guid': guid,
'a_comment': comment,
+ 'a_guid': guid,
+ 'a_id_user': user.id_user,
}
save_result = cls.db_procedure_execute('p_shop_save_product_category', argument_dict_list)
save_result.close()
diff --git a/datastores/datastore_store_product_permutation.py b/datastores/datastore_store_product_permutation.py
index 15121ae8..23ac372a 100644
--- a/datastores/datastore_store_product_permutation.py
+++ b/datastores/datastore_store_product_permutation.py
@@ -95,9 +95,9 @@ class DataStore_Store_Product_Permutation(DataStore_Store_Base):
print('bulk uploaded')
argument_dict_list = {
- 'a_id_user': user.id_user,
'a_comment': comment,
- 'a_guid': guid
+ 'a_guid': guid,
+ 'a_id_user': user.id_user,
}
cls.db_procedure_execute('p_shop_save_product_permutation', argument_dict_list)
print('saved product permutations')
diff --git a/datastores/datastore_store_product_variation.py b/datastores/datastore_store_product_variation.py
index c7163801..e44263a0 100644
--- a/datastores/datastore_store_product_variation.py
+++ b/datastores/datastore_store_product_variation.py
@@ -27,7 +27,7 @@ from business_objects.store.stock_item import Stock_Item
from business_objects.user import User, User_Filters, User_Permission_Evaluation
from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_Container
from datastores.datastore_store_base import DataStore_Store_Base
-# from helpers.helper_db_mysql import Helper_DB_MySQL
+from helpers.helper_db_mysql import Helper_DB_MySQL
# from models.model_view_store_checkout import Model_View_Store_Checkout # circular!
from extensions import db
# external
@@ -41,59 +41,9 @@ from pydantic import BaseModel, ConfigDict
from typing import ClassVar
from datetime import datetime
-# db = SQLAlchemy()
class DataStore_Store_Product_Variation(DataStore_Store_Base):
- # Global constants
- # Attributes
def __init__(self, **kwargs):
- super().__init__(**kwargs)
-
- def get_many_product_variation(self, variation_filters):
- _m = 'DataStore_Store_Product_Variation.get_many_product_variation'
- print(_m)
- av.val_instance(variation_filters, 'variation_filters', _m, Product_Variation_Filters)
-
- guid = Helper_DB_MySQL.create_guid()
- # now = datetime.now()
- # user = self.get_user_session()
-
- """
- argument_dict_list = {
- 'a_id_user': id_user,
- 'a_comment': comment,
- 'a_guid': guid
- }
- """
- user = self.get_user_session()
- argument_dict_list = {
- # 'a_guid': guid
- 'a_id_user': user.id_user
- , **variation_filters.to_json()
- }
- # argument_dict_list['a_guid'] = guid
- result = self.db_procedure_execute('p_shop_get_many_product_variation', argument_dict_list)
-
- cursor = result.cursor
- result_set = cursor.fetchall()
-
- # Product_Variations
- variations = Product_Variation_Container()
- for row in result_set:
- new_variation = Product_Variation.from_DB_variation(row)
- variations.add_product_variation(new_variation)
-
- errors = []
- cursor.nextset()
- result_set_e = cursor.fetchall()
- print(f'raw errors: {result_set_e}')
- if len(result_set_e) > 0:
- errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_e]
- for error in errors:
- print(f"Error [{error.code}]: {error.msg}")
-
- DataStore_Store_Product_Variation.db_cursor_clear(cursor)
-
- return variations, errors
\ No newline at end of file
+ super().__init__(**kwargs)
\ No newline at end of file
diff --git a/datastores/datastore_store_stock_item.py b/datastores/datastore_store_stock_item.py
index 28d70b4e..806dab05 100644
--- a/datastores/datastore_store_stock_item.py
+++ b/datastores/datastore_store_stock_item.py
@@ -58,8 +58,15 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
av.val_instance(Parameters_Stock_Item, 'Parameters_Stock_Item', _m, Parameters_Stock_Item)
argument_dict = Parameters_Stock_Item.to_json()
user = self.get_user_session()
- argument_dict['a_id_user'] = user.id_user # 1 # 'auth0|6582b95c895d09a70ba10fef' # id_user
+ """
+ argument_dict['a_id_user'] = user.id_user # 'auth0|6582b95c895d09a70ba10fef' # id_user
argument_dict['a_debug'] = 0
+ """
+ argument_dict = {
+ 'a_id_user': user.id_user
+ , **argument_dict
+ , 'a_debug': 0
+ }
print(f'argument_dict: {argument_dict}')
print('executing p_shop_get_many_stock_item')
result = self.db_procedure_execute('p_shop_get_many_stock_item', argument_dict)
diff --git a/forms/__pycache__/base.cpython-312.pyc b/forms/__pycache__/base.cpython-312.pyc
index e5a06a3b..5ba31834 100644
Binary files a/forms/__pycache__/base.cpython-312.pyc and b/forms/__pycache__/base.cpython-312.pyc differ
diff --git a/forms/__pycache__/unit_measurement.cpython-312.pyc b/forms/__pycache__/unit_measurement.cpython-312.pyc
index 0907c0d3..a68ac77a 100644
Binary files a/forms/__pycache__/unit_measurement.cpython-312.pyc and b/forms/__pycache__/unit_measurement.cpython-312.pyc differ
diff --git a/forms/base.py b/forms/base.py
index 81d99bb7..32f8829d 100644
--- a/forms/base.py
+++ b/forms/base.py
@@ -40,9 +40,8 @@ class Form_Base(FlaskForm, metaclass=Form_Base_Meta):
def from_json(cls, json):
pass
@classmethod
- @abstractmethod
def get_default(cls):
- pass
+ return cls()
"""
@abstractmethod
def test_69(self):
@@ -55,6 +54,12 @@ class Form_Base(FlaskForm, metaclass=Form_Base_Meta):
form_filters.active.data = av.input_bool(data_form['active'], 'active', 'filter_category')
return form_filters
"""
+ @classmethod
+ def get_choices_blank(cls):
+ return [('', 'Select')]
+ @classmethod
+ def get_choice_all(cls):
+ return ('', 'All')
'''
class Filters_Stored_Procedure_Base(Form_Base):
diff --git a/forms/store/__pycache__/product.cpython-312.pyc b/forms/store/__pycache__/product.cpython-312.pyc
index 61da09cb..7d88d192 100644
Binary files a/forms/store/__pycache__/product.cpython-312.pyc and b/forms/store/__pycache__/product.cpython-312.pyc differ
diff --git a/forms/store/__pycache__/product_permutation.cpython-312.pyc b/forms/store/__pycache__/product_permutation.cpython-312.pyc
index 7fc3d82e..3bfc0602 100644
Binary files a/forms/store/__pycache__/product_permutation.cpython-312.pyc and b/forms/store/__pycache__/product_permutation.cpython-312.pyc differ
diff --git a/forms/store/product.py b/forms/store/product.py
index 5dabdeb5..7eb3df1d 100644
--- a/forms/store/product.py
+++ b/forms/store/product.py
@@ -22,7 +22,7 @@ from flask_wtf.recaptcha import RecaptchaField
class Filters_Product(FlaskForm):
- id_category = SelectField('Category', validators=[Optional()], choices=[])
+ id_category = SelectField('Category', validators=[Optional()], choices=[('', 'All')])
is_not_empty = BooleanField('Not empty only?')
active = BooleanField("Active only?")
@classmethod
@@ -33,4 +33,11 @@ class Filters_Product(FlaskForm):
form.active.data = filters_product.active
return form
def __repr__(self):
- return f'Filters_Product(id_category={self.id_category}, is_not_empty={self.is_not_empty.data}, active={self.active.data})'
\ No newline at end of file
+ return f'Filters_Product(id_category={self.id_category}, is_not_empty={self.is_not_empty.data}, active={self.active.data})'
+ @classmethod
+ def from_json(cls, json):
+ filters = cls()
+ filters.id_category.data = json['id_category']
+ filters.is_not_empty.data = json['is_not_empty']
+ filters.active.data = json['active']
+ return filters
\ No newline at end of file
diff --git a/forms/store/product_permutation.py b/forms/store/product_permutation.py
index 7433232d..c859782b 100644
--- a/forms/store/product_permutation.py
+++ b/forms/store/product_permutation.py
@@ -26,8 +26,8 @@ from abc import ABCMeta, abstractmethod
class Filters_Product_Permutation(Form_Base):
- id_category = SelectField('Category', validators=[Optional()], choices=[])
- id_product = SelectField('Product', validators=[Optional()], choices=[])
+ id_category = SelectField('Category', validators=[Optional()], choices=[('', 'All')])
+ id_product = SelectField('Product', validators=[Optional()], choices=[('', 'All')])
is_out_of_stock = BooleanField('Out of stock only?')
quantity_min = FloatField('Min stock')
quantity_max = FloatField('Max stock')
diff --git a/forms/store/stock_item.py b/forms/store/stock_item.py
index fd695910..a1eab1d8 100644
--- a/forms/store/stock_item.py
+++ b/forms/store/stock_item.py
@@ -64,4 +64,5 @@ class Filters_Stock_Item(Form_Base):
@classmethod
def get_default(cls):
filters = cls()
- filters.id_category.choices = [('', 'Select category')]
\ No newline at end of file
+ filters.id_category.choices = cls.get_choices_blank()
+ filters.id_product.choices = cls.get_choices_blank()
\ No newline at end of file
diff --git a/models/__pycache__/model_view_base.cpython-312.pyc b/models/__pycache__/model_view_base.cpython-312.pyc
index 8dd81654..856adc48 100644
Binary files a/models/__pycache__/model_view_base.cpython-312.pyc and b/models/__pycache__/model_view_base.cpython-312.pyc differ
diff --git a/models/__pycache__/model_view_store.cpython-312.pyc b/models/__pycache__/model_view_store.cpython-312.pyc
index eb267538..9b2631b7 100644
Binary files a/models/__pycache__/model_view_store.cpython-312.pyc and b/models/__pycache__/model_view_store.cpython-312.pyc differ
diff --git a/models/__pycache__/model_view_store_product.cpython-312.pyc b/models/__pycache__/model_view_store_product.cpython-312.pyc
index 70dd8b93..d9585874 100644
Binary files a/models/__pycache__/model_view_store_product.cpython-312.pyc and b/models/__pycache__/model_view_store_product.cpython-312.pyc differ
diff --git a/models/model_view_base.py b/models/model_view_base.py
index 5c77cefc..fb025248 100644
--- a/models/model_view_base.py
+++ b/models/model_view_base.py
@@ -204,6 +204,7 @@ class Model_View_Base(BaseModel, ABC):
session: None = None
is_page_store: bool = None
is_user_logged_in: bool = None
+ user: User = None
access_levels: list = None
model_config = ConfigDict(arbitrary_types_allowed=True)
@@ -253,6 +254,7 @@ class Model_View_Base(BaseModel, ABC):
datastore_user = DataStore_User()
user = datastore_user.get_user_session()
+ self.user = user
self.is_user_logged_in = user.is_logged_in
def output_bool(self, boolean):
@@ -318,13 +320,13 @@ class Model_View_Base(BaseModel, ABC):
return {getattr(obj, key): obj.to_json() for obj in list_objects}
@staticmethod
def convert_list_objects_to_dict_by_attribute_key_default(list_objects):
- if len(list_objects) == 0:
+ if list_objects is None or len(list_objects) == 0:
return {}
obj_class = list_objects[0].__class__
return Model_View_Base.convert_list_objects_to_dict_by_attribute_key(list_objects, getattr(obj_class, obj_class.FLAG_NAME_ATTR_OPTION_VALUE))
@staticmethod
def convert_list_objects_to_dict_json_by_attribute_key_default(list_objects):
- if len(list_objects) == 0:
+ if list_objects is None or len(list_objects) == 0:
return {}
obj_class = list_objects[0].__class__
return Model_View_Base.convert_list_objects_to_dict_json_by_attribute_key(list_objects, getattr(obj_class, obj_class.FLAG_NAME_ATTR_OPTION_VALUE))
diff --git a/models/model_view_store.py b/models/model_view_store.py
index e8537881..a0a102e3 100644
--- a/models/model_view_store.py
+++ b/models/model_view_store.py
@@ -104,9 +104,9 @@ class Model_View_Store(Model_View_Base):
HASH_STORE_BASKET_LOAD : ClassVar[str] = '/store/basket_load'
HASH_GET_STORE_PRODUCT: ClassVar[str] = '/store/product_get'
HASH_GET_STORE_PRODUCT_CATEGORY: ClassVar[str] = '/store/category_get'
- HASH_SAVE_STORE_PRODUCT: ClassVar[str] = '/store/save_product'
HASH_GET_STORE_PRODUCT_PERMUTATION: ClassVar[str] = '/store/permutation_get'
HASH_GET_STORE_STOCK_ITEM: ClassVar[str] = '/store/stock_item_get'
+ HASH_SAVE_STORE_PRODUCT: ClassVar[str] = '/store/save_product'
HASH_SAVE_STORE_PRODUCT_CATEGORY: ClassVar[str] = '/store/save_category'
HASH_SAVE_STORE_PRODUCT_PERMUTATION: ClassVar[str] = '/store/save_permutation'
HASH_SAVE_STORE_STOCK_ITEM: ClassVar[str] = '/store/save_stock_item'
diff --git a/models/model_view_store_product.py b/models/model_view_store_product.py
index d6b2e9c5..3528adcb 100644
--- a/models/model_view_store_product.py
+++ b/models/model_view_store_product.py
@@ -19,6 +19,7 @@ Data model for store product view
from business_objects.store.product import Product, Parameters_Product
from business_objects.store.product_category import Product_Category_Container
from datastores.datastore_store_product import DataStore_Store_Product
+from forms.access_level import Filters_Access_Level
from forms.store.product import Filters_Product
from models.model_view_store import Model_View_Store
# from routes import bp_home
@@ -86,12 +87,17 @@ class Model_View_Store_Product(Model_View_Store):
return 'Products'
def __init__(self, form_filters, hash_page_current=Model_View_Store.HASH_PAGE_STORE_PRODUCTS):
- _m = 'Model_View_Store_Permutation.__init__'
+ _m = 'Model_View_Store_Product.__init__'
print(f'{_m}\nstarting...')
super().__init__(hash_page_current=hash_page_current, form_filters=form_filters)
+ self.access_levels = self.get_many_access_level(Filters_Access_Level())
parameters_product = Parameters_Product.from_form_filters_product(self.form_filters)
datastore_store = DataStore_Store_Product()
- self.category_list, errors = datastore_store.get_many_product(parameters_product)
+ self.category_list, errors = datastore_store.get_many_product(parameters_product)
+ countProducts = 0
+ for category in self.category_list.categories:
+ countProducts += len(category.products)
+ print(f'category count: {len(self.category_list.categories)}\nproduct count: {countProducts}')
self.category_list_filters, errors_filters = datastore_store.get_many_product(
Parameters_Product(
get_all_product_category = True,
@@ -110,7 +116,7 @@ class Model_View_Store_Product(Model_View_Store):
)
)
print(f'category filters: {self.category_list_filters.categories}')
- self.form_filters.id_category.choices = [('0', 'All')] + [(str(category.id_category), category.name) for category in self.category_list_filters.categories]
+ self.form_filters.id_category.choices += [(str(category.id_category), category.name) for category in self.category_list_filters.categories]
print(f'category options: {self.form_filters.id_category.choices}')
self.variation_types, self.variations, errors = self.get_many_product_variation()
self.units_measurement = self.get_many_unit_measurement()
@@ -118,7 +124,8 @@ class Model_View_Store_Product(Model_View_Store):
self.currencies = self.get_many_currency()
self.currency_options = [currency.to_json_option() for currency in self.currencies]
+ print(f'category count: {len(self.category_list.categories)}\nproduct count: {countProducts}')
@staticmethod
def save_products(comment, list_products):
_m = 'Model_View_Store_Product.save_products'
- DataStore_Store_Product.save_products(comment, list_products)
\ No newline at end of file
+ return DataStore_Store_Product.save_products(comment, list_products)
\ No newline at end of file
diff --git a/static/MySQL/0000_combine.sql b/static/MySQL/0000_combine.sql
index 9fab3fc2..b25480b3 100644
--- a/static/MySQL/0000_combine.sql
+++ b/static/MySQL/0000_combine.sql
@@ -7411,7 +7411,7 @@ BEGIN
, t_C.can_admin = UE_T.can_admin
;
- CALL p_shop_calc_user_clear_temp(a_guid);
+ CALL p_shop_clear_calc_user(a_guid);
END IF;
END IF;
@@ -7727,7 +7727,7 @@ BEGIN
, t_P.can_admin = UE_T.can_admin
;
- CALL p_shop_calc_user_clear_temp(a_guid);
+ CALL p_shop_clear_calc_user(a_guid);
END IF;
END IF;
@@ -11495,7 +11495,7 @@ BEGIN
)
;
- # CALL p_shop_calc_user_clear_temp(v_guid);
+ # CALL p_shop_clear_calc_user(v_guid);
# DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM partsltd_prod.Shop_Calc_User_Temp
WHERE GUID = v_guid
@@ -14368,7 +14368,7 @@ BEGIN
;
END IF;
- -- CALL p_shop_calc_user_clear_temp(v_guid_permission);
+ -- CALL p_shop_clear_calc_user(v_guid_permission);
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = a_guid;
@@ -15903,7 +15903,7 @@ BEGIN
t_P.can_admin = UE_T.can_admin
;
- # CALL p_shop_calc_user_clear_temp(v_guid);
+ # CALL p_shop_clear_calc_user(v_guid);
# DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
@@ -17186,7 +17186,7 @@ BEGIN
t_P.can_admin = UE_T.can_admin
;
- # CALL p_shop_calc_user_clear_temp(v_guid);
+ # CALL p_shop_clear_calc_user(v_guid);
# DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
@@ -17496,7 +17496,7 @@ BEGIN
;
END IF;
- -- CALL p_shop_calc_user_clear_temp(v_guid_permission);
+ -- CALL p_shop_clear_calc_user(v_guid_permission);
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = a_guid;
@@ -19071,7 +19071,7 @@ BEGIN
t_P.can_admin = UE_T.can_admin
;
- # CALL p_shop_calc_user_clear_temp(v_guid);
+ # CALL p_shop_clear_calc_user(v_guid);
# DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
diff --git a/static/MySQL/7200_p_shop_save_product_category.sql b/static/MySQL/7200_p_shop_save_product_category.sql
index 989c8b16..6e4d5d39 100644
--- a/static/MySQL/7200_p_shop_save_product_category.sql
+++ b/static/MySQL/7200_p_shop_save_product_category.sql
@@ -8,9 +8,9 @@ DROP PROCEDURE IF EXISTS p_shop_save_product_category;
DELIMITER //
CREATE PROCEDURE p_shop_save_product_category (
- IN a_id_user INT,
+ IN a_comment VARCHAR(500),
IN a_guid BINARY(36),
- IN a_comment VARCHAR(500)
+ IN a_id_user INT
)
BEGIN
DECLARE v_code_type_error_bad_data VARCHAR(100);
@@ -206,59 +206,59 @@ BEGIN
IF NOT EXISTS (SELECT * FROM tmp_Msg_Error LIMIT 1) THEN
START TRANSACTION;
-
- IF NOT ISNULL(v_ids_product_permission) THEN
- INSERT INTO Shop_Product_Change_Set ( comment )
- VALUES ( a_comment )
- ;
- SET v_id_change_set := LAST_INSERT_ID();
+ IF NOT ISNULL(v_ids_product_permission) THEN
+ INSERT INTO Shop_Product_Change_Set ( comment )
+ VALUES ( a_comment )
+ ;
+
+ SET v_id_change_set := LAST_INSERT_ID();
+
+ UPDATE Shop_Product_Category PC
+ INNER JOIN tmp_Category t_C ON PC.id_category = t_C.id_category
+ SET
+ PC.id_category = t_C.id_category
+ , PC.code = t_C.code
+ , PC.name = t_C.name
+ , PC.description = t_C.description
+ , PC.id_access_level_required = t_C.id_access_level_required
+ , PC.active = t_C.active
+ , PC.display_order = t_C.display_order
+ , PC.id_change_set = v_id_change_set
+ ;
+ END IF;
- UPDATE Shop_Product_Category PC
- INNER JOIN tmp_Category t_C ON PC.id_category = t_C.id_category
- SET
- PC.id_category = t_C.id_category
- , PC.code = t_C.code
- , PC.name = t_C.name
- , PC.description = t_C.description
- , PC.id_access_level_required = t_C.id_access_level_required
- , PC.active = t_C.active
- , PC.display_order = t_C.display_order
- , PC.id_change_set = v_id_change_set
+ INSERT INTO Shop_Product_Category (
+ code
+ , name
+ , description
+ , id_access_level_required
+ , active
+ , display_order
+ , created_by
+ , created_on
+ )
+ SELECT
+ -- t_C.id_category AS id_category
+ t_C.code AS code
+ , t_C.name AS name
+ , t_C.description AS description
+ , t_C.id_access_level_required AS id_access_level_required
+ , t_C.active AS active
+ , t_C.display_order AS display_order
+ , a_id_user AS created_by
+ , v_now AS created_on
+ FROM tmp_Category t_C
+ WHERE is_new = 1
+ AND active = 1
;
- END IF;
-
- INSERT INTO Shop_Product_Category (
- code
- , name
- , description
- , id_access_level_required
- , active
- , display_order
- , created_by
- , created_on
- )
- SELECT
- -- t_C.id_category AS id_category
- t_C.code AS code
- , t_C.name AS name
- , t_C.description AS description
- , t_C.id_access_level_required AS id_access_level_required
- , t_C.active AS active
- , t_C.display_order AS display_order
- , a_id_user AS created_by
- , v_now AS created_on
- FROM tmp_Category t_C
- WHERE is_new = 1
- AND active = 1
- ;
+ DELETE FROM Shop_Product_Category_Temp
+ WHERE GUID = a_guid;
+
COMMIT;
END IF;
- DELETE FROM Shop_Product_Category_Temp
- WHERE GUID = a_guid;
-
SELECT * FROM tmp_Msg_Error;
DROP TEMPORARY TABLE IF EXISTS tmp_Catgory;
diff --git a/static/MySQL/7200_p_shop_save_product_category_test.sql b/static/MySQL/7200_p_shop_save_product_category_test.sql
index a1a07f07..ba88e966 100644
--- a/static/MySQL/7200_p_shop_save_product_category_test.sql
+++ b/static/MySQL/7200_p_shop_save_product_category_test.sql
@@ -192,7 +192,7 @@ BEGIN
, t_C.can_admin = UE_T.can_admin
;
- CALL p_shop_calc_user_clear_temp(a_guid);
+ CALL p_shop_clear_calc_user(a_guid);
END IF;
END IF;
diff --git a/static/MySQL/7203_p_shop_save_product.sql b/static/MySQL/7203_p_shop_save_product.sql
index 7d328ef1..ee5a2a0a 100644
--- a/static/MySQL/7203_p_shop_save_product.sql
+++ b/static/MySQL/7203_p_shop_save_product.sql
@@ -9,16 +9,19 @@ DROP PROCEDURE IF EXISTS p_shop_save_product;
DELIMITER //
CREATE PROCEDURE p_shop_save_product (
+ IN a_comment VARCHAR(500),
IN a_guid BINARY(36),
- IN a_id_user INT,
- IN a_comment VARCHAR(500)
+ IN a_id_user INT,
+ IN a_debug BIT
)
BEGIN
DECLARE v_code_type_error_bad_data VARCHAR(100);
+ DECLARE v_id_access_level_edit INT;
DECLARE v_id_type_error_bad_data INT;
DECLARE v_id_permission_product INT;
DECLARE v_ids_product_permission LONGTEXT;
DECLARE v_id_change_set INT;
+ DECLARE v_time_start TIMESTAMP(6);
DECLARE exit handler for SQLEXCEPTION
BEGIN
@@ -35,24 +38,44 @@ BEGIN
-- Select the error information
-- SELECT 'Error' AS status, @errno AS error_code, @sqlstate AS sql_state, @text AS message;
INSERT INTO tmp_Msg_Error (
- guid
- , id_type
+ -- guid
+ id_type
, code
, msg
)
SELECT
- a_guid
- , NULL
+ -- a_guid
+ (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'MYSQL_ERROR' LIMIT 1)
, @errno
- , @text
+ , IFNULL(@text, 'NULL')
;
+
+ SELECT *
+ FROM tmp_Msg_Error t_ME
+ INNER JOIN partsltd_prod.Shop_Msg_Error_Type MET ON t_ME.id_type = MET.id_type
+ ;
+
+ DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error;
+ DROP TEMPORARY TABLE IF EXISTS tmp_Product;
END;
- SET v_code_type_error_bad_data := 'BAD_DATA';
+ SET v_time_start := CURRENT_TIMESTAMP(6);
+ SET v_code_type_error_bad_data := (SELECT code FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1);
SET v_id_type_error_bad_data := (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = v_code_type_error_bad_data LIMIT 1);
+ SET v_id_access_level_edit := (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'EDIT' LIMIT 1);
SET a_guid := IFNULL(a_guid, UUID());
+ SET a_debug := IFNULL(a_debug, 0);
+ IF a_debug = 1 THEN
+ SELECT
+ v_code_type_error_bad_data
+ , v_id_type_error_bad_data
+ ;
+ END IF;
+
+ DROP TEMPORARY TABLE IF EXISTS tmp_Product;
+ DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error;
CREATE TEMPORARY TABLE tmp_Product (
id_category INT NOT NULL
@@ -71,7 +94,7 @@ BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error (
display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT
- , guid BINARY(36) NOT NULL
+ -- , guid BINARY(36) NOT NULL
, id_type INT NOT NULL
/*
CONSTRAINT FK_tmp_Msg_Error_id_type
@@ -98,79 +121,115 @@ BEGIN
SELECT
IFNULL(P_T.id_category, P.id_category) AS id_category
, IFNULL(P_T.id_product, 0) AS id_product
- , IFNULL(PT.name, P.name) AS name
- , IFNULL(PT.has_variations, P.has_variations) AS has_variations
- , IFNULL(PT.id_access_level_required, P.id_access_level_required) AS id_access_level_required
+ , IFNULL(P_T.name, P.name) AS name
+ , IFNULL(P_T.has_variations, P.has_variations) AS has_variations
+ , IFNULL(P_T.id_access_level_required, P.id_access_level_required) AS id_access_level_required
, IFNULL(P_T.active, P.active) AS active
, IFNULL(P_T.display_order, P.display_order) AS display_order
- , IFNULL(PT.name, IFNULL(P.name, IFNULL(P_T.id_product, '(No Product)'))) AS name_error
+ , IFNULL(P_T.name, IFNULL(P.name, IFNULL(P_T.id_product, '(No Product)'))) AS name_error
, CASE WHEN IFNULL(P_T.id_product, 0) < 1 THEN 1 ELSE 0 END AS is_new
- FROM Shop_Product_Tenp P_T
- LEFT JOIN Shop_Product P ON P_T.id_product = P.id_product
+ FROM partsltd_prod.Shop_Product_Temp P_T
+ LEFT JOIN partsltd_prod.Shop_Product P ON P_T.id_product = P.id_product
;
-- Validation
- -- Missing mandatory fields
- INSERT INTO tmp_Msg_Error (
- guid
- , id_type
- , code
- , msg
- )
+ -- Missing mandatory fields
-- id_category
- SELECT
- a_guid AS GUID
- , v_id_type_error_bad_data
- , v_code_error_bad_data
- , CONCAT('The following product(s) do not have a category: ', GROUP_CONCAT(t_P.name_error SEPARATOR ', '))
- FROM tmp_Product t_P
- WHERE ISNULL(t_P.id_category)
- UNION
+ IF EXISTS (SELECT * FROM tmp_Product t_P WHERE ISNULL(t_P.id_category) LIMIT 1) THEN
+ INSERT INTO tmp_Msg_Error (
+ id_type
+ , code
+ , msg
+ )
+ SELECT
+ v_id_type_error_bad_data
+ , v_code_type_error_bad_data
+ , IFNULL(CONCAT('The following product(s) do not have a category: ', GROUP_CONCAT(IFNULL(t_P.name_error, 'NULL') SEPARATOR ', ')), 'NULL')
+ FROM tmp_Product t_P
+ WHERE ISNULL(t_P.id_category)
+ ;
+ END IF;
+
-- name
- SELECT
- a_guid AS GUID
- , v_id_type_error_bad_data
- , v_code_error_bad_data
- , CONCAT('The following product(s) do not have a name: ', GROUP_CONCAT(t_P.name_error SEPARATOR ', '))
- FROM tmp_Product t_P
- WHERE ISNULL(t_P.name)
- UNION
+ IF EXISTS (SELECT * FROM tmp_Product t_P WHERE ISNULL(t_P.name) LIMIT 1) THEN
+ INSERT INTO tmp_Msg_Error (
+ id_type
+ , code
+ , msg
+ )
+ SELECT
+ v_id_type_error_bad_data
+ , v_code_type_error_bad_data
+ , IFNULL(CONCAT('The following product(s) do not have a name: ', GROUP_CONCAT(IFNULL(t_P.name_error, 'NULL') SEPARATOR ', ')), 'NULL')
+ FROM tmp_Product t_P
+ WHERE ISNULL(t_P.name)
+ ;
+ END IF;
+
-- has_variations
- SELECT
- a_guid AS GUID
- , v_id_type_error_bad_data
- , v_code_error_bad_data
- , CONCAT('The following product(s) do not have a has-variations setting: ', GROUP_CONCAT(t_P.name_error SEPARATOR ', '))
- FROM tmp_Product t_P
- WHERE ISNULL(t_P.has_variations)
- UNION
+ IF EXISTS (SELECT * FROM tmp_Product t_P WHERE ISNULL(t_P.has_variations) LIMIT 1) THEN
+ INSERT INTO tmp_Msg_Error (
+ id_type
+ , code
+ , msg
+ )
+ SELECT
+ v_id_type_error_bad_data
+ , v_code_type_error_bad_data
+ , IFNULL(CONCAT('The following product(s) do not have a has-variations setting: ', GROUP_CONCAT(IFNULL(t_P.name_error, 'NULL') SEPARATOR ', ')), 'NULL')
+ FROM tmp_Product t_P
+ WHERE ISNULL(t_P.has_variations)
+ ;
+ END IF;
+
-- id_access_level_required
- SELECT
- a_guid AS GUID
- , v_id_type_error_bad_data
- , v_code_error_bad_data
- , CONCAT('The following product(s) do not have a required access level ID: ', GROUP_CONCAT(t_P.name_error SEPARATOR ', '))
- FROM tmp_Product t_P
- WHERE ISNULL(t_P.id_access_level_required)
- UNION
+ IF EXISTS (SELECT * FROM tmp_Product t_P WHERE ISNULL(t_P.id_access_level_required) LIMIT 1) THEN
+ INSERT INTO tmp_Msg_Error (
+ id_type
+ , code
+ , msg
+ )
+ SELECT
+ v_id_type_error_bad_data
+ , v_code_type_error_bad_data
+ , IFNULL(CONCAT('The following product(s) do not have a required access level ID: ', GROUP_CONCAT(IFNULL(t_P.name_error, 'NULL') SEPARATOR ', ')), 'NULL')
+ FROM tmp_Product t_P
+ WHERE ISNULL(t_P.id_access_level_required)
+ ;
+ END IF;
+
-- display_order
- SELECT
- a_guid AS GUID
- , v_id_type_error_bad_data
- , v_code_error_bad_data
- , CONCAT('The following product(s) do not have a display order: ', GROUP_CONCAT(t_P.name_error SEPARATOR ', '))
- FROM tmp_Product t_P
- WHERE ISNULL(t_P.display_order)
- ;
+ IF EXISTS (SELECT * FROM tmp_Product t_P WHERE ISNULL(t_P.display_order) LIMIT 1) THEN
+ INSERT INTO tmp_Msg_Error (
+ id_type
+ , code
+ , msg
+ )
+ SELECT
+ v_id_type_error_bad_data
+ , v_code_type_error_bad_data
+ , IFNULL(CONCAT('The following product(s) do not have a display order: ', GROUP_CONCAT(IFNULL(t_P.name_error, 'NULL') SEPARATOR ', ')), 'NULL')
+ FROM tmp_Product t_P
+ WHERE ISNULL(t_P.display_order)
+ ;
+ END IF;
-- Permissions
IF NOT EXISTS (SELECT * FROM tmp_Msg_Error LIMIT 1) THEN -- (SELECT * FROM tmp_Product WHERE is_new = 0 LIMIT 1) THEN
- SET v_ids_product_permission := (SELECT GROUP_CONCAT(item SEPARATOR ',') FROM tmp_Shop_Product WHERE is_new = 0);
+ SET v_ids_product_permission := (SELECT GROUP_CONCAT(id_product SEPARATOR ',') FROM tmp_Product WHERE is_new = 0);
IF NOT ISNULL(v_ids_product_permission) THEN
SET v_id_permission_product = (SELECT id_permission FROM Shop_Permission WHERE code = 'STORE_PRODUCT' LIMIT 1);
- CALL p_shop_calc_user(a_guid, a_id_user, v_id_permission_product, v_ids_product_permission);
+ CALL partsltd_prod.p_shop_calc_user(
+ a_guid
+ , a_id_user
+ , FALSE -- get_inactive_users
+ , v_id_permission_product
+ , v_id_access_level_edit
+ , v_ids_product_permission
+ , 0 -- debug
+ );
UPDATE tmp_Product t_P
INNER JOIN Shop_Calc_User_Temp UE_T
@@ -182,64 +241,72 @@ BEGIN
, t_P.can_admin = UE_T.can_admin
;
- CALL p_shop_calc_user_clear_temp(a_guid);
+ CALL partsltd_prod.p_shop_clear_calc_user(
+ a_guid
+ , 0 -- debug
+ );
END IF;
END IF;
IF NOT EXISTS (SELECT * FROM tmp_Msg_Error LIMIT 1) THEN
- -- Start the transaction
START TRANSACTION;
-
- -- Your transaction logic goes here
- IF NOT ISNULL(v_ids_product_permission) THEN
- INSERT INTO Shop_Product_Change_Set ( comment )
- VALUES ( a_comment )
- ;
-
- SET v_id_change_set := LAST_INSERT_ID();
-
- UPDATE Shop_Product P
- INNER JOIN tmp_Product t_P ON P.id_product = t_P.id_product
- SET
- P.id_category = t_P.id_category
- , P.name = t_P.name
- , P.has_variations = t_P.has_variations
- , P.id_access_level_required = t_P.id_access_level_required
- , P.display_order = t_P.display_order
- , P.id_change_set = v_id_change_set
- ;
- END IF;
-
- INSERT INTO Shop_Product (
- id_category
- , name
- , has_variations
- , id_access_level_required
- , display_order
- , created_by
- , created_on
- )
- SELECT
- t_P.id_category AS id_category
- , t_P.name AS name
- , t_P.has_variations AS has_variations
- , t_P.id_access_level_required AS id_access_level_required
- , t_P.display_order AS display_order
- , a_id_user AS created_by
- , v_now AS created_on
- FROM tmp_Product t_P
- WHERE is_new = 1
- ;
-
- -- If we reach here without error, commit the transaction
+ IF NOT ISNULL(v_ids_product_permission) THEN
+ INSERT INTO partsltd_prod.Shop_Product_Change_Set ( comment )
+ VALUES ( a_comment )
+ ;
+
+ SET v_id_change_set := LAST_INSERT_ID();
+
+ UPDATE partsltd_prod.Shop_Product P
+ INNER JOIN tmp_Product t_P ON P.id_product = t_P.id_product
+ SET
+ P.id_category = t_P.id_category
+ , P.name = t_P.name
+ , P.has_variations = t_P.has_variations
+ , P.id_access_level_required = t_P.id_access_level_required
+ , P.display_order = t_P.display_order
+ , P.id_change_set = v_id_change_set
+ ;
+ END IF;
+
+ INSERT INTO partsltd_prod.Shop_Product (
+ id_category
+ , name
+ , has_variations
+ , id_access_level_required
+ , display_order
+ , created_by
+ , created_on
+ )
+ SELECT
+ t_P.id_category AS id_category
+ , t_P.name AS name
+ , t_P.has_variations AS has_variations
+ , t_P.id_access_level_required AS id_access_level_required
+ , t_P.display_order AS display_order
+ , a_id_user AS created_by
+ , v_time_start AS created_on
+ FROM tmp_Product t_P
+ WHERE is_new = 1
+ ;
+
+ DELETE FROM partsltd_prod.Shop_Product_Category_Temp
+ WHERE GUID = a_guid;
COMMIT;
END IF;
- SELECT * FROM tmp_Msg_Error;
+ SELECT *
+ FROM tmp_Msg_Error t_ME
+ INNER JOIN partsltd_prod.Shop_Msg_Error_Type MET ON t_ME.id_type = MET.id_type
+ ;
DROP TEMPORARY TABLE IF EXISTS tmp_Product;
DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error;
+
+ IF a_debug = 1 THEN
+ CALL partsltd_prod.p_debug_timing_reporting ( v_time_start );
+ END IF;
END //
DELIMITER ;;
diff --git a/static/MySQL/7203_p_shop_save_product_test.sql b/static/MySQL/7203_p_shop_save_product_test.sql
new file mode 100644
index 00000000..18666a78
--- /dev/null
+++ b/static/MySQL/7203_p_shop_save_product_test.sql
@@ -0,0 +1,78 @@
+
+
+-- Clear previous proc
+DROP PROCEDURE IF EXISTS partsltd_prod.p_shop_save_product_test;
+
+
+DELIMITER //
+CREATE PROCEDURE p_shop_save_product_test ()
+BEGIN
+
+ DECLARE v_guid BINARY(36);
+ DECLARE v_time_start TIMESTAMP(6);
+
+ SET v_time_start := CURRENT_TIMESTAMP(6);
+ SET v_guid := 'nips';
+
+ SELECT *
+ FROM partsltd_prod.Shop_Product
+ ;
+ SELECT *
+ FROM partsltd_prod.Shop_Product_Temp
+ ;
+
+ START TRANSACTION;
+
+ INSERT INTO partsltd_prod.Shop_Product_Temp (
+ id_product
+ , id_category
+ , name
+ , has_variations
+ , id_access_level_required
+ , display_order
+ , active
+ , guid
+ )
+ VALUES (
+ 4 -- id_product
+ , 1 -- id_category
+ , 'Laptops' -- name
+ , 1 -- has_variations
+ , 2 -- id_access_level_required
+ , 2 -- display_order
+ , 1 -- active
+ , v_guid
+ );
+
+ COMMIT;
+
+ SELECT *
+ FROM partsltd_prod.Shop_Product_Temp
+ WHERE GUID = v_guid
+ ;
+
+ CALL partsltd_prod.p_shop_save_product (
+ 'Test save product' -- comment
+ , v_guid -- guid
+ , 1 -- id_user
+ , 1 -- debug
+ );
+
+ SELECT *
+ FROM partsltd_prod.Shop_Product
+ ;
+ SELECT *
+ FROM partsltd_prod.Shop_Product_Temp
+ ;
+
+ CALL partsltd_prod.p_debug_timing_reporting ( v_time_start );
+END //
+DELIMITER ;;
+
+CALL partsltd_prod.p_shop_save_product_test ();
+
+DELETE FROM partsltd_prod.Shop_Product_Temp;
+/*
+
+DROP TABLE IF EXISTS tmp_Msg_Error;
+*/
\ No newline at end of file
diff --git a/static/MySQL/7206_p_shop_save_permutation.sql b/static/MySQL/7206_p_shop_save_permutation.sql
deleted file mode 100644
index 14d49efe..00000000
--- a/static/MySQL/7206_p_shop_save_permutation.sql
+++ /dev/null
@@ -1,605 +0,0 @@
-
-
-
-
--- Clear previous proc
-DROP PROCEDURE IF EXISTS p_shop_save_permutation;
-
-DROP TABLE IF EXISTS tmp_Shop_Manufacturing_Purchase_Order_Product_Link;
-DROP TABLE IF EXISTS tmp_Msg_Error;
-
-DELIMITER //
-CREATE PROCEDURE p_shop_save_permutation (
- IN a_guid VARCHAR(500),
- IN a_id_user INT,
- IN a_id_order INT,
- -- IN a_id_supplier_ordered INT,
- IN a_id_currency_cost INT,
- IN a_active BIT,
- IN a_comment VARCHAR(500)
-)
-BEGIN
- DECLARE v_id_error_type_bad_data INT;
- DECLARE v_code_error_type_bad_data VARCHAR(50);
- DECLARE v_id_error_type_no_permission INT;
- DECLARE v_code_error_type_no_permission VARCHAR(50);
- DECLARE v_guid_permission BINARY(36);
- -- DECLARE v_id_user VARCHAR(100);
- DECLARE v_id_permission_manufacturing_purchase_order INT;
- DECLARE v_id_access_level_EDIT INT;
- DECLARE v_ids_product VARCHAR(4000);
- DECLARE v_ids_product_no_permission VARCHAR(4000);
- -- DECLARE v_id_order_new INT;
- DECLARE v_id_change_set INT;
- DECLARE v_is_new_manufacturing_purchase_order BIT;
-
- SET SESSION sql_mode = sys.list_drop(@@session.sql_mode, 'ONLY_FULL_GROUP_BY');
-
- SET v_code_error_type_bad_data = 'BAD_DATA';
- SET v_id_error_type_bad_data := (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = v_code_error_type_bad_data LIMIT 1);
- SET v_code_error_type_no_permission = 'NO_PERMISSION';
- SET v_id_error_type_no_permission := (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = v_code_error_type_no_permission LIMIT 1);
- SET v_guid_permission = UUID();
- -- SET v_id_user = CURRENT_USER();
- SET v_id_permission_manufacturing_purchase_order := (SELECT id_permission FROM Shop_Permission WHERE code = 'STORE_MANUFACTURING_PURCHASE_ORDER' LIMIT 1);
- SET v_id_access_level_EDIT := (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'EDIT');
-
- -- Argument default values
- IF a_guid IS NULL THEN
- SET a_guid = UUID();
- END IF;
- IF a_active IS NULL THEN
- SET a_active = 0;
- END IF;
-
- -- Temporary tables
- /*
- CREATE TABLE tmp_Shop_Supplier_Purchase_Order (
- id_order INT NOT NULL PRIMARY KEY,
- id_supplier_ordered INT NOT NULL,
- CONSTRAINT FK_tmp_Shop_Supplier_Purchase_Order_id_supplier_ordered
- FOREIGN KEY (id_supplier_ordered)
- REFERENCES Shop_Supplier(id_supplier),
- cost_total_local FLOAT NOT NULL,
- id_currency_cost INT NOT NULL
- );
- */
-
- CREATE TABLE tmp_Shop_Manufacturing_Purchase_Order_Product_Link (
- id_link INT NOT NULL PRIMARY KEY,
- id_order INT NOT NULL,
- /*
- CONSTRAINT FK_tmp_Supplier_Purchase_Order_Product_Link_id_order
- FOREIGN KEY (id_order)
- REFERENCES Shop_Manufacturing_Purchase_Order(id_order),
- */
- id_permutation INT NOT NULL,
- CONSTRAINT FK_tmp_Manuf_Purch_Order_Product_Link_id_permutation
- FOREIGN KEY (id_permutation)
- REFERENCES Shop_Product_Permutation(id_permutation),
- cost_total_local FLOAT NOT NULL,
- id_currency_cost INT NOT NULL,
- value_produced_total_local FLOAT NOT NULL,
- quantity_used FLOAT NOT NULL,
- id_unit_quantity INT NOT NULL,
- CONSTRAINT FK_tmp_Manuf_Purch_Order_Product_Link_id_unit_quantity
- FOREIGN KEY (id_unit_quantity)
- REFERENCES Shop_Unit_Measurement(id_unit_measurement),
- quantity_produced FLOAT NULL,
- latency_manufacture_days INT NOT NULL,
- display_order INT NOT NULL,
- active BIT NOT NULL,
- name_error VARCHAR(200) NOT NULL
- );
-
- CREATE TABLE IF NOT EXISTS tmp_Msg_Error (
- display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
- guid BINARY(36) NOT NULL,
- id_type INT NOT NULL,
- CONSTRAINT FK_tmp_Msg_Error_id_type
- FOREIGN KEY (id_type)
- REFERENCES Shop_Msg_Error_Type (id_type),
- code VARCHAR(50) NOT NULL,
- msg VARCHAR(4000) NOT NULL
- );
-
-
- -- Argument validation
- # User ID
- IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN
- IF ISNULL(a_id_user) OR NOT EXISTS (SELECT * FROM Shop_User WHERE id_user = a_id_user) THEN
- INSERT INTO tmp_Msg_Error (
- guid, id_type, code, msg
- )
- VALUES
- (a_guid, v_id_error_type_bad_data, v_code_error_type_bad_data, CONCAT('Invalid User ID: ', IFNULL(a_id_user, 'NULL')))
- ;
- END IF;
- END IF;
-
- # Order ID
- IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN
- IF ISNULL(a_id_order) OR ((a_id_order > 0) AND NOT EXISTS (SELECT * FROM Shop_Manufacturing_Purchase_Order WHERE id_order = a_id_order)) THEN
- INSERT INTO tmp_Msg_Error (
- guid, id_type, code, msg
- )
- VALUES
- (a_guid, v_id_error_type_bad_data, v_code_error_type_bad_data, CONCAT('Invalid Manufacturing Purchase Order ID: ', IFNULL(a_id_order, 'NULL')))
- ;
- END IF;
- END IF;
-
- /*
- # Supplier ID
- IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN
- IF ISNULL(a_id_supplier_ordered) OR NOT EXISTS (SELECT * FROM Shop_Supplier WHERE id_supplier = a_id_supplier_ordered) THEN
- INSERT INTO tmp_Msg_Error (
- guid, id_type, code, msg
- )
- VALUES
- (a_guid, v_id_error_type_bad_data, v_code_error_type_bad_data, CONCAT('Invalid supplier ID: ', IFNULL(a_id_supplier_ordered, 'NULL')))
- ;
- END IF;
- END IF;
- */
-
- # Currency ID
- IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN
- IF ISNULL(a_id_currency_cost) OR NOT EXISTS (SELECT * FROM Shop_Currency WHERE id_currency = a_id_currency_cost) THEN
- INSERT INTO tmp_Msg_Error (
- guid, id_type, code, msg
- )
- VALUES
- (a_guid, v_id_error_type_bad_data, v_code_error_type_bad_data, CONCAT('Invalid currency ID: ', IFNULL(a_id_currency, 'NULL')))
- ;
- END IF;
- END IF;
-
- # Comment
- IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN
- IF ISNULL(a_comment) OR TRIM(a_comment) = '' THEN
- INSERT INTO tmp_Msg_Error (
- guid, id_type, code, msg
- )
- VALUES
- (a_guid, v_id_error_type_bad_data, v_code_error_type_bad_data, 'A comment must be provided.')
- ;
- END IF;
- END IF;
-
-
- -- Get data from Temp table
- IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN
- SET v_is_new_manufacturing_purchase_order := CASE WHEN a_id_order <= 0 THEN 1 ELSE 0 END;
-
- INSERT INTO tmp_Shop_Manufacturing_Purchase_Order_Product_Link (
- id_link,
- id_order,
- id_permutation,
- cost_total_local,
- id_currency_cost,
- quantity_used,
- id_unit_quantity,
- quantity_produced,
- value_produced_total_local,
- latency_manufacture_days,
- display_order,
- active,
- name_error
- )
- /*
- VALUES
- (a_id_supplier, a_name_company, a_name_contact, a_department_contact, a_id_address, a_phone_number, a_fax, a_email, a_website, a_id_currency, a_active)
- */
- SELECT
- MPOPL_T.id_link,
- MPOPL_T.id_order,
- MPOPL_T.id_permutation,
- PP.cost_local * MPOPL_T.quantity_used AS cost_total_local,
- MPOPL_T.id_currency_cost,
- MPOPL_T.quantity_used,
- MPOPL_T.id_unit_quantity,
- MPOPL_T.quantity_produced,
- (PP.cost_local + PP.profit_local_min) * MPOPL_T.quantity_produced AS value_produced_total_local,
- MPOPL_T.latency_manufacture_days,
- MPOPL_T.display_order,
- MPOPL_T.active,
- CONCAT(PP.id_permutation, ' - ', IFNULL(P.name ,'')) AS name_error
- FROM Shop_Manufacturing_Purchase_Order_Product_Link_Temp MPOPL_T
- INNER JOIN Shop_Product_Permutation PP ON MPOPL_T.id_permutation = PP.id_permutation
- INNER JOIN Shop_Product P ON PP.id_product = P.id_product
- WHERE MPOPL_T.GUID = a_guid
- -- GROUP BY MPOPL_T.id_order, name_error, MPOPL_T.id_link
- /*
- group by
- MPOPL_T.id_link,
- MPOPL_T.id_order,
- MPOPL_T.id_permutation,
- cost_total_local,
- MPOPL_T.id_currency_cost,
- MPOPL_T.quantity_used,
- MPOPL_T.id_unit_quantity,
- MPOPL_T.quantity_produced,
- value_produced_total_local,
- MPOPL_T.latency_manufacture_days,
- MPOPL_T.display_order,
- MPOPL_T.active,
- name_error
- */
- -- GROUP BY id_link, P.id_product, PP.id_permutation
- -- GROUP BY name_error, ID_LINK, cost_total_local, value_produced_total_local
- ;
- DELETE MPOPL_T
- FROM Shop_Manufacturing_Purchase_Order_Product_Link_Temp MPOPL_T
- WHERE MPOPL_T.GUID = a_guid
- ;
- END IF;
-
- -- Invalid quantity used
- IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN
- IF EXISTS (
- SELECT *
- FROM tmp_Shop_Manufacturing_Purchase_Order_Product_Link
- WHERE
- NOT ISNULL(quantity_used)
- AND quantity_used < 0
- ) THEN
- INSERT INTO tmp_Msg_Error (
- guid, id_type, code, msg
- )
- SELECT
- a_guid,
- v_id_error_type_bad_data,
- v_code_error_type_bad_data,
- CONCAT('Invalid quantity used property for the following permutations: ', GROUP_CONCAT(t_MPOPL.name_error SEPARATOR ', '))
- FROM tmp_Shop_Manufacturing_Purchase_Order_Product_Link t_MPOPL
- WHERE t_MPOPL.quantity_used < 0
- ;
- END IF;
- END IF;
-
- -- Invalid quantity produced
- IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN
- IF EXISTS (
- SELECT *
- FROM tmp_Shop_Manufacturing_Purchase_Order_Product_Link
- WHERE
- NOT ISNULL(quantity_produced)
- AND quantity_produced < 0
- ) THEN
- INSERT INTO tmp_Msg_Error (
- guid, id_type, code, msg
- )
- SELECT
- a_guid,
- v_id_error_type_bad_data,
- v_code_error_type_bad_data,
- CONCAT('Invalid quantity produced property for the following permutations: ', GROUP_CONCAT(t_MPOPL.name_error SEPARATOR ', '))
- FROM tmp_Shop_Manufacturing_Purchase_Order_Product_Link t_MPOPL
- WHERE t_MPOPL.quantity_produced < 0
- ;
- END IF;
- END IF;
-
- -- Duplicates
- IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN
- IF EXISTS (SELECT id_permutation, name_error, COUNT(*) FROM tmp_Shop_Manufacturing_Purchase_Order_Product_Link t_MPOPL GROUP BY id_permutation HAVING COUNT(*) > 1) THEN
- INSERT INTO tmp_Msg_Error (
- guid, id_type, code, msg
- )
- SELECT
- a_guid,
- v_id_error_type_bad_data,
- v_code_error_type_bad_data,
- CONCAT('Duplicate records: ', GROUP_CONCAT(t_MPOPLC.name_error SEPARATOR ', '))
- FROM (SELECT id_permutation, name_error, COUNT(*) FROM tmp_Shop_Manufacturing_Purchase_Order_Product_Link t_MPOPL GROUP BY id_permutation HAVING COUNT(*) > 1) t_MPOPLC
- ;
- END IF;
- END IF;
-
-
- -- Permissions
- IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN
- SET v_ids_product := (
- SELECT GROUP_CONCAT(G.id_product SEPARATOR ',')
- FROM (
- SELECT DISTINCT PP.id_product
- FROM tmp_Shop_Manufacturing_Purchase_Order_Product_Link t_MPO
- INNER JOIN Shop_Product_Permutation PP ON t_MPO.id_permutation = PP.id_permutation
- ) G
- );
-
- CALL p_shop_calc_user(v_guid_permission, a_id_user, 0, v_id_permission_manufacturing_purchase_order, v_id_access_level_edit, v_ids_product);
-
- /*
- UPDATE tmp_Shop_Supplier t_S
- INNER JOIN Shop_Calc_User_Temp TP
- ON TP.GUID = v_guid_permission
- SET tP.can_view = TP.can_view,
- tP.can_edit = TP.can_edit,
- tP.can_admin = TP.can_admin;
- */
- /*
- SET v_has_permission := (
- SELECT can_edit
- FROM Shop_Calc_User_Temp
- WHERE
- GUID = v_guid_permission
- AND can_edit = 0
- );
-
- IF v_has_permission = 0 THEN
- SET v_id_error_type_no_permission := (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'NO_PERMISSION');
- INSERT INTO tmp_Msg_Error (
- guid, id_type, msg
- )
- SELECT
- a_guid,
- v_id_error_type_no_permission,
- CONCAT('You do not have ', name, ' permissions.')
- FROM Shop_Permission
- WHERE id_permission = v_id_permission_manufacturing_purchase_order
- ;
- END IF;
- */
- SET v_ids_product_no_permission := (
- SELECT GROUP_CONCAT(PT.id_product SEPARATOR ',')
- FROM Shop_Calc_User_Temp PT
- WHERE
- PT.can_edit = 0
- AND NOT ISNULL(PT.id_product)
- );
- IF NOT ISNULL(v_ids_product_no_permission) THEN
- INSERT INTO tmp_Msg_Error (
- guid, id_type, code, msg
- )
- VALUES (
- a_guid,
- v_id_error_type_no_permission,
- v_code_error_type_no_permission,
- CONCAT('You do not have permission to edit the following product IDs: ', v_ids_product_no_permission)
- )
- ;
- END IF;
- END IF;
-
- -- Transaction
- IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN
- START TRANSACTION;
- INSERT INTO Shop_Sales_And_Purchasing_Change_Set (
- comment,
- updated_last_by,
- updated_last_on
- )
- VALUES (
- CONCAT(
- 'Save ',
- CASE WHEN v_is_new_manufacturing_purchase_order = 1 THEN 'new ' ELSE '' END,
- 'Manufacturing Purchase Order - ',
- a_comment
- ),
- a_id_user,
- CURRENT_TIME()
- );
-
- SET v_id_change_set := (SELECT id_change_set FROM Shop_Sales_And_Purchasing_Change_Set ORDER BY id_change_set DESC LIMIT 1);
-
- IF (v_is_new_manufacturing_purchase_order = 1) THEN
- INSERT INTO Shop_Manufacturing_Purchase_Order (
- -- id_supplier_ordered,
- cost_total_local,
- id_currency_cost,
- value_produced_total_local,
- created_by,
- id_change_set,
- active
- )
- SELECT
- -- a_id_supplier_ordered,
- SUM(t_MPOPL.cost_total_local),
- a_id_currency_cost,
- SUM(t_MPOPL.value_produced_total_local),
- a_id_user,
- v_id_change_set,
- a_active
- FROM tmp_Shop_Manufacturing_Purchase_Order_Product_Link t_MPOPL
- ;
- -- SET v_id_order_new
- SET a_id_order := (SELECT id_order FROM Shop_Manufacturing_Purchase_Order ORDER BY id_order DESC LIMIT 1);
-
- INSERT INTO Shop_Manufacturing_Purchase_Order_Product_Link (
- id_order,
- id_permutation,
- cost_total_local,
- value_produced_total_local,
- id_currency_cost,
- quantity_used,
- id_unit_quantity,
- quantity_produced,
- latency_manufacture_days,
- display_order,
- active,
- created_by,
- id_change_set
- )
- SELECT
- a_id_order, -- v_id_order_new,
- id_permutation,
- cost_total_local,
- value_produced_total_local,
- id_currency_cost,
- quantity_used,
- id_unit_quantity,
- quantity_produced,
- latency_manufacture_days,
- display_order,
- active,
- a_id_user,
- v_id_change_set
- FROM tmp_Shop_Manufacturing_Purchase_Order_Product_Link t_MPOPL
- ;
- ELSE
- UPDATE Shop_Manufacturing_Purchase_Order MPO
- INNER JOIN tmp_Shop_Manufacturing_Purchase_Order_Product_Link t_MPOPL ON MPO.id_order = t_MPOPL.id_order
- SET
- -- MPO.id_supplier_ordered = a_id_supplier_ordered,
- MPO.cost_total_local = SUM(t_MPOPL.cost_total_local),
- MPO.value_produced_total_local = SUM(t_MPOPL.value_produced_total_local),
- MPO.id_currency = a_id_currency_cost,
- MPO.id_change_set = v_id_change_set,
- MPO.active = a_active
- WHERE MPO.id_order = a_id_order
- ;
- IF EXISTS (SELECT * FROM tmp_Shop_Manufacturing_Purchase_Order_Product_Link t_MPOPL INNER JOIN Shop_Manufacturing_Purchase_Order_Product_Link MPOPL ON t_MPOPL.id_link = MPOPL.id_link) THEN
- UPDATE Shop_Manufacturing_Purchase_Order_Product_Link MPOPL
- INNER JOIN tmp_Shop_Manufacturing_Purchase_Order_Product_Link t_MPOPL
- ON MPOPL.id_link = t_MPOPL.id_link
- SET
- MPOPL.id_order = t_MPOPL.id_order,
- MPOPL.id_permutation = t_MPOPL.id_permutation,
- MPOPL.cost_total_local = t_MPOPL.cost_total_local,
- MPOPL.value_produced_total_local = t_MPOPL.value_produced_total_local,
- MPOPL.id_currency_cost = t_MPOPL.id_currency_cost,
- MPOPL.quantity_used = t_MPOPL.quantity_used,
- MPOPL.id_unit_quantity = t_MPOPL.id_unit_quantity,
- MPOPL.quantity_produced = t_MPOPL.quantity_produced,
- MPOPL.latency_manufacture_days = t_MPOPL.latency_manufacture_days,
- MPOPL.display_order = t_MPOPL.display_order,
- MPOPL.active = t_MPOPL.active,
- MPOPL.id_change_set = v_id_change_set
- ;
- ELSE
- INSERT INTO Shop_Manufacturing_Purchase_Order_Product_Link (
- id_order,
- id_permutation,
- cost_total_local,
- value_produced_total_local,
- id_currency_cost,
- quantity_used,
- id_unit_quantity,
- quantity_produced,
- latency_manufacture_days,
- display_order,
- active,
- created_by,
- id_change_set
- )
- SELECT
- id_order,
- id_permutation,
- cost_total_local,
- value_produced_total_local,
- id_currency_cost,
- quantity_used,
- id_unit_quantity,
- quantity_produced,
- latency_manufacture_days,
- display_order,
- active,
- a_id_user,
- v_id_change_set
- FROM tmp_Shop_Manufacturing_Purchase_Order_Product_Link t_MPOPL
- WHERE t_MPOPL.id_link < 0
- ;
- END IF;
- END IF;
-
- IF EXISTS (SELECT * FROM tmp_Msg_Error) THEN
- ROLLBACK;
- ELSE
- COMMIT;
- END IF;
- END IF;
-
- -- Returns
- # SET v_now = NOW();
-
- # Manufacturing Purchase Orders
- SELECT *
- FROM Shop_Manufacturing_Purchase_Order
- WHERE
- id_order = a_id_order
- -- GUID = a_guid
- ;
-
- # Manufacturing Purchase Order Product Links
- SELECT *
- FROM Shop_Manufacturing_Purchase_Order_Product_Link
- WHERE
- id_order = a_id_order
- -- GUID = a_guid
- ;
-
- # Errors
- SELECT *
- FROM tmp_Msg_Error
- ;
-
- # DROP TABLE tmp_Shop_Manufacturing_Purchase_Order;
- DROP TABLE tmp_Shop_Manufacturing_Purchase_Order_Product_Link;
- DROP TABLE tmp_Msg_Error;
-END //
-DELIMITER ;;
-
-
-/*
-
-DELETE FROM Shop_Manufacturing_Purchase_Order_Product_Link_Audit;
-DELETE FROM Shop_Manufacturing_Purchase_Order_Product_Link;
-DELETE FROM Shop_Manufacturing_Purchase_Order_Product_Link_Temp;
-DELETE FROM Shop_Manufacturing_Purchase_Order_Audit;
-DELETE FROM Shop_Manufacturing_Purchase_Order;
-
-INSERT INTO Shop_Manufacturing_Purchase_Order_Product_Link_Temp (
- guid,
- id_link,
- id_order,
- id_permutation,
- cost_total_local,
- id_currency_cost,
- quantity_used,
- id_unit_quantity,
- quantity_produced,
- latency_manufacture_days,
- display_order,
- active
-)
-VALUES
- (
- 'NIPS', # guid
- -1, # id_link,
- -1, # id_order,
- 1, # id_permutation,
- 100, # cost_total_local,
- 1, # id_currency_cost,
- 1, # quantity_used,
- 1, # id_unit_quantity,
- 1, # quantity_produced,
- 14, # latency_manufacture_days ,
- 1, # display_order
- 1 # active
- )
-;
-
-SELECT * FROM Shop_Manufacturing_Purchase_Order_Product_Link_Temp;
-
-CALL p_shop_save_manufacturing_purchase_order (
- 'NIPS', # a_guid
- 'auth0|6582b95c895d09a70ba10fef', # a_id_user
- -1, # a_id_order
- 1, # a_id_currency_cost
- 1, # a_active
- 'Initial data' # a_comment
-);
-
-SELECT * FROM Shop_Manufacturing_Purchase_Order_Product_Link_Temp;
-
-DELETE FROM Shop_Manufacturing_Purchase_Order_Product_Link_Audit;
-DELETE FROM Shop_Manufacturing_Purchase_Order_Product_Link;
-DELETE FROM Shop_Manufacturing_Purchase_Order_Product_Link_Temp;
-DELETE FROM Shop_Manufacturing_Purchase_Order_Audit;
-DELETE FROM Shop_Manufacturing_Purchase_Order;
-
-
-*/
-
diff --git a/static/MySQL/7206_p_shop_save_product_permutation.sql b/static/MySQL/7206_p_shop_save_product_permutation.sql
index 1468ddd8..e56d960b 100644
--- a/static/MySQL/7206_p_shop_save_product_permutation.sql
+++ b/static/MySQL/7206_p_shop_save_product_permutation.sql
@@ -6,9 +6,9 @@ DROP PROCEDURE IF EXISTS p_shop_save_product_permutation;
DELIMITER //
CREATE PROCEDURE p_shop_save_product_permutation (
- IN a_id_user INT,
IN a_comment VARCHAR(500),
- IN a_guid BINARY(36)
+ IN a_guid BINARY(36),
+ IN a_id_user INT
)
BEGIN
diff --git a/static/MySQL/7210_p_shop_get_many_product_variation.sql b/static/MySQL/7210_p_shop_get_many_product_variation.sql
index c684ddae..0cfcb40d 100644
--- a/static/MySQL/7210_p_shop_get_many_product_variation.sql
+++ b/static/MySQL/7210_p_shop_get_many_product_variation.sql
@@ -26,14 +26,14 @@ BEGIN
DECLARE v_id_access_level_view INT;
DECLARE v_time_start TIMESTAMP(6);
DECLARE v_id_minimum INT;
- DECLARE v_code_error_data VARCHAR(50);
- DECLARE v_id_type_error_data INT;
+ DECLARE v_code_error_bad_data VARCHAR(50);
+ DECLARE v_id_type_error_bad_data INT;
SET v_time_start := CURRENT_TIMESTAMP(6);
SET v_guid := UUID();
SET v_id_access_level_view := (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'VIEW' LIMIT 1);
- SET v_code_error_data := (SELECT code FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1);
- SET v_id_type_error_data := (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = v_code_error_data LIMIT 1);
+ SET v_code_error_bad_data := (SELECT code FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1);
+ SET v_id_type_error_bad_data := (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = v_code_error_bad_data LIMIT 1);
-- Argument validation + default values
SET a_id_user = IFNULL(a_id_user, 0);
@@ -282,8 +282,8 @@ BEGIN
)
VALUES (
-- v_guid,
- v_id_type_error_data,
- v_code_error_data,
+ v_id_type_error_bad_data,
+ v_code_error_bad_data,
CONCAT('You do not have view permissions for ', (SELECT name FROM Shop_Permission WHERE id_permission = v_id_permission_variation LIMIT 1))
)
;
diff --git a/static/MySQL/7219_p_shop_get_many_stock_item.sql b/static/MySQL/7219_p_shop_get_many_stock_item.sql
index 86caa1bc..21c21bf2 100644
--- a/static/MySQL/7219_p_shop_get_many_stock_item.sql
+++ b/static/MySQL/7219_p_shop_get_many_stock_item.sql
@@ -609,7 +609,7 @@ BEGIN
)
;
- # CALL p_shop_calc_user_clear_temp(v_guid);
+ # CALL p_shop_clear_calc_user(v_guid);
# DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM partsltd_prod.Shop_Calc_User_Temp
WHERE GUID = v_guid
diff --git a/static/MySQL/7400_p_shop_save_supplier.sql b/static/MySQL/7400_p_shop_save_supplier.sql
index df19624f..64f88225 100644
--- a/static/MySQL/7400_p_shop_save_supplier.sql
+++ b/static/MySQL/7400_p_shop_save_supplier.sql
@@ -184,7 +184,7 @@ BEGIN
;
END IF;
- -- CALL p_shop_calc_user_clear_temp(v_guid_permission);
+ -- CALL p_shop_clear_calc_user(v_guid_permission);
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = a_guid;
diff --git a/static/MySQL/7404_p_shop_get_many_supplier_purchase_order.sql b/static/MySQL/7404_p_shop_get_many_supplier_purchase_order.sql
index 17a95205..c945e1b7 100644
--- a/static/MySQL/7404_p_shop_get_many_supplier_purchase_order.sql
+++ b/static/MySQL/7404_p_shop_get_many_supplier_purchase_order.sql
@@ -615,7 +615,7 @@ BEGIN
t_P.can_admin = UE_T.can_admin
;
- # CALL p_shop_calc_user_clear_temp(v_guid);
+ # CALL p_shop_clear_calc_user(v_guid);
# DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
diff --git a/static/MySQL/7416_p_shop_get_many_manufacturing_purchase_order.sql b/static/MySQL/7416_p_shop_get_many_manufacturing_purchase_order.sql
index b04ef5fa..5f55c21c 100644
--- a/static/MySQL/7416_p_shop_get_many_manufacturing_purchase_order.sql
+++ b/static/MySQL/7416_p_shop_get_many_manufacturing_purchase_order.sql
@@ -528,7 +528,7 @@ BEGIN
t_P.can_admin = UE_T.can_admin
;
- # CALL p_shop_calc_user_clear_temp(v_guid);
+ # CALL p_shop_clear_calc_user(v_guid);
# DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
diff --git a/static/MySQL/7421_p_shop_save_customer.sql b/static/MySQL/7421_p_shop_save_customer.sql
index 07622f00..86b46279 100644
--- a/static/MySQL/7421_p_shop_save_customer.sql
+++ b/static/MySQL/7421_p_shop_save_customer.sql
@@ -180,7 +180,7 @@ BEGIN
;
END IF;
- -- CALL p_shop_calc_user_clear_temp(v_guid_permission);
+ -- CALL p_shop_clear_calc_user(v_guid_permission);
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = a_guid;
diff --git a/static/MySQL/7425_p_shop_get_many_customer_sales_order.sql b/static/MySQL/7425_p_shop_get_many_customer_sales_order.sql
index 147c4566..df3abf91 100644
--- a/static/MySQL/7425_p_shop_get_many_customer_sales_order.sql
+++ b/static/MySQL/7425_p_shop_get_many_customer_sales_order.sql
@@ -627,7 +627,7 @@ BEGIN
t_P.can_admin = UE_T.can_admin
;
- # CALL p_shop_calc_user_clear_temp(v_guid);
+ # CALL p_shop_clear_calc_user(v_guid);
# DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
diff --git a/static/MySQL/9000_populate.sql b/static/MySQL/9000_populate.sql
index 8b366468..c4e1836c 100644
--- a/static/MySQL/9000_populate.sql
+++ b/static/MySQL/9000_populate.sql
@@ -33,9 +33,10 @@ INSERT INTO Shop_Msg_Error_Type (
code, name, description
)
VALUES
- ('BAD_DATA', 'Invalid data', 'Rubbish data'),
- ('NO_PERMISSION', 'No permission', 'Not authorised'),
- ('PRODUCT_AVAILABILITY', 'Product not available', 'Product not available')
+ ('BAD_DATA', 'Invalid data', 'Rubbish data')
+ , ('NO_PERMISSION', 'No permission', 'Not authorised')
+ , ('PRODUCT_AVAILABILITY', 'Product not available', 'Product not available')
+ , ('MYSQL_ERROR', 'MySQL error', 'MySQL execution error.')
;
# File Types
diff --git a/static/PostgreSQL/000_combine.sql b/static/PostgreSQL/000_combine.sql
index 6aea8b4d..89e2573a 100644
--- a/static/PostgreSQL/000_combine.sql
+++ b/static/PostgreSQL/000_combine.sql
@@ -6982,7 +6982,7 @@ BEGIN
;
END IF;
- -- CALL p_shop_calc_user_clear_temp(v_guid_permission);
+ -- CALL p_shop_clear_calc_user(v_guid_permission);
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid;
@@ -7878,7 +7878,7 @@ BEGIN
*/
END IF;
- -- CALL p_shop_calc_user_clear_temp(v_guid_permission);
+ -- CALL p_shop_clear_calc_user(v_guid_permission);
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid;
@@ -10368,7 +10368,7 @@ BEGIN
OR t_P.can_view = FALSE
;
- -- CALL p_shop_calc_user_clear_temp(v_guid);
+ -- CALL p_shop_clear_calc_user(v_guid);
-- DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
@@ -12527,7 +12527,7 @@ BEGIN
AND UE_T.GUID = v_guid
;
- -- CALL p_shop_calc_user_clear_temp(v_guid);
+ -- CALL p_shop_clear_calc_user(v_guid);
-- DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
@@ -13156,7 +13156,7 @@ BEGIN
AND UE_T.GUID = v_guid
;
- -- CALL p_shop_calc_user_clear_temp(v_guid);
+ -- CALL p_shop_clear_calc_user(v_guid);
-- DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
@@ -14099,7 +14099,7 @@ BEGIN
AND UE_T.GUID = v_guid
;
- -- CALL p_shop_calc_user_clear_temp(v_guid);
+ -- CALL p_shop_clear_calc_user(v_guid);
-- DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
diff --git a/static/PostgreSQL/600_p_shop_save_product.sql b/static/PostgreSQL/600_p_shop_save_product.sql
index a5dc4387..d29a1d12 100644
--- a/static/PostgreSQL/600_p_shop_save_product.sql
+++ b/static/PostgreSQL/600_p_shop_save_product.sql
@@ -179,7 +179,7 @@ BEGIN
tP.can_edit = TP.can_edit,
tP.can_admin = TP.can_admin;
- CALL p_shop_calc_user_clear_temp(v_guid_permission);
+ CALL p_shop_clear_calc_user(v_guid_permission);
END IF;
diff --git a/static/PostgreSQL/602_p_shop_save_supplier.sql b/static/PostgreSQL/602_p_shop_save_supplier.sql
index f6bd4f8a..1534a0bf 100644
--- a/static/PostgreSQL/602_p_shop_save_supplier.sql
+++ b/static/PostgreSQL/602_p_shop_save_supplier.sql
@@ -215,7 +215,7 @@ BEGIN
;
END IF;
- -- CALL p_shop_calc_user_clear_temp(v_guid_permission);
+ -- CALL p_shop_clear_calc_user(v_guid_permission);
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid;
diff --git a/static/PostgreSQL/605_p_shop_save_customer.sql b/static/PostgreSQL/605_p_shop_save_customer.sql
index d6492334..79ec88d7 100644
--- a/static/PostgreSQL/605_p_shop_save_customer.sql
+++ b/static/PostgreSQL/605_p_shop_save_customer.sql
@@ -199,7 +199,7 @@ BEGIN
*/
END IF;
- -- CALL p_shop_calc_user_clear_temp(v_guid_permission);
+ -- CALL p_shop_clear_calc_user(v_guid_permission);
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid;
diff --git a/static/PostgreSQL/700_p_shop_get_many_product.sql b/static/PostgreSQL/700_p_shop_get_many_product.sql
index ac534d0f..ae671142 100644
--- a/static/PostgreSQL/700_p_shop_get_many_product.sql
+++ b/static/PostgreSQL/700_p_shop_get_many_product.sql
@@ -822,7 +822,7 @@ BEGIN
OR t_P.can_view = FALSE
;
- -- CALL p_shop_calc_user_clear_temp(v_guid);
+ -- CALL p_shop_clear_calc_user(v_guid);
-- DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
diff --git a/static/PostgreSQL/706_p_shop_get_many_supplier_purchase_order.sql b/static/PostgreSQL/706_p_shop_get_many_supplier_purchase_order.sql
index c4d2d63a..7a146245 100644
--- a/static/PostgreSQL/706_p_shop_get_many_supplier_purchase_order.sql
+++ b/static/PostgreSQL/706_p_shop_get_many_supplier_purchase_order.sql
@@ -534,7 +534,7 @@ BEGIN
AND UE_T.GUID = v_guid
;
- -- CALL p_shop_calc_user_clear_temp(v_guid);
+ -- CALL p_shop_clear_calc_user(v_guid);
-- DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
diff --git a/static/PostgreSQL/708_p_shop_get_many_manufacturing_purchase_order.sql b/static/PostgreSQL/708_p_shop_get_many_manufacturing_purchase_order.sql
index 85cd8fa1..6cc77ded 100644
--- a/static/PostgreSQL/708_p_shop_get_many_manufacturing_purchase_order.sql
+++ b/static/PostgreSQL/708_p_shop_get_many_manufacturing_purchase_order.sql
@@ -454,7 +454,7 @@ BEGIN
AND UE_T.GUID = v_guid
;
- -- CALL p_shop_calc_user_clear_temp(v_guid);
+ -- CALL p_shop_clear_calc_user(v_guid);
-- DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
diff --git a/static/PostgreSQL/710_p_shop_get_many_customer_sales_order.sql b/static/PostgreSQL/710_p_shop_get_many_customer_sales_order.sql
index 1242102e..36cd842e 100644
--- a/static/PostgreSQL/710_p_shop_get_many_customer_sales_order.sql
+++ b/static/PostgreSQL/710_p_shop_get_many_customer_sales_order.sql
@@ -547,7 +547,7 @@ BEGIN
AND UE_T.GUID = v_guid
;
- -- CALL p_shop_calc_user_clear_temp(v_guid);
+ -- CALL p_shop_clear_calc_user(v_guid);
-- DROP TABLE IF EXISTS Shop_Calc_User_Temp;
DELETE FROM Shop_Calc_User_Temp
WHERE GUID = v_guid
diff --git a/static/css/pages/store/products.css b/static/css/pages/store/products.css
new file mode 100644
index 00000000..fcdadac8
--- /dev/null
+++ b/static/css/pages/store/products.css
@@ -0,0 +1,76 @@
+
+#formFilters {
+ width: 50vh;
+}
+
+#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 * 79), 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;
+}
+
+textarea {
+ width: 95%;
+}
+
+select {
+ width: 100%;
+}
+
+input {
+ width: 90%;
+}
+
+td > input, td > select, td > textarea, .container-input > input, .container-input > select, .container-input > textarea {
+ border: 2px solid var(--c_purple);
+ border-radius: 0.5vh;
+}
+
+#tableMain tbody tr td button {
+ padding: 0;
+ border: 0;
+ margin: 0;
+ text-decoration: none;
+}
+
+#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/dist/js/main.bundle.js b/static/dist/js/main.bundle.js
index 7fb44013..fe0503a7 100644
--- a/static/dist/js/main.bundle.js
+++ b/static/dist/js/main.bundle.js
@@ -1,2 +1,2 @@
/*! For license information please see main.bundle.js.LICENSE.txt */
-(()=>{"use strict";(()=>{function e(t){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e(t)}function t(e,t){for(var n=0;n0)if(r)t=!1;else if("string"!=typeof e[0])t=!1;else for(var n=0;n0)}},{key:"getDataContentType",value:function(t){var r=null,n="";return e.isEmpty(t)||("string"==typeof t?(r=t,n="application/x-www-form-urlencoded; charset=UTF-8"):(r=JSON.stringify(t),n="application/json; charset=UTF-8")),{Data:r,ContentType:n}}},{key:"arrayContainsItem",value:function(t,r){var n=!1;if(!e.isEmpty(t)&&!e.isEmpty(r))if(t[0]instanceof jQuery){for(var o=0;o=0;--i){var a=this.tryEntries[i],u=a.completion;if("root"===a.tryLoc)return o("end");if(a.tryLoc<=this.prev){var l=n.call(a,"catchLoc"),c=n.call(a,"finallyLoc");if(l&&c){if(this.prev=0;--r){var o=this.tryEntries[r];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),F(r),h}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var o=n.arg;F(r)}return o}}throw Error("illegal catch attempt")},delegateYield:function(t,r,n){return this.delegate={iterator:q(t),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=e),h}},t}function b(e,t,r,n,o,i,a){try{var u=e[i](a),l=u.value}catch(e){return void r(e)}u.done?t(l):Promise.resolve(l).then(n,o)}function k(e){return function(){var t=this,r=arguments;return new Promise((function(n,o){var i=e.apply(t,r);function a(e){b(i,n,o,a,u,"next",e)}function u(e){b(i,n,o,a,u,"throw",e)}a(void 0)}))}}function P(e,t){for(var r=0;r1&&void 0!==c[1]?c[1]:"GET",o=c.length>2&&void 0!==c[2]?c[2]:null,i=c.length>3&&void 0!==c[3]?c[3]:null,a=e.getUrlFromHash(r,i),u={method:n,headers:{"Content-Type":"application/json","X-CSRFToken":e.getCsrfToken()}},!o||"POST"!==n&&"PUT"!==n&&"PATCH"!==n||(u.body=JSON.stringify(o)),console.log("API request:",n,a,o),t.prev=7,t.next=10,fetch(a,u);case 10:if((l=t.sent).ok){t.next=13;break}throw new Error("HTTP error! status: ".concat(l.status));case 13:return t.next=15,l.json();case 15:return t.abrupt("return",t.sent);case 18:throw t.prev=18,t.t0=t.catch(7),console.error("API request failed:",t.t0),t.t0;case 22:case"end":return t.stop()}}),t,null,[[7,18]])}))),function(e){return f.apply(this,arguments)})},{key:"getUrlFromHash",value:function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;null==t&&(t=hashPageHome),console.log("getUrlFromHash:"),console.log("base url: "+_pathHost+"\nhash: "+t+"\nparams: "+r);var n=e.parameteriseUrl(_pathHost+t,r);return console.log("url: "+n),n}},{key:"parameteriseUrl",value:function(e,t){return t&&(e+="?"+new URLSearchParams(t).toString()),e}},{key:"goToUrl",value:function(e){window.location.href=e}},{key:"goToHash",value:function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=e.getUrlFromHash(t,r);e.goToUrl(n)}},{key:"loginUser",value:(s=k(m().mark((function t(){var r;return m().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return(r={})[keyCallback]=l.getHashPageCurrent(),t.next=4,e.request(hashPageUserLogin,"POST",r);case 4:return t.abrupt("return",t.sent);case 5:case"end":return t.stop()}}),t)}))),function(){return s.apply(this,arguments)})},{key:"getCategories",value:(c=k(m().mark((function t(){return m().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,e.request(hashGetStoreProductCategory);case 2:return t.abrupt("return",t.sent);case 3:case"end":return t.stop()}}),t)}))),function(){return c.apply(this,arguments)})},{key:"getCategoriesByFilters",value:(u=k(m().mark((function t(r){return m().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:e.goToHash(hashPageStoreProductCategories,r);case 1:case"end":return t.stop()}}),t)}))),function(e){return u.apply(this,arguments)})},{key:"saveCategories",value:(a=k(m().mark((function t(r,n,o){var i;return m().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return(i={})[flagFormFilters]=l.convertForm2JSON(n),i[flagProductCategory]=r,i[flagComment]=o,t.next=6,e.request(hashSaveStoreProductCategory,"POST",i);case 6:return t.abrupt("return",t.sent);case 7:case"end":return t.stop()}}),t)}))),function(e,t,r){return a.apply(this,arguments)})},{key:"getProductPermutations",value:(i=k(m().mark((function t(){return m().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,e.request(hashGetStoreProductPermutation);case 2:return t.abrupt("return",t.sent);case 3:case"end":return t.stop()}}),t)}))),function(){return i.apply(this,arguments)})},{key:"getProductPermutationsByFilters",value:(o=k(m().mark((function t(r){return m().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:e.goToHash(hashPageStoreProductPermutations,r);case 1:case"end":return t.stop()}}),t)}))),function(e){return o.apply(this,arguments)})},{key:"saveProductPermutations",value:(n=k(m().mark((function t(r,n,o){var i;return m().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return(i={})[flagFormFilters]=l.convertForm2JSON(n),i[flagProductPermutation]=r,i[flagComment]=o,t.next=6,e.request(hashSaveStoreProductPermutation,"POST",i);case 6:return t.abrupt("return",t.sent);case 7:case"end":return t.stop()}}),t)}))),function(e,t,r){return n.apply(this,arguments)})}],r&&P(t,r),Object.defineProperty(t,"prototype",{writable:!1}),t;var t,r,n,o,i,a,u,c,s,f}();function w(e){return w="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},w(e)}function E(e,t){for(var r=0;r"+r[keyNameFull]+" at "+r[keyPostcode]+"",document.querySelectorAll(idOverlayInfoBilling).css("display","none"),document.querySelectorAll(idOverlayInfoBilling).querySelector("form").classList.add(flagSubmitted)}else document.querySelectorAll(idContainerInfoDelivery).querySelector("div").innerHTML=""+r[keyNameFull]+" at "+r[keyPostcode]+"",document.querySelectorAll(idOverlayInfoDelivery).css("display","none"),document.querySelectorAll(idOverlayInfoDelivery).querySelector("form").classList.add(flagSubmitted)}},{key:"convertFormBilling2JSON",value:function(e,t){var r;r=document.querySelectorAll(t).querySelector("form"),r=document.querySelectorAll(idOverlayInfoDelivery).querySelector("form"),console.log("converting billing form to json\nform ID: "+r.id),e[keyForm]=convertForm2JSON(r);var n=[keyNameFull,keyPhoneNumber,keyPostcode,keyAddress1,keyAddress2,keyCity,keyCounty];for(var o in console.log("ajaxData:"),console.log(e),e[keyForm][keyInfoIdentical]=getElementValueCurrent(r.querySelector("#"+keyInfoIdentical)),n)t==idOverlayInfoBilling&&e[keyForm][keyInfoIdentical]?e[keyForm][n[o]]=getElementValueCurrent((void 0).querySelector("#"+n[o])):e[keyForm][n[o]]=getElementValueCurrent(r.querySelector("#"+n[o]));return console.log("ajaxData:"),console.log(e),e}},{key:"hookupButtonCheckoutSession",value:function(){var e=document.querySelectorAll(idButtonCheckout);e.classList.remove(flagInitialised),y.initialiseEventHandler(idButtonCheckout,flagInitialised,(function(){e.removeEventListener("click"),e.addEventListener("click",(function(e){var t=h.getLocalStorage(keyBasket),r={};r[keyBasket]=t,r=convertFormBilling2JSON(r,idOverlayInfoDelivery),(r=convertFormBilling2JSON(r,idOverlayInfoBilling))[key_code_currency]=getCurrencySelected(),ajaxJSONData("checkout session",mapHashToController(hashPageStoreCheckout),r,handleResponseCheckout,!1)}))}))}},{key:"handleResponseCheckout",value:function(e){window.location.href=e.data[keyUrlCheckout]}},{key:"hookupButtonFormBillingCopy",value:function(){y.initialiseEventHandler(idButtonFormBillingCopy,flagInitialised,(function(){document.querySelectorAll(idButtonFormBillingCopy).addEventListener("click",(function(e){var t=[keyNameFull,keyPhoneNumber,keyPostcode,keyAddress1,keyAddress2,keyCity,keyCounty],r=document.querySelectorAll(idOverlayInfoBilling).querySelector("form"),n=document.querySelectorAll(idOverlayInfoDelivery).querySelector("form");for(var o in t)r.querySelector("#"+t[o]).value=getElementValueCurrent(n.querySelector("#"+t[o]))}))}))}},{key:"leave",value:function(){!function(e,t,r){var n=Ke(We(e.prototype),"leave",r);return"function"==typeof n?function(e){return n.apply(r,e)}:n}(t,0,this)([])}}])}(F);function Ze(e){return Ze="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ze(e)}function et(e,t){for(var r=0;r3&&void 0!==arguments[3]?arguments[3]:null;return{text:e[t],value:e[r],selected:e[r]==n}}},{key:"getOptionJsonFromObjectJson",value:function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=t[flagNameAttrOptionText],o=t[flagNameAttrOptionValue];return console.log({objectJson:t,keyText:n,keyValue:o}),e.getOptionJsonFromObjectJsonAndKeys(t,n,o,r)}}])}();function yt(e){return yt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},yt(e)}function dt(e,t){for(var r=0;r1&&void 0!==arguments[1]&&arguments[1];if(arguments.length>0&&void 0!==arguments[0]&&arguments[0]){var o=this.getLocalStoragePage()[flagFormFilters],i=this.getFormFilters(),a=l.convertForm2JSON(i);n.areEqualDicts(o,a)||this.callFilterTableContent(o)}else Et(t,"sharedInitialize",this,3)([]),this.hookupFilters(),this.hookupButtonsAddSaveCancel(),this.hookupTableMain(),T.hookup((function(){r?e.saveRecordsTableDirtySinglePageApp():e.saveRecordsTableDirty()}))}},{key:"hookupFilters",value:function(){if(this.constructor===t)throw new Error("Subclass of TableBasePage must implement method hookupFilters().")}},{key:"sharedHookupFilters",value:function(){this.hookupButtonApplyFilters()}},{key:"hookupFilterActive",value:function(){this.hookupFilter(flagActive)}},{key:"hookupFilter",value:function(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(e,r){return t.isDirtyFilter(r)},n=idFormFilters+" ."+e;this.hookupEventHandler("change",n,r)}},{key:"hookupButtonApplyFilters",value:function(){var e=this;this.hookupEventHandler("click",idButtonApplyFilters,(function(t,r){t.stopPropagation(),e.getAndLoadFilteredTableContent()}))}},{key:"getAndLoadFilteredTableContent",value:function(){var e=this.getFormFilters(),t=l.convertForm2JSON(e);this.leave(),this.callFilterTableContent(t).catch((function(e){return console.error("Error:",e)}))}},{key:"getFormFilters",value:function(){return document.querySelector(idFormFilters)}},{key:"callbackLoadTableContent",value:function(e){this.getTableMain().querySelector("tbody").querySelectorAll("tr").forEach((function(e){e.remove()}));var t=e.data[flagRows];!n.isEmpty(t)&&t.every((function(e){return e.hasOwnProperty("display_order")}))&&(t=t.sort((function(e,t){return e.display_order-t.display_order}))),t.forEach(this.loadRowTable.bind(this)),this.hookupTableMain()}},{key:"getTableMain",value:function(){return document.querySelector(idTableMain)}},{key:"loadRowTable",value:function(e){throw new Error("Subclass of TableBasePage must implement method loadRowTable().")}},{key:"getAndLoadFilteredTableContentSinglePageApp",value:function(){var e=this,t=this.getFormFilters(),r=l.convertForm2JSON(t);this.callFilterTableContent(r).then((function(t){console.log("Table data received:",t),e.callbackLoadTableContent(t)})).catch((function(e){return console.error("Error:",e)}))}},{key:"hookupButtonsAddSaveCancel",value:function(){this.hookupButtonAddRowTable(),this.hookupButtonSave(),this.hookupButtonCancel(),this.toggleShowButtonsSaveCancel(!1)}},{key:"saveRecordsTableDirty",value:function(){var e=this,t=this.getTableRecords(!0);if(0!=t.length){var r=this.getFormFilters(),n=l.getElementValueCurrent(document.querySelector(idTextareaConfirm));this.callSaveTableContent(t,r,n).then((function(t){t[flagStatus]==flagSuccess?(console.log("Records saved!"),console.log("Data received:",t),e.getAndLoadFilteredTableContent()):(console.log("error: ",t[flagMessage]),bt.show(t[flagMessage]))})).catch((function(e){return console.error("Error:",e)}))}else bt.show("No records to save")}},{key:"getTableRecords",value:function(){var e,t=this,r=arguments.length>0&&void 0!==arguments[0]&&arguments[0],n=this.getTableMain(),o=[];return n.querySelectorAll("tbody tr").forEach((function(n){r&&!n.classList.contains(flagDirty)||(e=t.getJsonRow(n),o.push(e))})),o}},{key:"getJsonRow",value:function(e){throw new Error("Subclass of TableBasePage must implement method getJsonRow().")}},{key:"saveRecordsTableDirtySinglePageApp",value:function(){var e=this,t=this.getTableRecords(!0);if(0!=t.length){var r=this.getFormFilters(),n=l.getElementValueCurrent(document.querySelector(idTextareaConfirm));this.callSaveTableContent(t,r,n).then((function(t){t[flagStatus]==flagSuccess?(console.log("Records saved!"),console.log("Data received:",t),e.callbackLoadTableContent(t)):(console.log("error: ",t[flagMessage]),bt.show(t[flagMessage]))})).catch((function(e){return console.error("Error:",e)}))}else bt.show("No records to save")}},{key:"hookupButtonCancel",value:function(){y.initialiseEventHandler(idFormFilters+" button."+flagCancel,flagInitialised,(function(e){e.addEventListener("click",(function(e){e.stopPropagation(),getAndLoadFilteredTableContent()})),e.classList.add(flagCollapsed)}))}},{key:"hookupButtonAddRowTable",value:function(){var e=this;this.hookupEventHandler("click",idFormFilters+" button."+flagAdd,(function(t,r){t.stopPropagation();var n=document.querySelector(idTableMain+" tbody"),o=_rowBlank.cloneNode(!0);o.classList.remove(flagInitialised),o.querySelectorAll("."+flagInitialised).forEach((function(e){e.classList.remove(flagInitialised)})),e.initialiseRowNew(o),n.appendChild(o),e.hookupTableMain()}))}},{key:"initialiseRowNew",value:function(e){throw new Error("Subclass of TableBasePage must implement method initialiseRowNew().")}},{key:"hookupTableMain",value:function(){var e=this;if(this.constructor===t)throw new Error("Must implement hookupTableMain() method.");null==_rowBlank&&y.initialiseEventHandler(idTableMain,flagInitialised,(function(t){e.cacheRowBlank()}))}},{key:"cacheRowBlank",value:function(){var e=idTableMain+" tbody tr."+flagRowNew,t=document.querySelector(e);console.log("row blank temp: ",t),_rowBlank=t.cloneNode(!0),document.querySelectorAll(e).forEach((function(e){e.remove()}))}},{key:"hookupSlidersDisplayOrderTable",value:function(){var e=idTableMain+" tbody tr td."+flagDisplayOrder+" input."+flagSlider+"."+flagDisplayOrder;this.hookupChangeHandlerTableCells(e)}},{key:"hookupChangeHandlerTableCells",value:function(e){var t=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(e,r){t.handleChangeElementCellTable(e,r)};this.hookupEventHandler("change",e,r)}},{key:"handleChangeElementCellTable",value:function(e,t){var r=l.getRowFromElement(t),n=l.getCellFromElement(t);console.log("td: ",n);var o=l.hasDirtyChildrenContainer(r),i=t.classList.contains(flagDirty),a=l.updateAndCheckIsElementDirty(t);if(console.log("isDirtyElement: ",a),console.log("wasDirtyElement: ",i),a!=i){l.handleDirtyElement(n,a);var u=l.hasDirtyChildrenContainer(r);if(console.log("isNowDirtyRow: ",u),console.log("wasDirtyRow: ",o),u!=o){l.handleDirtyElement(r,u);var c=this.getTableRecords(!0),s=c.length>0;console.log("dirty records:",c),console.log("existsDirtyRecord:",s),this.toggleShowButtonsSaveCancel(s)}}}},{key:"hookupChangeHandlerTableCellsWhenNotCollapsed",value:function(e){var t=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(e,r){r.classList.contains(flagCollapsed)||t.handleChangeElementCellTable(e,r)};this.hookupEventHandler("change",e,r)}},{key:"hookupTextareasCodeTable",value:function(){this.hookupChangeHandlerTableCells(idTableMain+" tbody tr td."+flagCode+" textarea")}},{key:"hookupTextareasNameTable",value:function(){this.hookupChangeHandlerTableCells(idTableMain+" tbody tr td."+flagName+" textarea")}},{key:"hookupTextareasDescriptionTable",value:function(){this.hookupChangeHandlerTableCells(idTableMain+" tbody tr td."+flagDescription+" textarea")}},{key:"hookupInputsActiveTable",value:function(){this.hookupChangeHandlerTableCells(idTableMain+" tbody tr td."+flagActive+' input[type="checkbox"]')}},{key:"hookupTdsAccessLevel",value:function(){var e=idTableMain+" tbody td."+flagAccessLevel;this.hookupTableCellDdlPreviews(e,vt.getListFromDict(accessLevels))}},{key:"hookupTableCellDdlPreviews",value:function(e,t){var r=this,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(e,t){r.hookupTableCellDdls(e,t)};this.hookupEventHandler("click",e,(function(o,i){r.handleClickTableCellDdlPreview(o,i,t,e,(function(e,t){n(e,t)}))}))}},{key:"hookupTableCellDdls",value:function(e){var t=this;this.hookupEventHandler("change",e,(function(e,r){t.handleChangeTableCellDdl(e,r)}))}},{key:"handleClickTableCellDdlPreview",value:function(e,t,r,n){var o=this,i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:function(e,t){o.hookupTableCellDdls(e,t)};if(!t.querySelector("select")){console.log("click table cell ddl preview");var a=t.cloneNode(!0);t.parentNode.replaceChild(a,t);var u=a.getAttribute(attrValueCurrent);a.innerHTML="";var c,s,f=document.createElement("select");l.setElementValuesCurrentAndPrevious(f,l.getElementAttributeValueCurrent(a)),console.log({optionObjectList:r,cellSelector:n}),r.forEach((function(e){c=ft.getOptionJsonFromObjectJson(e,u),s=l.createOption(c),f.appendChild(s)})),a.appendChild(f),i(n+" select")}}},{key:"handleChangeTableCellDdl",value:function(e,t){var r=l.getRowFromElement(t),n=l.getCellFromElement(t);console.log("td: ",n);var o=l.hasDirtyChildrenContainer(r),i=t.classList.contains(flagDirty),a=l.updateAndCheckIsElementDirty(t);if(console.log("isDirtyElement: ",a),console.log("wasDirtyElement: ",i),a!=i){l.handleDirtyElement(n,a);var u=t.options[t.selectedIndex];l.setElementAttributeValueCurrent(n,u.value);var c=l.hasDirtyChildrenContainer(r);if(console.log("isNowDirtyRow: ",c),console.log("wasDirtyRow: ",o),c!=o){l.handleDirtyElement(r,c);var s=this.getTableRecords(!0),f=s.length>0;console.log("dirty records:",s),console.log("existsDirtyRecord:",f),this.toggleShowButtonsSaveCancel(f)}}}},{key:"hookupTableCellDDlPreviewsWhenNotCollapsed",value:function(e,t){var r=this,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(e,t){r.hookupTableCellDdls(e,t)};this.hookupEventHandler("click",e,(function(o,i){var a=i.querySelector("div");a&&!a.classList.contains(flagCollapsed)&&r.handleClickTableCellDdlPreview(o,i,t,e,(function(e,t){n(e,t)}))}))}},{key:"leave",value:function(){if(this.constructor===t)throw new Error("Must implement leave() method.");Et(t,"leave",this,3)([]);var e=this.getFormFilters(),r={};r[flagFormFilters]=l.convertForm2JSON(e),this.setLocalStoragePage(r)}},{key:"toggleColumnHasClassnameFlag",value:function(e,t,r){var n=this.getTableMain(),o=n.querySelector("th."+e),i=o.classList.contains(r);if(t!=i){var a=n.querySelectorAll("td."+e);l.toggleElementHasClassnameFlag(o,t,r),a.forEach((function(e){l.toggleElementHasClassnameFlag(e,t,r)}))}}}],[{key:"isDirtyFilter",value:function(e){var t=l.updateAndCheckIsElementDirty(e);if(t){var r=document.querySelector(idTableMain+" tbody");r.querySelectorAll("tr").remove(),r.appendChild(document.createElement(' Press "Apply Filters" to refresh the table. '))}return t}}])}(F);function It(e){return It="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},It(e)}function Ft(e,t){var r="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!r){if(Array.isArray(e)||(r=function(e,t){if(e){if("string"==typeof e)return Lt(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?Lt(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0,o=function(){};return{s:o,n:function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,a=!0,u=!1;return{s:function(){r=r.call(e)},n:function(){var e=r.next();return a=e.done,e},e:function(e){u=!0,i=e},f:function(){try{a||null==r.return||r.return()}finally{if(u)throw i}}}}function Lt(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r",e))})),t.addEventListener("change",(function(e){loadPermutations()}))}));var r=document.querySelectorAll(idFilterIsOutOfStock);y.initialiseEventHandler(r,flagInitialised,(function(){r.addEventListener("change",(function(e){loadPermutations()}))}));var n=document.querySelectorAll(idFilterQuantityMin);y.initialiseEventHandler(n,flagInitialised,(function(){n.addEventListener("change",(function(e){loadPermutations()}))}));var o=document.querySelectorAll(idFilterQuantityMax);y.initialiseEventHandler(o,flagInitialised,(function(){o.addEventListener("change",(function(e){loadPermutations()}))}))}},{key:"loadPermutations",value:function(){var e=document.querySelectorAll(idFormFiltersPermutations),t={};t[keyForm]=convertForm2JSON(e),t.csrf_token=t[keyForm].csrf_token,console.log("ajaxData:"),console.log(t),ajaxJSONData("permutations",mapHashToController(hashPageStorePermutationsPost),t,callbackLoadPermutations,!1,{"X-CSRFToken":t.csrf_token})}},{key:"callbackLoadPermutations",value:function(e){console.log("ajax:"),console.log(e.data);var t,r,n,o=document.querySelectorAll(idTableMain);(t=o.querySelector("tbody")).querySelector("tr").remove(),$.each(e.data,(function(e,o){r=_rowBlank.cloneNode(!0),(r=document.querySelectorAll(r)).classList.remove(flagRowNew),console.log("applying data row: ",o),r.querySelector("td."+flagProductCategory+" select").val(o[attrIdProductCategory]),n=r.querySelector("td."+flagProduct+" select"),listProducts.forEach((function(e){e[attrIdProductCategory]==o[attrIdProductCategory]&&n.appendChild(document.createElement(" |
-
-
+ |
+ {% include 'components/store/_preview_DDL_product_category.html' %}
|
|
+ {#
{% include 'components/common/inputs/_textarea_product_variation_types.html' %}
|
+ #}
+
+
+ |
{{ product.name_access_level_required }}
|
diff --git a/templates/js/sections/store.js b/templates/js/sections/store.js
index 4559b15f..f581207b 100644
--- a/templates/js/sections/store.js
+++ b/templates/js/sections/store.js
@@ -7,7 +7,6 @@ var attrIdProductVariation = "{{ model.ATTR_ID_PRODUCT_VARIATION }}";
var attrIdProductVariationType = "{{ model.ATTR_ID_PRODUCT_VARIATION_TYPE }}";
var flagButtonBasketAdd = "{{ model.FLAG_BUTTON_BASKET_ADD }}";
var flagButtonBuyNow = "{{ model.FLAG_BUTTON_BUY_NOW }}";
-var flagProductCategory = "{{ model.FLAG_PRODUCT_CATEGORY }}";
var flagCostLocal = "{{ model.FLAG_COST_LOCAL }}";
var flagCountUnitMeasurementIntervalExpirationUnsealed = "{{ model.FLAG_COUNT_UNIT_MEASUREMENT_INTERVAL_EXPIRATION_UNSEALED }}";
var flagCountUnitMeasurementIntervalRecurrence = "{{ model.FLAG_COUNT_UNIT_MEASUREMENT_INTERVAL_RECURRENCE }}";
@@ -49,10 +48,14 @@ var flagUnitMeasurementIntervalExpirationUnsealed = "{{ model.FLAG_UNIT_MEASUREM
var flagUnitMeasurementIntervalRecurrence = "{{ model.FLAG_UNIT_MEASUREMENT_INTERVAL_RECURRENCE }}";
var flagUnitMeasurementQuantity = "{{ model.FLAG_UNIT_MEASUREMENT_QUANTITY }}";
var flagProductVariations = "{{ model.FLAG_PRODUCT_VARIATIONS }}";
+var hashGetStoreProduct = "{{ model.HASH_GET_STORE_PRODUCT }}";
var hashGetStoreProductCategory = "{{ model.HASH_GET_STORE_PRODUCT_CATEGORY }}";
var hashGetStoreProductPermutation = "{{ model.HASH_GET_STORE_PRODUCT_PERMUTATION }}";
+var hashGetStoreStockItem = "{{ model.HASH_GET_STORE_STOCK_ITEM }}";
+var hashSaveStoreProduct = "{{ model.HASH_SAVE_STORE_PRODUCT }}";
var hashSaveStoreProductCategory = "{{ model.HASH_SAVE_STORE_PRODUCT_CATEGORY }}";
var hashSaveStoreProductPermutation = "{{ model.HASH_SAVE_STORE_PRODUCT_PERMUTATION }}";
+var hashSaveStoreStockItem = "{{ model.HASH_SAVE_STORE_STOCK_ITEM }}";
var hashStoreBasketAdd = "{{ model.HASH_STORE_BASKET_ADD }}";
var hashStoreBasketDelete = "{{ model.HASH_STORE_BASKET_DELETE }}";
var hashStoreBasketEdit = "{{ model.HASH_STORE_BASKET_EDIT }}";
diff --git a/templates/pages/store/_products.html b/templates/pages/store/_products.html
index 235b3e63..d6fa338b 100644
--- a/templates/pages/store/_products.html
+++ b/templates/pages/store/_products.html
@@ -5,12 +5,12 @@
-->
-
+