feat(UI): Stock Items page added with getting, filtering, and saving data.
This commit is contained in:
24
README.md
24
README.md
@@ -14,3 +14,27 @@ python -m flask run
|
|||||||
|
|
||||||
host for local network:
|
host for local network:
|
||||||
python -m flask run --host=0.0.0.0
|
python -m flask run --host=0.0.0.0
|
||||||
|
|
||||||
|
|
||||||
|
files dedicated to each page:
|
||||||
|
CSS
|
||||||
|
page
|
||||||
|
HTML
|
||||||
|
page
|
||||||
|
row
|
||||||
|
JavaScript
|
||||||
|
page
|
||||||
|
api
|
||||||
|
router
|
||||||
|
MySQL
|
||||||
|
get
|
||||||
|
save
|
||||||
|
table
|
||||||
|
staging table
|
||||||
|
audit table
|
||||||
|
Python
|
||||||
|
business object
|
||||||
|
controller
|
||||||
|
datastore
|
||||||
|
form
|
||||||
|
model
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
111
app.log
111
app.log
@@ -1,46 +1,65 @@
|
|||||||
Traceback: Traceback (most recent call last):
|
Request: 127.0.0.1 GET http /store/stock_items?id_category=3&id_product=&is_out_of_stock=false&quantity_min=&quantity_max= Host: 127.0.0.1:5000
|
||||||
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()
|
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:131.0) Gecko/20100101 Firefox/131.0
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 882, in full_dispatch_request
|
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
|
||||||
rv = self.handle_user_exception(e)
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
Accept-Language: en-GB,en;q=0.5
|
||||||
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)))
|
Accept-Encoding: gzip, deflate, br, zstd
|
||||||
^^^^^^^^^^^^^^^^^^
|
|
||||||
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 880, in full_dispatch_request
|
Referer: http://127.0.0.1:5000/store/stock_items?id_category=3&id_product=3&is_out_of_stock=false&quantity_min=&quantity_max=
|
||||||
rv = self.dispatch_request()
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
Dnt: 1
|
||||||
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]
|
Connection: keep-alive
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\controllers\store\product.py", line 114, in products
|
Cookie: session=.eJytVlnPqzgS_SutSN1PnVz25ZOuZsgGJIEkhLC9ILBZzB6WLPTc_z4m3-2-_dCzSSOFYLtMnVOuclX9NguGPq1b1EXw2kXt7OO3GQgqP4Alqvyur9to9tG3Q_Trn5aH98bP1agMUDH7mEXwEbRwUSIIi6ivq65Effr3ZJIuQF3Ofp3FqO36KiixwpkZQfjCawj6YGjbqAIvH0ZxMBT97KMaiuItaqME1dVfCD4JkH-M_ckIAut9v__BsQIViiwQRBYSYsATYUAScRRPgJ3_ZuzfoxbFKIKzjzgouugtQRUoBhhB35LMH6ifdmJxNzQY6s_Gd0P73SDtd7vnl8nw2Td8Xl0b-32dRxWWg1gAbMCIPA0ZhuBogqZCigAEB4OQJ7kwZCkYEhyHKQ7f3RAAEHXdHxqi1y4NZYCOaJcHjooOq10Rlto0X2rZlTIIXVfRAwWOPqpZjQLFIICicYeXmHuO24cVTINRfeiZV3iZVx_lggkRS4IXm0LHqLUVm2FKd7UiFgtn617dFzzsYq1Rzr26GJ8usLan_Fjvjp4S3kxnpUgyw87l89Vlo-3TlTJ_v2eq_c7Ir-y-7kb_DC-I2SRjv_GsRD8YZbvpu7AW2uU6NIqIu7KR4kXD7gga1iSSw3wv1kbp1-d-wzV3F6zmNrKeCsk37E0E-gPUQxhc-tS3SjkOLTeu9sXa4q5ZtexW_mEfS-5yL9-qOIOsHDUKhGDeHQebvMQrD5zkKyqsjFyVjO3UaJNzohNJqIwAyJJUURgakRfZv_hldqiGuRdJr3oEFSuU0s1FibD3hbBORZvZjfd4GOLVSVyGYyfuHF7zGN3oLdZkD-yqY5e677rg8MwZP7mE5dgHQx1LOcvMx_MT1OeKJ-nt3k6s8C4sYihlxHlT6KlkeU8arNC51iQcBtGzQW3U-QEOQZKnBJ4UaI77sY5wUAgcQxDvW_AXUXK5jiqpI7VTK4MFK5VT88axVnhe9o03zSvrHjne1cgZJsx2d09JSCvfHrRtShqvnbjAyobA1tuw3PbeBX9QWjmkti9vxfaBbeShbBEhxY6hXRDBWzGbhvZ1Ai88BaagPA9Ylnvys4CyOACKbKCcSh5FpoH9GFxK7KeQBXKRQcV6fWKkBFSW4xEJdxyaFSi3lOsYKUCf4ek6Xgrl7eswXkdvrZdadia0Ncx1ExtLuYwuuy-d0lNtDRh9NJC3dokTrYn6OnnsKlUEMii9NVlDxXiA13U8X64vA-Gn1HN8Hf58FQotx1jllnCd3bgzd7Jnnwcgs9XEGTrLHPMqvK2YwukwM_WBufSaKeFne8X4nDaqnL6-DtqoMfbkiNLqXbvopuvp2QaN9eaHkmw82eg8x7iHld4HGP8sw_e-Q6nfw8uP7xzaK0BZlIFt5WrWlK79HL3L_-HKY3tcZ9KJeRHwFjnG08xJ50ylZuCkT3PEJ1VsOStPnbO9LS55w13LfEpBjeuc0THb0FqWUNq4YfUsmfgyU8BpJngd1y6ljzl1XGE_0xaaMDAWEayXgp5dGa1UWd3WmKNp5dq6SPVxiVxz8_BKq3zHBlW8ecEirUy7aU277o-bdONO53BVRzfzYpOAO6tqKLcydlrZTbwGHJfZO54yiIwcHi-K4WpKTXvYnx4FV1pmyVOqK1VFE2nHUXtOl-ICzTd519W2RUXkvXkMSJLofhWkdXTv6tNecCVkPG8X59CsvdMmlKvhUt5O7fa0fOmdq8DTQRt3FP-6w_acZE7S8HwzJKRGMZleWKvLvHavr7ZLU_VxN24A5_4BBu7QydSZXy2TU0EmIfNMLdY1IuuiNHWqMawEmqcSn7a-cpwvg7CshgHFxT60IYVW0m0jP4bLGvDpeLmC-W3r1KqrFkldtKaYWanVgKbjHXNfKQdWMh8rKSmgy0XQJtf9PeoFUeK0ZfUMVXtvnqBc7SFhioW-dLqWOfm0aD3sQLzKD8xTTG1PbY-7ka-OzjLMeOtCL4W56C0FV3N3hHhEp3lLJDh_daBupsqI_ysEf2raOkZF9NNnv_Dr7J2w_P713rOMghYXvc_ah6q4fte_ARfnWSJnr_6ma_YqvaDn7chTxnm0FFsKot0O3-_Z_9KC_IvSj1PqZ47lOF7kBJxQf0-6HE1-LnQdBkj7vuk-vnyB0X1ePYKcwgU7irlUQM9qMXSLd_cxQX3BWN8bg_9MqkIg_3ebpy11BSY5H25lXekdYuTjoE-SJcVusbhBoB-mRu0Pht0iaYN70Aftm87n8AtLQzqmcP_BQ5Zi-VhgYooHAcELPBNCjvlb95URiF_ar03yC_z61vUzLf1MbfEPwOqHfXj-qbLDowgumurtcTQ57O4kWpZr2VxQ1iE-5yUdcv5RVq3xHvYqlU8bh_C_6dWGBgY97sYmZ8wogmLmJDEnSZPgP2jqg2EXNC14s2_fvv0TX22jag.ZwjUoA.pitPRgpTPJyCaDMIr0TPpBG_lIc
|
||||||
return render_template('pages/store/_products.html', model = model)
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
Upgrade-Insecure-Requests: 1
|
||||||
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)
|
Sec-Fetch-Dest: document
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\templating.py", line 131, in _render
|
Sec-Fetch-Mode: navigate
|
||||||
rv = template.render(context)
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
Sec-Fetch-Site: same-origin
|
||||||
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\jinja2\environment.py", line 1304, in render
|
|
||||||
self.environment.handle_exception()
|
Sec-Fetch-User: ?1
|
||||||
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)
|
Sec-Gpc: 1
|
||||||
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' %}
|
Priority: u=0, i
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
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'
|
Request data: b''
|
||||||
{% include 'components/store/_row_product.html' %}
|
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
|
||||||
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
|
response = self.full_dispatch_request()
|
||||||
<td class="{{ model.FLAG_PRODUCT_CATEGORY }}" {{ model.ATTR_VALUE_CURRENT }}="{{ permutation.id_category }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ permutation.id_category }}">
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 882, in full_dispatch_request
|
||||||
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\jinja2\environment.py", line 487, in getattr
|
rv = self.handle_user_exception(e)
|
||||||
return getattr(obj, attribute)
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask_cors\extension.py", line 178, in wrapped_function
|
||||||
jinja2.exceptions.UndefinedError: 'permutation' is undefined
|
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\stock_item.py", line 45, in stock_items
|
||||||
|
return render_template('pages/store/_stock_items.html', model = model, datetime = datetime)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
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)
|
||||||
|
|||||||
81
app.log.1
81
app.log.1
@@ -1,4 +1,47 @@
|
|||||||
Exception on /store/products [GET]
|
Request: 127.0.0.1 GET http /store/stock_items?id_category=3&id_product=3&is_out_of_stock=false&quantity_min=&quantity_max= Host: 127.0.0.1:5000
|
||||||
|
|
||||||
|
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:131.0) Gecko/20100101 Firefox/131.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
|
||||||
|
|
||||||
|
Referer: http://127.0.0.1:5000/store/stock_items?id_category=3&id_product=&is_out_of_stock=false&quantity_min=&quantity_max=
|
||||||
|
|
||||||
|
Dnt: 1
|
||||||
|
|
||||||
|
Connection: keep-alive
|
||||||
|
|
||||||
|
Cookie: session=.eJytVlnPqzgS_SutSN1PnVz25ZOuZsgGJIEkhLC9ILBZzB6WLPTc_z4m3-2-_dCzSSOFYLtMnVOuclX9NguGPq1b1EXw2kXt7OO3GQgqP4Alqvyur9to9tG3Q_Trn5aH98bP1agMUDH7mEXwEbRwUSIIi6ivq65Effr3ZJIuQF3Ofp3FqO36KiixwpkZQfjCawj6YGjbqAIvH0ZxMBT97KMaiuItaqME1dVfCD4JkH-M_ckIAut9v__BsQIViiwQRBYSYsATYUAScRRPgJ3_ZuzfoxbFKIKzjzgouugtQRUoBhhB35LMH6ifdmJxNzQY6s_Gd0P73SDtd7vnl8nw2Td8Xl0b-32dRxWWg1gAbMCIPA0ZhuBogqZCigAEB4OQJ7kwZCkYEhyHKQ7f3RAAEHXdHxqi1y4NZYCOaJcHjooOq10Rlto0X2rZlTIIXVfRAwWOPqpZjQLFIICicYeXmHuO24cVTINRfeiZV3iZVx_lggkRS4IXm0LHqLUVm2FKd7UiFgtn617dFzzsYq1Rzr26GJ8usLan_Fjvjp4S3kxnpUgyw87l89Vlo-3TlTJ_v2eq_c7Ir-y-7kb_DC-I2SRjv_GsRD8YZbvpu7AW2uU6NIqIu7KR4kXD7gga1iSSw3wv1kbp1-d-wzV3F6zmNrKeCsk37E0E-gPUQxhc-tS3SjkOLTeu9sXa4q5ZtexW_mEfS-5yL9-qOIOsHDUKhGDeHQebvMQrD5zkKyqsjFyVjO3UaJNzohNJqIwAyJJUURgakRfZv_hldqiGuRdJr3oEFSuU0s1FibD3hbBORZvZjfd4GOLVSVyGYyfuHF7zGN3oLdZkD-yqY5e677rg8MwZP7mE5dgHQx1LOcvMx_MT1OeKJ-nt3k6s8C4sYihlxHlT6KlkeU8arNC51iQcBtGzQW3U-QEOQZKnBJ4UaI77sY5wUAgcQxDvW_AXUXK5jiqpI7VTK4MFK5VT88axVnhe9o03zSvrHjne1cgZJsx2d09JSCvfHrRtShqvnbjAyobA1tuw3PbeBX9QWjmkti9vxfaBbeShbBEhxY6hXRDBWzGbhvZ1Ai88BaagPA9Ylnvys4CyOACKbKCcSh5FpoH9GFxK7KeQBXKRQcV6fWKkBFSW4xEJdxyaFSi3lOsYKUCf4ek6Xgrl7eswXkdvrZdadia0Ncx1ExtLuYwuuy-d0lNtDRh9NJC3dokTrYn6OnnsKlUEMii9NVlDxXiA13U8X64vA-Gn1HN8Hf58FQotx1jllnCd3bgzd7Jnnwcgs9XEGTrLHPMqvK2YwukwM_WBufSaKeFne8X4nDaqnL6-DtqoMfbkiNLqXbvopuvp2QaN9eaHkmw82eg8x7iHld4HGP8sw_e-Q6nfw8uP7xzaK0BZlIFt5WrWlK79HL3L_-HKY3tcZ9KJeRHwFjnG08xJ50ylZuCkT3PEJ1VsOStPnbO9LS55w13LfEpBjeuc0THb0FqWUNq4YfUsmfgyU8BpJngd1y6ljzl1XGE_0xaaMDAWEayXgp5dGa1UWd3WmKNp5dq6SPVxiVxz8_BKq3zHBlW8ecEirUy7aU277o-bdONO53BVRzfzYpOAO6tqKLcydlrZTbwGHJfZO54yiIwcHi-K4WpKTXvYnx4FV1pmyVOqK1VFE2nHUXtOl-ICzTd519W2RUXkvXkMSJLofhWkdXTv6tNecCVkPG8X59CsvdMmlKvhUt5O7fa0fOmdq8DTQRt3FP-6w_acZE7S8HwzJKRGMZleWKvLvHavr7ZLU_VxN24A5_4BBu7QydSZXy2TU0EmIfNMLdY1IuuiNHWqMawEmqcSn7a-cpwvg7CshgHFxT60IYVW0m0jP4bLGvDpeLmC-W3r1KqrFkldtKaYWanVgKbjHXNfKQdWMh8rKSmgy0XQJtf9PeoFUeK0ZfUMVXtvnqBc7SFhioW-dLqWOfm0aD3sQLzKD8xTTG1PbY-7ka-OzjLMeOtCL4W56C0FV3N3hHhEp3lLJDh_daBupsqI_ysEf2raOkZF9NNnv_Dr7J2w_P713rOMghYXvc_ah6q4fte_ARfnWSJnr_6ma_YqvaDn7chTxnm0FFsKot0O3-_Z_9KC_IvSj1PqZ47lOF7kBJxQf0-6HE1-LnQdBkj7vuk-vnyB0X1ePYKcwgU7irlUQM9qMXSLd_cxQX3BWN8bg_9MqkIg_3ebpy11BSY5H25lXekdYuTjoE-SJcVusbhBoB-mRu0Pht0iaYN70Aftm87n8AtLQzqmcP_BQ5Zi-VhgYooHAcELPBNCjvlb95URiF_ar03yC_z61vUzLf1MbfEPwOqHfXj-qbLDowgumurtcTQ57O4kWpZr2VxQ1iE-5yUdcv5RVq3xHvYqlU8bh_C_6dWGBgY97sYmZ8wogmLmJDEnSZPgP2jqg2EXNC14s2_fvv0TX22jag.ZwjUoA.pitPRgpTPJyCaDMIr0TPpBG_lIc
|
||||||
|
|
||||||
|
Upgrade-Insecure-Requests: 1
|
||||||
|
|
||||||
|
Sec-Fetch-Dest: document
|
||||||
|
|
||||||
|
Sec-Fetch-Mode: navigate
|
||||||
|
|
||||||
|
Sec-Fetch-Site: same-origin
|
||||||
|
|
||||||
|
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)))
|
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
|
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 880, in full_dispatch_request
|
||||||
@@ -15,9 +58,9 @@ Traceback (most recent call last):
|
|||||||
^^^^^
|
^^^^^
|
||||||
NameError: name 'nself' is not defined. Did you mean: 'self'?
|
NameError: name 'nself' is not defined. Did you mean: 'self'?
|
||||||
|
|
||||||
File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\controllers\store\product.py", line 114, in products
|
Exception on /store/stock_items [GET]
|
||||||
return render_template('pages/store/_products.html', model = model)
|
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()
|
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
|
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 882, in full_dispatch_request
|
||||||
@@ -28,38 +71,20 @@ Traceback (most recent call last):
|
|||||||
^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^
|
||||||
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 880, in full_dispatch_request
|
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()
|
rv = self.dispatch_request()
|
||||||
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
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 865, in 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]
|
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\stock_item.py", line 45, in stock_items
|
File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\controllers\store\stock_item.py", line 45, in stock_items
|
||||||
return render_template('pages/store/_stock_items.html', model = model, datetime = datetime)
|
return render_template('pages/store/_stock_items.html', model = model, datetime = datetime)
|
||||||
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\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\templating.py", line 150, in render_template
|
||||||
return _render(app, template, context)
|
return _render(app, template, context)
|
||||||
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
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
<td class="{{ model.FLAG_PRODUCT_CATEGORY }}" {{ model.ATTR_VALUE_CURRENT }}="{{ permutation.id_category }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ permutation.id_category }}">
|
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\templating.py", line 131, in _render
|
||||||
rv = template.render(context)
|
rv = template.render(context)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\jinja2\environment.py", line 1304, in render
|
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\jinja2\environment.py", line 1304, in render
|
||||||
self.environment.handle_exception()
|
self.environment.handle_exception()
|
||||||
jinja2.exceptions.UndefinedError: 'permutation' is undefined
|
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)
|
raise rewrite_traceback_stack(source=source)
|
||||||
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
|
|
||||||
|
|
||||||
|
|||||||
109
app.log.2
109
app.log.2
@@ -1,58 +1,16 @@
|
|||||||
Exception on /store/products [GET]
|
Request: 127.0.0.1 GET http /store/stock_items?id_category=3&id_product=3&is_out_of_stock=false&quantity_min=&quantity_max= Host: 127.0.0.1:5000
|
||||||
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 <class 'business_objects.store.product.Product'> argument product. Type = <class 'business_objects.store.product.Product'>. 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:131.0) Gecko/20100101 Firefox/131.0
|
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:131.0) Gecko/20100101 Firefox/131.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: 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-Language: en-GB,en;q=0.5
|
||||||
|
|
||||||
|
Accept-Encoding: gzip, deflate, br, zstd
|
||||||
|
|
||||||
Referer: http://127.0.0.1:5000/store/stock_items?id_category=3&id_product=&is_out_of_stock=false&quantity_min=&quantity_max=
|
Referer: http://127.0.0.1:5000/store/stock_items?id_category=3&id_product=&is_out_of_stock=false&quantity_min=&quantity_max=
|
||||||
|
|
||||||
|
Dnt: 1
|
||||||
|
|
||||||
Connection: keep-alive
|
Connection: keep-alive
|
||||||
|
|
||||||
@@ -75,29 +33,36 @@ Traceback: Traceback (most recent call last):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Traceback: Traceback (most recent call last):
|
Request data: b''
|
||||||
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 1473, in wsgi_app
|
Traceback: Traceback (most recent call last):
|
||||||
response = self.full_dispatch_request()
|
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\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
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
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\stock_item.py", line 40, in stock_items
|
||||||
|
model = Model_View_Store_Stock_Item(form_filters)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\models\model_view_store_stock_item.py", line 89, in __init__
|
||||||
|
if product.id_category != self.form_filters.id_category.data and self.form_filters.id_category.data != '':
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
AttributeError: 'dict' object has no attribute 'id_category'
|
||||||
|
|
||||||
|
Exception on /store/stock_items [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)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|||||||
109
app.log.3
109
app.log.3
@@ -1,58 +1,16 @@
|
|||||||
Exception on /store/products [GET]
|
Request: 127.0.0.1 GET http /store/stock_items?id_category=3&id_product=3&is_out_of_stock=false&quantity_min=&quantity_max= Host: 127.0.0.1:5000
|
||||||
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 <class 'business_objects.store.product.Product'> argument product. Type = <class 'business_objects.store.product.Product'>. 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:131.0) Gecko/20100101 Firefox/131.0
|
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:131.0) Gecko/20100101 Firefox/131.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: 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-Language: en-GB,en;q=0.5
|
||||||
|
|
||||||
|
Accept-Encoding: gzip, deflate, br, zstd
|
||||||
|
|
||||||
Referer: http://127.0.0.1:5000/store/stock_items?id_category=3&id_product=&is_out_of_stock=false&quantity_min=&quantity_max=
|
Referer: http://127.0.0.1:5000/store/stock_items?id_category=3&id_product=&is_out_of_stock=false&quantity_min=&quantity_max=
|
||||||
|
|
||||||
|
Dnt: 1
|
||||||
|
|
||||||
Connection: keep-alive
|
Connection: keep-alive
|
||||||
|
|
||||||
@@ -75,29 +33,36 @@ Traceback: Traceback (most recent call last):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Traceback: Traceback (most recent call last):
|
Request data: b''
|
||||||
File "C:\Users\edwar\AppData\Local\Programs\Python\Python312\Lib\site-packages\flask\app.py", line 1473, in wsgi_app
|
Traceback: Traceback (most recent call last):
|
||||||
response = self.full_dispatch_request()
|
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\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
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
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\stock_item.py", line 40, in stock_items
|
||||||
|
model = Model_View_Store_Stock_Item(form_filters)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
File "C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\models\model_view_store_stock_item.py", line 89, in __init__
|
||||||
|
self.form_filters.import_values(filters_stock_item)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
AttributeError: 'Filters_Stock_Item' object has no attribute 'import_values'
|
||||||
|
|
||||||
|
Exception on /store/stock_items [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)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
97
business_objects/address.py
Normal file
97
business_objects/address.py
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
"""
|
||||||
|
Project: PARTS Website
|
||||||
|
Author: Edward Middleton-Smith
|
||||||
|
Precision And Research Technology Systems Limited
|
||||||
|
|
||||||
|
Technology: Business Objects
|
||||||
|
Feature: Address Business Object
|
||||||
|
|
||||||
|
Description:
|
||||||
|
Business object for address
|
||||||
|
"""
|
||||||
|
|
||||||
|
# internal
|
||||||
|
import lib.argument_validation as av
|
||||||
|
from business_objects.base import Base
|
||||||
|
from business_objects.region import Region
|
||||||
|
from extensions import db
|
||||||
|
# external
|
||||||
|
from typing import ClassVar
|
||||||
|
|
||||||
|
|
||||||
|
class Address(db.Model, Base):
|
||||||
|
FLAG_ADDRESS_LINE_1: ClassVar[str] = 'address_line_1'
|
||||||
|
FLAG_ADDRESS_LINE_2: ClassVar[str] = 'address_line_2'
|
||||||
|
FLAG_CITY: ClassVar[str] = 'city'
|
||||||
|
FLAG_COUNTY: ClassVar[str] = 'county'
|
||||||
|
NAME_ATTR_OPTION_VALUE: ClassVar[str] = Base.ATTR_ID_ADDRESS
|
||||||
|
NAME_ATTR_OPTION_TEXT: ClassVar[str] = Base.FLAG_POSTCODE
|
||||||
|
__tablename__ = 'Shop_Address'
|
||||||
|
id_address = db.Column(db.Integer, primary_key=True)
|
||||||
|
id_region = db.Column(db.Integer)
|
||||||
|
postcode = db.Column(db.String(20))
|
||||||
|
address_line_1 = db.Column(db.String(256))
|
||||||
|
address_line_2 = db.Column(db.String(256))
|
||||||
|
city = db.Column(db.String(256))
|
||||||
|
county = db.Column(db.String(256))
|
||||||
|
active = db.Column(db.Boolean)
|
||||||
|
|
||||||
|
# region = None
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
Base.__init__(self)
|
||||||
|
self.region = None
|
||||||
|
@classmethod
|
||||||
|
def from_DB_storage_location(cls, query_row):
|
||||||
|
address = cls()
|
||||||
|
address.id_address = query_row[2]
|
||||||
|
address.id_region = query_row[3]
|
||||||
|
return address
|
||||||
|
@classmethod
|
||||||
|
def from_DB_plant(cls, query_row):
|
||||||
|
address = cls()
|
||||||
|
address.id_address = query_row[1]
|
||||||
|
address.id_region = query_row[2]
|
||||||
|
@classmethod
|
||||||
|
def from_DB_stock_item(cls, query_row):
|
||||||
|
address = cls()
|
||||||
|
address.id_address = query_row[6]
|
||||||
|
address.id_region = query_row[7]
|
||||||
|
return address
|
||||||
|
def __repr__(self):
|
||||||
|
return f'''
|
||||||
|
{self.ATTR_ID_ADDRESS}: {self.id_address}
|
||||||
|
{self.FLAG_REGION}: {self.region}
|
||||||
|
{self.FLAG_POSTCODE}: {self.postcode}
|
||||||
|
{self.FLAG_ADDRESS_LINE_1}: {self.address_line_1}
|
||||||
|
{self.FLAG_ADDRESS_LINE_2}: {self.address_line_2}
|
||||||
|
{self.FLAG_CITY}: {self.city}
|
||||||
|
{self.FLAG_COUNTY}: {self.county}
|
||||||
|
{self.FLAG_ACTIVE}: {self.active}
|
||||||
|
'''
|
||||||
|
def to_json(self):
|
||||||
|
return {
|
||||||
|
**self.get_shared_json_attributes(self),
|
||||||
|
self.ATTR_ID_ADDRESS: self.id_address,
|
||||||
|
self.FLAG_REGION: self.region.to_json(),
|
||||||
|
self.FLAG_POSTCODE: self.postcode,
|
||||||
|
self.FLAG_ADDRESS_LINE_1: self.address_line_1,
|
||||||
|
self.FLAG_ADDRESS_LINE_2: self.address_line_2,
|
||||||
|
self.FLAG_CITY: self.city,
|
||||||
|
self.FLAG_COUNTY: self.county,
|
||||||
|
self.FLAG_ACTIVE: 1 if av.input_bool(self.active, self.FLAG_ACTIVE, f'{self.__class__.__name__}.to_json') else 0
|
||||||
|
}
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, json):
|
||||||
|
print(f'{cls.__name__}.from_json: {json}')
|
||||||
|
address = cls()
|
||||||
|
address.id_address = json[cls.ATTR_ID_ADDRESS],
|
||||||
|
address.region = Region.from_json(json[cls.FLAG_REGION]),
|
||||||
|
address.postcode = json[cls.FLAG_POSTCODE],
|
||||||
|
address.address_line_1 = json[cls.FLAG_ADDRESS_LINE_1],
|
||||||
|
address.address_line_2 = json.get(cls.FLAG_ADDRESS_LINE_2, ''),
|
||||||
|
address.city = json[cls.FLAG_CITY],
|
||||||
|
address.county = json[cls.FLAG_COUNTY],
|
||||||
|
address.active = json[cls.FLAG_ACTIVE]
|
||||||
|
return address
|
||||||
@@ -19,15 +19,20 @@ from typing import ClassVar
|
|||||||
|
|
||||||
class Base():
|
class Base():
|
||||||
ATTR_ID_ACCESS_LEVEL: ClassVar[str] = 'id_access_level'
|
ATTR_ID_ACCESS_LEVEL: ClassVar[str] = 'id_access_level'
|
||||||
|
ATTR_ID_ADDRESS: ClassVar[str] = 'id_address'
|
||||||
ATTR_ID_CURRENCY: ClassVar[str] = 'id_currency'
|
ATTR_ID_CURRENCY: ClassVar[str] = 'id_currency'
|
||||||
ATTR_ID_DELIVERY_REGION: ClassVar[str] = 'id_delivery_region'
|
ATTR_ID_REGION: ClassVar[str] = 'id_region'
|
||||||
ATTR_ID_USER: ClassVar[str] = 'id_user'
|
ATTR_ID_USER: ClassVar[str] = 'id_user'
|
||||||
|
ATTR_ID_USER_MANAGER: ClassVar[str] = 'id_user_manager'
|
||||||
FLAG_ACCESS_LEVEL_REQUIRED: ClassVar[str] = 'access_level_required'
|
FLAG_ACCESS_LEVEL_REQUIRED: ClassVar[str] = 'access_level_required'
|
||||||
FLAG_ACTIVE: ClassVar[str] = 'active'
|
FLAG_ACTIVE: ClassVar[str] = 'active'
|
||||||
|
FLAG_ADDRESS: ClassVar[str] = 'address'
|
||||||
FLAG_CAN_ADMIN: ClassVar[str] = 'can_admin'
|
FLAG_CAN_ADMIN: ClassVar[str] = 'can_admin'
|
||||||
FLAG_CAN_EDIT: ClassVar[str] = 'can_edit'
|
FLAG_CAN_EDIT: ClassVar[str] = 'can_edit'
|
||||||
FLAG_CAN_VIEW: ClassVar[str] = 'can_view'
|
FLAG_CAN_VIEW: ClassVar[str] = 'can_view'
|
||||||
FLAG_CODE: ClassVar[str] = 'code'
|
FLAG_CODE: ClassVar[str] = 'code'
|
||||||
|
FLAG_CURRENCY: ClassVar[str] = 'currency'
|
||||||
|
FLAG_CURRENCY_COST: ClassVar[str] = 'currency_cost'
|
||||||
FLAG_DESCRIPTION: ClassVar[str] = 'description'
|
FLAG_DESCRIPTION: ClassVar[str] = 'description'
|
||||||
FLAG_DISPLAY_ORDER: ClassVar[str] = 'display_order'
|
FLAG_DISPLAY_ORDER: ClassVar[str] = 'display_order'
|
||||||
FLAG_GUID: ClassVar[str] = 'guid'
|
FLAG_GUID: ClassVar[str] = 'guid'
|
||||||
@@ -38,10 +43,14 @@ class Base():
|
|||||||
FLAG_NAME_ATTR_OPTION_VALUE: ClassVar[str] = 'NAME_ATTR_OPTION_VALUE'
|
FLAG_NAME_ATTR_OPTION_VALUE: ClassVar[str] = 'NAME_ATTR_OPTION_VALUE'
|
||||||
FLAG_NAME_SINGULAR: ClassVar[str] = 'name_singular'
|
FLAG_NAME_SINGULAR: ClassVar[str] = 'name_singular'
|
||||||
FLAG_NAME_PLURAL: ClassVar[str] = 'name_plural'
|
FLAG_NAME_PLURAL: ClassVar[str] = 'name_plural'
|
||||||
|
FLAG_POSTCODE: ClassVar[str] = 'postcode'
|
||||||
FLAG_PRIORITY: ClassVar[str] = 'priority'
|
FLAG_PRIORITY: ClassVar[str] = 'priority'
|
||||||
|
FLAG_REGION: ClassVar[str] = 'region'
|
||||||
FLAG_ROWS: ClassVar[str] = 'rows'
|
FLAG_ROWS: ClassVar[str] = 'rows'
|
||||||
FLAG_SYMBOL: ClassVar[str] = 'symbol'
|
FLAG_SYMBOL: ClassVar[str] = 'symbol'
|
||||||
FLAG_URL: ClassVar[str] = 'url'
|
FLAG_URL: ClassVar[str] = 'url'
|
||||||
|
FLAG_VALUE_LOCAL_VAT_EXCL: ClassVar[str] = 'value_local_vat_excl'
|
||||||
|
FLAG_VALUE_LOCAL_VAT_INCL: ClassVar[str] = 'value_local_vat_incl'
|
||||||
NAME_ATTR_OPTION_TEXT: ClassVar[str] = 'name-attribute-option-text'
|
NAME_ATTR_OPTION_TEXT: ClassVar[str] = 'name-attribute-option-text'
|
||||||
NAME_ATTR_OPTION_VALUE: ClassVar[str] = 'name-attribute-option-value'
|
NAME_ATTR_OPTION_VALUE: ClassVar[str] = 'name-attribute-option-value'
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,15 @@ class Currency(db.Model, Store_Base):
|
|||||||
v_arg_type = 'class attribute'
|
v_arg_type = 'class attribute'
|
||||||
currency = cls()
|
currency = cls()
|
||||||
return currency
|
return currency
|
||||||
|
@classmethod
|
||||||
|
def from_DB_stock_item(cls, query_row):
|
||||||
|
_m = 'Currency.from_DB_get_many_stock_item'
|
||||||
|
v_arg_type = 'class attribute'
|
||||||
|
currency = cls()
|
||||||
|
currency.id_currency = query_row[12]
|
||||||
|
currency.code = query_row[13]
|
||||||
|
currency.symbol = query_row[14]
|
||||||
|
return currency
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'''
|
return f'''
|
||||||
id: {self.id_currency}
|
id: {self.id_currency}
|
||||||
@@ -30,11 +30,8 @@ class Get_Many_Parameters_Base(BaseModel, metaclass=ABCMeta):
|
|||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_default(cls): # , id_user
|
def get_default(cls): # , id_user
|
||||||
pass
|
pass
|
||||||
"""
|
|
||||||
@abstractmethod
|
|
||||||
def to_json(self):
|
def to_json(self):
|
||||||
pass
|
return self.dict()
|
||||||
"""
|
|
||||||
"""
|
"""
|
||||||
@classmethod
|
@classmethod
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
|||||||
82
business_objects/region.py
Normal file
82
business_objects/region.py
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
"""
|
||||||
|
Project: PARTS Website
|
||||||
|
Author: Edward Middleton-Smith
|
||||||
|
Precision And Research Technology Systems Limited
|
||||||
|
|
||||||
|
Technology: Business Objects
|
||||||
|
Feature: Address Region Business Object
|
||||||
|
|
||||||
|
Description:
|
||||||
|
Business object for address region
|
||||||
|
"""
|
||||||
|
|
||||||
|
# internal
|
||||||
|
import lib.argument_validation as av
|
||||||
|
from business_objects.base import Base
|
||||||
|
from extensions import db
|
||||||
|
# external
|
||||||
|
from typing import ClassVar
|
||||||
|
|
||||||
|
|
||||||
|
class Region(db.Model, Base):
|
||||||
|
NAME_ATTR_OPTION_VALUE: ClassVar[str] = Base.ATTR_ID_REGION
|
||||||
|
NAME_ATTR_OPTION_TEXT: ClassVar[str] = Base.FLAG_NAME
|
||||||
|
__tablename__ = 'Shop_Region'
|
||||||
|
id_region = db.Column(db.Integer, primary_key=True)
|
||||||
|
code = db.Column(db.String(50))
|
||||||
|
name = db.Column(db.String(200))
|
||||||
|
active = db.Column(db.Boolean)
|
||||||
|
|
||||||
|
# region = None
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
Base.__init__(self)
|
||||||
|
self.region = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_DB_stock_item(cls, query_row):
|
||||||
|
plant = cls()
|
||||||
|
plant.id_region = query_row[7]
|
||||||
|
return plant
|
||||||
|
def __repr__(self):
|
||||||
|
return f'''
|
||||||
|
{self.ATTR_ID_REGION}: {self.id_region}
|
||||||
|
{self.FLAG_CODE}: {self.code}
|
||||||
|
{self.FLAG_NAME}: {self.name}
|
||||||
|
{self.FLAG_ACTIVE}: {self.active}
|
||||||
|
'''
|
||||||
|
def to_json(self):
|
||||||
|
return {
|
||||||
|
**self.get_shared_json_attributes(self),
|
||||||
|
self.ATTR_ID_REGION: self.id_region,
|
||||||
|
self.FLAG_CODE: self.code,
|
||||||
|
self.FLAG_NAME: self.name,
|
||||||
|
self.FLAG_ACTIVE: 1 if av.input_bool(self.active, self.FLAG_ACTIVE, f'{self.__class__.__name__}.to_json') else 0
|
||||||
|
}
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, json):
|
||||||
|
print(f'{cls.__name__}.from_json: {json}')
|
||||||
|
plant = cls()
|
||||||
|
plant.id_region = json[cls.ATTR_ID_REGION]
|
||||||
|
plant.code = json[cls.FLAG_CODE]
|
||||||
|
plant.name = json[cls.FLAG_NAME]
|
||||||
|
plant.active = json[cls.FLAG_ACTIVE]
|
||||||
|
return plant
|
||||||
|
@classmethod
|
||||||
|
def from_DB_get_many_product_catalogue(cls, query_row):
|
||||||
|
region = cls()
|
||||||
|
region.id_region = query_row[0]
|
||||||
|
region.name = query_row[1]
|
||||||
|
region.code = query_row[2]
|
||||||
|
# self.display_order = query_row[3]
|
||||||
|
return region
|
||||||
|
@classmethod
|
||||||
|
def from_DB_region(cls, query_row):
|
||||||
|
region = cls()
|
||||||
|
region.id_region = query_row[0]
|
||||||
|
region.code = query_row[1]
|
||||||
|
region.name = query_row[2]
|
||||||
|
region.active = av.input_bool(query_row[3], cls.FLAG_ACTIVE, f'{cls.__name__}.from_DB_region')
|
||||||
|
region.display_order = query_row[4]
|
||||||
|
return region
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -22,7 +22,7 @@ class Delivery_Option():
|
|||||||
delay_max: int
|
delay_max: int
|
||||||
quantity_min: float
|
quantity_min: float
|
||||||
quantity_max: float
|
quantity_max: float
|
||||||
regions: list # [Enum_Delivery_Region]
|
regions: list # [Enum_Region]
|
||||||
cost: float
|
cost: float
|
||||||
|
|
||||||
def __new__(cls, name, delay_min, delay_max, quantity_min, quantity_max, regions, cost):
|
def __new__(cls, name, delay_min, delay_max, quantity_min, quantity_max, regions, cost):
|
||||||
@@ -33,7 +33,7 @@ class Delivery_Option():
|
|||||||
av.val_int(delay_max, 'delay_max', _m, 0, v_arg_type = v_arg_type)
|
av.val_int(delay_max, 'delay_max', _m, 0, v_arg_type = v_arg_type)
|
||||||
av.val_float(quantity_min, 'quantity_min', _m, 0, v_arg_type = v_arg_type)
|
av.val_float(quantity_min, 'quantity_min', _m, 0, v_arg_type = v_arg_type)
|
||||||
av.val_float(quantity_max, 'quantity_max', _m, 0, v_arg_type = v_arg_type)
|
av.val_float(quantity_max, 'quantity_max', _m, 0, v_arg_type = v_arg_type)
|
||||||
av.val_list_instances(regions, 'regions', _m, Enum_Delivery_Region, v_arg_type = v_arg_type)
|
av.val_list_instances(regions, 'regions', _m, Enum_Region, v_arg_type = v_arg_type)
|
||||||
av.val_float(cost, 'cost', _m, 0, v_arg_type = v_arg_type)
|
av.val_float(cost, 'cost', _m, 0, v_arg_type = v_arg_type)
|
||||||
return super(Delivery_Option, cls).__new__(cls)
|
return super(Delivery_Option, cls).__new__(cls)
|
||||||
|
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
"""
|
|
||||||
Project: PARTS Website
|
|
||||||
Author: Edward Middleton-Smith
|
|
||||||
Precision And Research Technology Systems Limited
|
|
||||||
|
|
||||||
Technology: Business Objects
|
|
||||||
Feature: Delivery Region Business Object
|
|
||||||
|
|
||||||
Description:
|
|
||||||
Business object for delivery region
|
|
||||||
"""
|
|
||||||
|
|
||||||
# internal
|
|
||||||
from business_objects.store.store_base import Store_Base
|
|
||||||
from extensions import db
|
|
||||||
from lib import argument_validation as av
|
|
||||||
# external
|
|
||||||
from enum import Enum
|
|
||||||
from typing import ClassVar
|
|
||||||
|
|
||||||
|
|
||||||
class Enum_Delivery_Region(Enum):
|
|
||||||
UK = 0
|
|
||||||
|
|
||||||
class Delivery_Region(db.Model, Store_Base):
|
|
||||||
NAME_ATTR_OPTION_VALUE: ClassVar[str] = Store_Base.ATTR_ID_DELIVERY_REGION
|
|
||||||
NAME_ATTR_OPTION_TEXT: ClassVar[str] = Store_Base.FLAG_NAME
|
|
||||||
|
|
||||||
id_region = db.Column(db.Integer, primary_key=True)
|
|
||||||
"""
|
|
||||||
id_category = db.Column(db.Integer)
|
|
||||||
id_product = db.Column(db.Integer)
|
|
||||||
id_discount = db.Column(db.Integer)
|
|
||||||
"""
|
|
||||||
code = db.Column(db.String(50))
|
|
||||||
name = db.Column(db.String(200))
|
|
||||||
active = db.Column(db.Boolean)
|
|
||||||
display_order = db.Column(db.Integer)
|
|
||||||
"""
|
|
||||||
def __new__(cls, id, id_category, id_product, id_discount, code, name, display_order):
|
|
||||||
_m = 'Delivery_Region.__new__'
|
|
||||||
v_arg_type = 'class attribute'
|
|
||||||
av.val_int(id, 'id', _m, 0, v_arg_type = v_arg_type)
|
|
||||||
av.val_int(id_category, 'id_category', _m, 0, v_arg_type=v_arg_type)
|
|
||||||
av.val_int(id_product, 'id_product', _m, 0, v_arg_type = v_arg_type)
|
|
||||||
av.val_int(id_discount, 'id_discount', _m, v_arg_type = v_arg_type)
|
|
||||||
av.val_str(code, 'code', _m, max_len = 50, v_arg_type = v_arg_type)
|
|
||||||
av.val_str(name, 'name', _m, max_len = 100, v_arg_type = v_arg_type)
|
|
||||||
av.val_int(display_order, 'display_order', _m, v_arg_type = v_arg_type)
|
|
||||||
return super(Delivery_Region, cls).__new__(cls)
|
|
||||||
|
|
||||||
def __init__(self, id, id_category, id_product, id_discount, code, name, display_order):
|
|
||||||
self.id_region = id
|
|
||||||
self.id_category = id_category
|
|
||||||
self.id_product = id_product
|
|
||||||
self.id_discount = id_discount
|
|
||||||
self.name = name
|
|
||||||
self.code = code
|
|
||||||
self.display_order = display_order
|
|
||||||
"""
|
|
||||||
@classmethod
|
|
||||||
def from_DB_get_many_product_catalogue(cls, query_row):
|
|
||||||
region = cls()
|
|
||||||
region.id_region = query_row[0]
|
|
||||||
region.name = query_row[1]
|
|
||||||
region.code = query_row[2]
|
|
||||||
# self.display_order = query_row[3]
|
|
||||||
return region
|
|
||||||
@classmethod
|
|
||||||
def from_DB_region(cls, query_row):
|
|
||||||
region = cls()
|
|
||||||
region.id_region = query_row[0]
|
|
||||||
region.code = query_row[1]
|
|
||||||
region.name = query_row[2]
|
|
||||||
region.active = av.input_bool(query_row[3], cls.FLAG_ACTIVE, f'{cls.__name__}.from_DB_region')
|
|
||||||
region.display_order = query_row[4]
|
|
||||||
return region
|
|
||||||
def __repr__(self):
|
|
||||||
return f'''
|
|
||||||
id: {self.id_region}
|
|
||||||
name: {self.name}
|
|
||||||
code: {self.code}
|
|
||||||
active: {self.active}
|
|
||||||
display_order: {self.display_order}
|
|
||||||
'''
|
|
||||||
def to_json(self):
|
|
||||||
return {
|
|
||||||
**self.get_shared_json_attributes(self),
|
|
||||||
self.ATTR_ID_REGION: self.id_region,
|
|
||||||
self.FLAG_CODE: self.code,
|
|
||||||
self.FLAG_NAME: self.name,
|
|
||||||
self.FLAG_ACTIVE: self.active,
|
|
||||||
self.FLAG_DISPLAY_ORDER: self.display_order
|
|
||||||
}
|
|
||||||
@staticmethod
|
|
||||||
def from_json(json_region):
|
|
||||||
region = Delivery_Region()
|
|
||||||
region.id_region = json_region[Delivery_Region.ATTR_ID_REGION]
|
|
||||||
region.code = json_region[Delivery_Region.FLAG_CODE]
|
|
||||||
region.name = json_region[Delivery_Region.FLAG_NAME]
|
|
||||||
region.active = json_region[Delivery_Region.FLAG_ACTIVE]
|
|
||||||
region.display_order = json_region[Delivery_Region.FLAG_DISPLAY_ORDER]
|
|
||||||
return region
|
|
||||||
92
business_objects/store/plant.py
Normal file
92
business_objects/store/plant.py
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
"""
|
||||||
|
Project: PARTS Website
|
||||||
|
Author: Edward Middleton-Smith
|
||||||
|
Precision And Research Technology Systems Limited
|
||||||
|
|
||||||
|
Technology: Business Objects
|
||||||
|
Feature: Plant Business Object
|
||||||
|
|
||||||
|
Description:
|
||||||
|
Business object for plant
|
||||||
|
"""
|
||||||
|
|
||||||
|
# internal
|
||||||
|
import lib.argument_validation as av
|
||||||
|
from business_objects.address import Address
|
||||||
|
from business_objects.store.store_base import Store_Base
|
||||||
|
from extensions import db
|
||||||
|
# external
|
||||||
|
from typing import ClassVar
|
||||||
|
|
||||||
|
|
||||||
|
class Plant(db.Model, Store_Base):
|
||||||
|
NAME_ATTR_OPTION_VALUE: ClassVar[str] = Store_Base.ATTR_ID_PLANT
|
||||||
|
NAME_ATTR_OPTION_TEXT: ClassVar[str] = Store_Base.FLAG_NAME
|
||||||
|
__tablename__ = 'Shop_Plant'
|
||||||
|
id_plant = db.Column(db.Integer, primary_key=True)
|
||||||
|
code = db.Column(db.String(50))
|
||||||
|
name = db.Column(db.String(255))
|
||||||
|
id_address = db.Column(db.Integer)
|
||||||
|
id_user_manager = db.Column(db.Integer)
|
||||||
|
active = db.Column(db.Boolean)
|
||||||
|
|
||||||
|
# address = None
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
Store_Base.__init__(self)
|
||||||
|
self.address = None
|
||||||
|
@classmethod
|
||||||
|
def from_DB_storage_location(cls, query_row):
|
||||||
|
plant = cls()
|
||||||
|
plant.id_plant = query_row[1]
|
||||||
|
plant.id_address = query_row[2]
|
||||||
|
plant.address = Address.from_DB_storage_location(query_row)
|
||||||
|
return plant
|
||||||
|
@classmethod
|
||||||
|
def from_DB_plant(cls, query_row):
|
||||||
|
plant = cls()
|
||||||
|
plant.id_plant = query_row[0]
|
||||||
|
plant.id_address = query_row[1]
|
||||||
|
plant.address = Address.from_DB_plant(query_row)
|
||||||
|
plant.code = query_row[4]
|
||||||
|
plant.name = query_row[5]
|
||||||
|
plant.active = query_row[6]
|
||||||
|
return plant
|
||||||
|
@classmethod
|
||||||
|
def from_DB_stock_item(cls, query_row):
|
||||||
|
plant = cls()
|
||||||
|
plant.id_plant = query_row[5]
|
||||||
|
plant.code = query_row[10]
|
||||||
|
plant.name = query_row[11]
|
||||||
|
return plant
|
||||||
|
def __repr__(self):
|
||||||
|
return f'''
|
||||||
|
{self.ATTR_ID_PLANT}: {self.id_plant}
|
||||||
|
{self.FLAG_CODE}: {self.code}
|
||||||
|
{self.FLAG_NAME}: {self.name}
|
||||||
|
{self.FLAG_ADDRESS}: {self.address}
|
||||||
|
{self.ATTR_ID_USER_MANAGER}: {self.id_user_manager}
|
||||||
|
{self.FLAG_ACTIVE}: {self.active}
|
||||||
|
'''
|
||||||
|
def to_json(self):
|
||||||
|
return {
|
||||||
|
**self.get_shared_json_attributes(self),
|
||||||
|
self.ATTR_ID_PLANT: self.id_plant,
|
||||||
|
self.FLAG_CODE: self.code,
|
||||||
|
self.FLAG_NAME: self.name,
|
||||||
|
self.FLAG_ADDRESS: self.address.to_json(),
|
||||||
|
self.ATTR_ID_USER_MANAGER: self.id_user_manager,
|
||||||
|
self.FLAG_ACTIVE: 1 if av.input_bool(self.active, self.FLAG_ACTIVE, f'{self.__class__.__name__}.to_json') else 0
|
||||||
|
}
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, json):
|
||||||
|
print(f'{cls.__name__}.from_json: {json}')
|
||||||
|
plant = cls()
|
||||||
|
plant.id_plant = json[cls.ATTR_ID_PLANT],
|
||||||
|
plant.code = json[cls.FLAG_CODE],
|
||||||
|
plant.name = json[cls.FLAG_NAME],
|
||||||
|
plant.address = Address.from_json(json[cls.FLAG_ADDRESS]),
|
||||||
|
plant.id_user_manager = json[cls.ATTR_ID_USER_MANAGER],
|
||||||
|
plant.active = json[cls.FLAG_ACTIVE]
|
||||||
|
return plant
|
||||||
@@ -175,7 +175,7 @@ class Product(SQLAlchemy_ABC, Store_Base):
|
|||||||
if self.variation_trees[index_tree].is_equal(variation_tree):
|
if self.variation_trees[index_tree].is_equal(variation_tree):
|
||||||
found_variation_tree_match = True
|
found_variation_tree_match = True
|
||||||
break
|
break
|
||||||
if not found_variation_tree_match:
|
if not found_variation_tree_match and variation_tree is not None:
|
||||||
self.variation_trees.append(variation_tree)
|
self.variation_trees.append(variation_tree)
|
||||||
def from_DB_Stripe_product(query_row):
|
def from_DB_Stripe_product(query_row):
|
||||||
permutation = Product_Permutation.from_DB_Stripe_product(query_row)
|
permutation = Product_Permutation.from_DB_Stripe_product(query_row)
|
||||||
@@ -374,6 +374,13 @@ class Product(SQLAlchemy_ABC, Store_Base):
|
|||||||
text_input += tree.get_text_input_types()
|
text_input += tree.get_text_input_types()
|
||||||
return text_input
|
return text_input
|
||||||
"""
|
"""
|
||||||
|
def get_csv_ids_permutation(self):
|
||||||
|
csv = ''
|
||||||
|
for permutation in self.permutations:
|
||||||
|
if csv != '':
|
||||||
|
csv += ','
|
||||||
|
csv += str(permutation.id_permutation)
|
||||||
|
return csv
|
||||||
|
|
||||||
|
|
||||||
class Parameters_Product(Get_Many_Parameters_Base):
|
class Parameters_Product(Get_Many_Parameters_Base):
|
||||||
@@ -482,7 +489,7 @@ class Parameters_Product(Get_Many_Parameters_Base):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def from_form_filters_product_permutation(form):
|
def from_form_filters_product_permutation(form):
|
||||||
# if not (form is Filters_Product_Permutation): raise ValueError(f'Invalid form type: {type(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_Permutation)
|
# av.val_instance(form, 'form', 'Parameters_Product.from_form', Filters_Product_Permutation)
|
||||||
has_category_filter = not (form.id_category.data == '0' or form.id_category.data == '')
|
has_category_filter = not (form.id_category.data == '0' or form.id_category.data == '')
|
||||||
has_product_filter = not (form.id_product.data == '0' or form.id_product.data == '')
|
has_product_filter = not (form.id_product.data == '0' or form.id_product.data == '')
|
||||||
get_permutations_stock_below_min = av.input_bool(form.is_out_of_stock.data, "is_out_of_stock", "Parameters_Product.from_form")
|
get_permutations_stock_below_min = av.input_bool(form.is_out_of_stock.data, "is_out_of_stock", "Parameters_Product.from_form")
|
||||||
@@ -491,11 +498,11 @@ class Parameters_Product(Get_Many_Parameters_Base):
|
|||||||
get_all_product_category = not has_category_filter,
|
get_all_product_category = not has_category_filter,
|
||||||
get_inactive_product_category = False,
|
get_inactive_product_category = False,
|
||||||
# get_first_product_category_only = False,
|
# get_first_product_category_only = False,
|
||||||
ids_product_category = form.id_category.data,
|
ids_product_category = form.id_category.data if form.id_category.data is not None else '',
|
||||||
get_all_product = not has_product_filter,
|
get_all_product = not has_product_filter,
|
||||||
get_inactive_product = False,
|
get_inactive_product = False,
|
||||||
# get_first_product_only = False,
|
# get_first_product_only = False,
|
||||||
ids_product = form.id_product.data,
|
ids_product = form.id_product.data if form.id_product.data is not None else '',
|
||||||
get_all_permutation = not get_permutations_stock_below_min,
|
get_all_permutation = not get_permutations_stock_below_min,
|
||||||
get_inactive_permutation = False,
|
get_inactive_permutation = False,
|
||||||
# get_first_permutation_only = False,
|
# get_first_permutation_only = False,
|
||||||
@@ -601,6 +608,9 @@ class Parameters_Product(Get_Many_Parameters_Base):
|
|||||||
ids_image = '',
|
ids_image = '',
|
||||||
get_products_quantity_stock_below_min = False
|
get_products_quantity_stock_below_min = False
|
||||||
)
|
)
|
||||||
|
@classmethod
|
||||||
|
def from_filters_stock_item(cls, filters_stock_item):
|
||||||
|
return cls.from_form_filters_product_permutation(filters_stock_item)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
class Parameters_Product(Get_Many_Parameters_Base):
|
class Parameters_Product(Get_Many_Parameters_Base):
|
||||||
|
|||||||
@@ -242,6 +242,11 @@ class Product_Category(SQLAlchemy_ABC, Store_Base):
|
|||||||
'value': self.id_category,
|
'value': self.id_category,
|
||||||
'text': self.name
|
'text': self.name
|
||||||
}
|
}
|
||||||
|
def get_csv_ids_permutation(self):
|
||||||
|
list_ids = []
|
||||||
|
for product in self.products:
|
||||||
|
list_ids += product.get_csv_ids_permutation()
|
||||||
|
return list_ids
|
||||||
"""
|
"""
|
||||||
class Filters_Product_Category(BaseModel, Store_Base):
|
class Filters_Product_Category(BaseModel, Store_Base):
|
||||||
ids_product_category: str
|
ids_product_category: str
|
||||||
@@ -433,6 +438,11 @@ class Product_Category_Container(Store_Base):
|
|||||||
if column.name not in ['created_on', 'created_by']
|
if column.name not in ['created_on', 'created_by']
|
||||||
}
|
}
|
||||||
return self.to_object_with_missing_attributes(excluded_attributes)
|
return self.to_object_with_missing_attributes(excluded_attributes)
|
||||||
|
def get_csv_ids_permutation(self):
|
||||||
|
list_ids = []
|
||||||
|
for category in self.categories:
|
||||||
|
list_ids += category.get_csv_ids_permutation()
|
||||||
|
return ','.join(list_ids)
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ Business object for product permutation
|
|||||||
import lib.argument_validation as av
|
import lib.argument_validation as av
|
||||||
from lib import data_types
|
from lib import data_types
|
||||||
from forms.forms import Form_Basket_Add, Form_Basket_Edit
|
from forms.forms import Form_Basket_Add, Form_Basket_Edit
|
||||||
from business_objects.store.currency import Currency
|
from business_objects.currency import Currency
|
||||||
from business_objects.store.delivery_option import Delivery_Option
|
from business_objects.store.delivery_option import Delivery_Option
|
||||||
from business_objects.store.discount import Discount
|
from business_objects.store.discount import Discount
|
||||||
from business_objects.store.image import Image
|
from business_objects.store.image import Image
|
||||||
@@ -309,6 +309,7 @@ class Product_Permutation(db.Model, Store_Base):
|
|||||||
'value': self.id_permutation,
|
'value': self.id_permutation,
|
||||||
'text': self.get_name_variations()
|
'text': self.get_name_variations()
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
return
|
return
|
||||||
def get_name_variations(self):
|
def get_name_variations(self):
|
||||||
@@ -317,19 +318,14 @@ class Product_Permutation(db.Model, Store_Base):
|
|||||||
return len(self.prices) > 0
|
return len(self.prices) > 0
|
||||||
def get_price(self):
|
def get_price(self):
|
||||||
return self.prices[0]
|
return self.prices[0]
|
||||||
def get_price_local_VAT_incl(self):
|
|
||||||
price = self.get_price()
|
|
||||||
return price.value_local_VAT_incl
|
|
||||||
def get_price_local_VAT_excl(self):
|
|
||||||
price = self.get_price()
|
|
||||||
return price.value_local_VAT_excl
|
|
||||||
|
|
||||||
def output_lead_time(self):
|
|
||||||
return '1 day' if self.latency_manufacture_days == 1 else f'{self.latency_manufacture_days} days'
|
|
||||||
|
|
||||||
def output_delivery_date(self):
|
def output_delivery_date(self):
|
||||||
return (datetime.now() + timedelta(days=self.latency_manufacture_days)).strftime('%A, %d %B %Y')
|
return (datetime.now() + timedelta(days=self.latency_manufacture_days)).strftime('%A, %d %B %Y')
|
||||||
|
|
||||||
|
"""
|
||||||
|
def output_lead_time(self):
|
||||||
|
return '1 day' if self.latency_manufacture_days == 1 else f'{self.latency_manufacture_days} days'
|
||||||
|
|
||||||
def output_price(self, is_included_VAT):
|
def output_price(self, is_included_VAT):
|
||||||
if self.is_unavailable_in_currency_or_region:
|
if self.is_unavailable_in_currency_or_region:
|
||||||
return 'Not available in currency and region'
|
return 'Not available in currency and region'
|
||||||
@@ -341,33 +337,14 @@ class Product_Permutation(db.Model, Store_Base):
|
|||||||
return f'{price.symbol_currency} {locale.format_string("%d", price.value_local_VAT_incl, grouping=True)}'
|
return f'{price.symbol_currency} {locale.format_string("%d", price.value_local_VAT_incl, grouping=True)}'
|
||||||
else:
|
else:
|
||||||
return f'{price.symbol_currency} {locale.format_string("%d", price.value_local_VAT_excl, grouping=True)}'
|
return f'{price.symbol_currency} {locale.format_string("%d", price.value_local_VAT_excl, grouping=True)}'
|
||||||
def output_currency(self):
|
"""
|
||||||
if not self.is_available:
|
|
||||||
return ''
|
|
||||||
"""
|
|
||||||
price = self.get_price()
|
|
||||||
return price.code_currency
|
|
||||||
"""
|
|
||||||
return self.code_currency_cost if self.symbol_currency_cost == '' else self.symbol_currency_cost
|
|
||||||
def output_variations(self):
|
def output_variations(self):
|
||||||
if not self.has_variations: return ''
|
if not self.has_variations: return ''
|
||||||
return '\n'.join([f'{variation.name_variation_type}: {variation.name_variation}' for variation in self.variations])
|
return '\n'.join([f'{variation.name_variation_type}: {variation.name_variation}' for variation in self.variations])
|
||||||
def output_variations_jsonify(self):
|
def output_variations_jsonify(self):
|
||||||
if not self.has_variations: return ''
|
if not self.has_variations: return ''
|
||||||
return ','.join([f'{variation.id_type}: {variation.id_variation}' for variation in self.variations])
|
return ','.join([f'{variation.id_type}: {variation.id_variation}' for variation in self.variations])
|
||||||
"""
|
|
||||||
def output_price_VAT_incl(self):
|
|
||||||
locale.setlocale(locale.LC_ALL, '')
|
|
||||||
return locale.format_string("%d", self.price_GBP_VAT_incl, grouping=True)
|
|
||||||
def output_price_VAT_excl(self):
|
|
||||||
locale.setlocale(locale.LC_ALL, '')
|
|
||||||
return locale.format_string("%d", self.price_GBP_VAT_excl, grouping=True)
|
|
||||||
def add_form_basket_add(self):
|
|
||||||
self.form_basket_add = None
|
|
||||||
|
|
||||||
def add_form_basket_edit(self):
|
|
||||||
self.form_basket_edit = None
|
|
||||||
"""
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'''Product_Permutation
|
return f'''Product_Permutation
|
||||||
id_permutation: {self.id_permutation}
|
id_permutation: {self.id_permutation}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ Business object for product price
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# internal
|
# internal
|
||||||
from business_objects.store.currency import Currency
|
from business_objects.currency import Currency
|
||||||
from business_objects.store.delivery_region import Delivery_Region
|
from business_objects.region import Region
|
||||||
from business_objects.store.store_base import Store_Base
|
from business_objects.store.store_base import Store_Base
|
||||||
from extensions import db
|
from extensions import db
|
||||||
# external
|
# external
|
||||||
@@ -22,8 +22,6 @@ from typing import ClassVar
|
|||||||
class Product_Price(db.Model, Store_Base):
|
class Product_Price(db.Model, Store_Base):
|
||||||
NAME_ATTR_OPTION_VALUE: ClassVar[str] = Store_Base.ATTR_ID_PRODUCT_PRICE
|
NAME_ATTR_OPTION_VALUE: ClassVar[str] = Store_Base.ATTR_ID_PRODUCT_PRICE
|
||||||
NAME_ATTR_OPTION_TEXT = Store_Base.FLAG_TEXT
|
NAME_ATTR_OPTION_TEXT = Store_Base.FLAG_TEXT
|
||||||
FLAG_VALUE_LOCAL_VAT_INCL: ClassVar[str] = 'value-local-vat-incl'
|
|
||||||
FLAG_VALUE_LOCAL_VAT_EXCL: ClassVar[str] = 'value-local-vat-excl'
|
|
||||||
|
|
||||||
id_price = db.Column(db.Integer, primary_key=True)
|
id_price = db.Column(db.Integer, primary_key=True)
|
||||||
id_permutation = db.Column(db.Integer)
|
id_permutation = db.Column(db.Integer)
|
||||||
@@ -87,7 +85,7 @@ class Product_Price(db.Model, Store_Base):
|
|||||||
self.ATTR_ID_PRODUCT: self.id_product,
|
self.ATTR_ID_PRODUCT: self.id_product,
|
||||||
self.ATTR_ID_PRODUCT_CATEGORY: self.id_category,
|
self.ATTR_ID_PRODUCT_CATEGORY: self.id_category,
|
||||||
self.FLAG_CURRENCY: self.currency.to_json(),
|
self.FLAG_CURRENCY: self.currency.to_json(),
|
||||||
# Delivery_Region.ATTR_ID_DELIVERY_REGION: self.id_region,
|
# Region.ATTR_ID_REGION_DELIVERY: self.id_region,
|
||||||
self.FLAG_VALUE_LOCAL_VAT_INCL: self.value_local_VAT_incl,
|
self.FLAG_VALUE_LOCAL_VAT_INCL: self.value_local_VAT_incl,
|
||||||
self.FLAG_VALUE_LOCAL_VAT_EXCL: self.value_local_VAT_excl,
|
self.FLAG_VALUE_LOCAL_VAT_EXCL: self.value_local_VAT_excl,
|
||||||
self.FLAG_DISPLAY_ORDER: self.display_order
|
self.FLAG_DISPLAY_ORDER: self.display_order
|
||||||
@@ -101,7 +99,7 @@ class Product_Price(db.Model, Store_Base):
|
|||||||
price.id_product = json[cls.ATTR_ID_PRODUCT]
|
price.id_product = json[cls.ATTR_ID_PRODUCT]
|
||||||
price.id_category = json[cls.ATTR_ID_PRODUCT_CATEGORY]
|
price.id_category = json[cls.ATTR_ID_PRODUCT_CATEGORY]
|
||||||
price.currency = Currency.from_json(json)
|
price.currency = Currency.from_json(json)
|
||||||
# price.id_region = json[Delivery_Region.ATTR_ID_DELIVERY_REGION]
|
# price.id_region = json[Region.ATTR_ID_REGION_DELIVERY]
|
||||||
price.value_local_VAT_incl = json[cls.FLAG_VALUE_LOCAL_VAT_INCL]
|
price.value_local_VAT_incl = json[cls.FLAG_VALUE_LOCAL_VAT_INCL]
|
||||||
price.value_local_VAT_excl = json[cls.FLAG_VALUE_LOCAL_VAT_EXCL]
|
price.value_local_VAT_excl = json[cls.FLAG_VALUE_LOCAL_VAT_EXCL]
|
||||||
price.display_order = json[cls.FLAG_DISPLAY_ORDER]
|
price.display_order = json[cls.FLAG_DISPLAY_ORDER]
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ class Product_Variation_Tree():
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_json_str(cls, json_str):
|
def from_json_str(cls, json_str):
|
||||||
variations = []
|
variations = []
|
||||||
|
if json_str is None or json_str == '': return None
|
||||||
for json_variation in json_str.split(','):
|
for json_variation in json_str.split(','):
|
||||||
parts = json_variation.split(':')
|
parts = json_variation.split(':')
|
||||||
if len(parts) != 2: continue
|
if len(parts) != 2: continue
|
||||||
|
|||||||
@@ -13,13 +13,15 @@ import lib.argument_validation as av
|
|||||||
from lib import data_types
|
from lib import data_types
|
||||||
from forms.store.stock_item import Filters_Stock_Item
|
from forms.store.stock_item import Filters_Stock_Item
|
||||||
from business_objects.db_base import Get_Many_Parameters_Base
|
from business_objects.db_base import Get_Many_Parameters_Base
|
||||||
from business_objects.store.product_price import Product_Price
|
from business_objects.currency import Currency
|
||||||
# from business_objects.discount import Discount
|
# from business_objects.discount import Discount
|
||||||
|
from business_objects.store.product_variation_tree import Product_Variation_Tree
|
||||||
|
from business_objects.store.storage_location import Storage_Location
|
||||||
from business_objects.store.store_base import Store_Base
|
from business_objects.store.store_base import Store_Base
|
||||||
from extensions import db
|
from extensions import db
|
||||||
# external
|
# external
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import ClassVar
|
from typing import ClassVar, Optional
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
@@ -34,21 +36,19 @@ class Stock_Item(db.Model, Store_Base):
|
|||||||
FLAG_DATE_UNSEALED: ClassVar[str] = 'date_unsealed'
|
FLAG_DATE_UNSEALED: ClassVar[str] = 'date_unsealed'
|
||||||
FLAG_IS_CONSUMED: ClassVar[str] = 'is_consumed'
|
FLAG_IS_CONSUMED: ClassVar[str] = 'is_consumed'
|
||||||
FLAG_IS_SEALED: ClassVar[str] = 'is_sealed'
|
FLAG_IS_SEALED: ClassVar[str] = 'is_sealed'
|
||||||
FLAG_VALUE_LOCAL_VAT_EXCL_COST: ClassVar[str] = f'{Product_Price.FLAG_VALUE_LOCAL_VAT_EXCL}_cost'
|
|
||||||
FLAG_VALUE_LOCAL_VAT_INCL_COST: ClassVar[str] = f'{Product_Price.FLAG_VALUE_LOCAL_VAT_INCL}_cost'
|
|
||||||
|
|
||||||
id_stock = db.Column(db.Integer, primary_key=True)
|
id_stock = db.Column(db.Integer, primary_key=True)
|
||||||
id_permutation = db.Column(db.Integer)
|
id_permutation = db.Column(db.Integer)
|
||||||
id_product = db.Column(db.Integer)
|
id_product = db.Column(db.Integer)
|
||||||
id_category = db.Column(db.Integer)
|
id_category = db.Column(db.Integer)
|
||||||
# name_category = db.Column(db.String(255))
|
id_location_storage = db.Column(db.Integer)
|
||||||
# name_product = db.Column(db.String(255))
|
id_plant = db.Column(db.Integer)
|
||||||
|
id_region = db.Column(db.Integer)
|
||||||
|
id_currency_cost = db.Column(db.Integer)
|
||||||
|
cost_local_VAT_excl = db.Column(db.Float)
|
||||||
|
cost_local_VAT_incl = db.Column(db.Float)
|
||||||
date_purchased = db.Column(db.DateTime)
|
date_purchased = db.Column(db.DateTime)
|
||||||
date_received = db.Column(db.DateTime)
|
date_received = db.Column(db.DateTime)
|
||||||
id_location_storage = db.Column(db.Integer)
|
|
||||||
id_currency_cost = db.Column(db.Integer)
|
|
||||||
cost_local_VAT_incl = db.Column(db.Float)
|
|
||||||
cost_local_VAT_excl = db.Column(db.Float)
|
|
||||||
is_sealed = db.Column(db.Boolean)
|
is_sealed = db.Column(db.Boolean)
|
||||||
date_unsealed = db.Column(db.DateTime)
|
date_unsealed = db.Column(db.DateTime)
|
||||||
date_expiration = db.Column(db.DateTime)
|
date_expiration = db.Column(db.DateTime)
|
||||||
@@ -60,10 +60,15 @@ class Stock_Item(db.Model, Store_Base):
|
|||||||
can_edit = db.Column(db.Boolean)
|
can_edit = db.Column(db.Boolean)
|
||||||
can_admin = db.Column(db.Boolean)
|
can_admin = db.Column(db.Boolean)
|
||||||
"""
|
"""
|
||||||
|
# variation_tree: Product_Variation_Tree = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
Store_Base.__init__(self)
|
Store_Base.__init__(self)
|
||||||
|
self.currency_cost = None
|
||||||
|
self.storage_location = None
|
||||||
|
self.variation_tree = None
|
||||||
|
self.has_variations = False
|
||||||
|
|
||||||
def from_DB_stock_item(query_row):
|
def from_DB_stock_item(query_row):
|
||||||
_m = 'Product.from_DB_stock_item'
|
_m = 'Product.from_DB_stock_item'
|
||||||
@@ -73,21 +78,20 @@ class Stock_Item(db.Model, Store_Base):
|
|||||||
stock_item.id_permutation = query_row[1]
|
stock_item.id_permutation = query_row[1]
|
||||||
stock_item.id_product = query_row[2]
|
stock_item.id_product = query_row[2]
|
||||||
stock_item.id_category = query_row[3]
|
stock_item.id_category = query_row[3]
|
||||||
# stock_item.name_category = query_row[4]
|
stock_item.id_location_storage = query_row[4]
|
||||||
# stock_item.name_product = query_row[5]
|
stock_item.storage_location = Storage_Location.from_DB_stock_item(query_row)
|
||||||
stock_item.date_purchased = query_row[4]
|
stock_item.id_currency_cost = query_row[12]
|
||||||
stock_item.date_received = query_row[5]
|
stock_item.currency_cost = Currency.from_DB_stock_item(query_row)
|
||||||
stock_item.id_location_storage = query_row[6]
|
stock_item.cost_local_VAT_excl = query_row[15]
|
||||||
# stock_item.name_location_storage = query_row[9]
|
stock_item.cost_local_VAT_incl = query_row[16]
|
||||||
stock_item.id_currency_cost = query_row[7]
|
stock_item.date_purchased = query_row[17]
|
||||||
stock_item.cost_local_VAT_incl = query_row[8]
|
stock_item.date_received = query_row[18]
|
||||||
stock_item.cost_local_VAT_excl = query_row[9]
|
stock_item.is_sealed = av.input_bool(query_row[19], "is_sealed", _m, v_arg_type=v_arg_type)
|
||||||
stock_item.is_sealed = av.input_bool(query_row[10], "is_sealed", _m, v_arg_type=v_arg_type)
|
stock_item.date_unsealed = query_row[20]
|
||||||
stock_item.date_unsealed = query_row[11]
|
stock_item.date_expiration = query_row[21]
|
||||||
stock_item.date_expiration = query_row[12]
|
stock_item.is_consumed = av.input_bool(query_row[22], "is_consumed", _m, v_arg_type=v_arg_type)
|
||||||
stock_item.is_consumed = av.input_bool(query_row[13], "is_consumed", _m, v_arg_type=v_arg_type)
|
stock_item.date_consumed = query_row[23]
|
||||||
stock_item.date_consumed = query_row[14]
|
stock_item.active = av.input_bool(query_row[24], "active", _m, v_arg_type=v_arg_type)
|
||||||
stock_item.active = av.input_bool(query_row[15], "active", _m, v_arg_type=v_arg_type)
|
|
||||||
"""
|
"""
|
||||||
stock_item.can_view = av.input_bool(query_row[24], "can_view", _m, v_arg_type=v_arg_type)
|
stock_item.can_view = av.input_bool(query_row[24], "can_view", _m, v_arg_type=v_arg_type)
|
||||||
stock_item.can_edit = av.input_bool(query_row[25], "can_edit", _m, v_arg_type=v_arg_type)
|
stock_item.can_edit = av.input_bool(query_row[25], "can_edit", _m, v_arg_type=v_arg_type)
|
||||||
@@ -99,96 +103,55 @@ class Stock_Item(db.Model, Store_Base):
|
|||||||
def from_json(cls, json):
|
def from_json(cls, json):
|
||||||
stock_item = cls()
|
stock_item = cls()
|
||||||
stock_item.id_stock = json[cls.ATTR_ID_STOCK_ITEM]
|
stock_item.id_stock = json[cls.ATTR_ID_STOCK_ITEM]
|
||||||
stock_item.id_permutation = json[cls.ATTR_ID_PRODUCT_PERMUTATION]
|
stock_item.id_permutation = json.get(cls.ATTR_ID_PRODUCT_PERMUTATION, 0)
|
||||||
stock_item.id_product = json[cls.ATTR_ID_PRODUCT]
|
stock_item.id_product = json[cls.ATTR_ID_PRODUCT]
|
||||||
stock_item.id_category = json[cls.ATTR_ID_PRODUCT_CATEGORY]
|
stock_item.id_category = json[cls.ATTR_ID_PRODUCT_CATEGORY]
|
||||||
|
print(f'json: {json}\nhalf stock item: {stock_item}')
|
||||||
|
stock_item.variation_tree = Product_Variation_Tree.from_json_str(json[cls.FLAG_PRODUCT_VARIATIONS])
|
||||||
stock_item.date_purchased = json[cls.FLAG_DATE_PURCHASED]
|
stock_item.date_purchased = json[cls.FLAG_DATE_PURCHASED]
|
||||||
stock_item.date_received = json[cls.FLAG_DATE_RECEIVED]
|
stock_item.date_received = json[cls.FLAG_DATE_RECEIVED]
|
||||||
stock_item.id_location_storage = json[cls.ATTR_ID_LOCATION_STORAGE]
|
stock_item.id_location_storage = json[cls.ATTR_ID_STORAGE_LOCATION]
|
||||||
stock_item.id_currency_cost = json[cls.ATTR_ID_CURRENCY_COST]
|
stock_item.id_currency_cost = json[cls.ATTR_ID_CURRENCY_COST]
|
||||||
stock_item.cost_local_VAT_incl = json[cls.FLAG_VALUE_LOCAL_VAT_INCL_COST]
|
stock_item.cost_local_VAT_excl = json[cls.FLAG_COST_LOCAL_VAT_EXCL]
|
||||||
stock_item.cost_local_VAT_excl = json[cls.FLAG_VALUE_LOCAL_VAT_EXCL_COST]
|
stock_item.cost_local_VAT_incl = json[cls.FLAG_COST_LOCAL_VAT_INCL]
|
||||||
stock_item.is_sealed = json[cls.FLAG_IS_SEALED]
|
stock_item.is_sealed = json[cls.FLAG_IS_SEALED]
|
||||||
stock_item.date_unsealed = json[cls.FLAG_DATE_UNSEALED]
|
stock_item.date_unsealed = json[cls.FLAG_DATE_UNSEALED]
|
||||||
stock_item.date_expiration = json[cls.FLAG_DATE_EXPIRATION]
|
stock_item.date_expiration = json[cls.FLAG_DATE_EXPIRATION]
|
||||||
stock_item.is_consumed = json[cls.FLAG_IS_CONSUMED]
|
stock_item.is_consumed = json[cls.FLAG_IS_CONSUMED]
|
||||||
stock_item.date_consumed = json[cls.FLAG_DATE_CONSUMED]
|
stock_item.date_consumed = json[cls.FLAG_DATE_CONSUMED]
|
||||||
stock_item.active = json[cls.FLAG_ACTIVE]
|
stock_item.active = json[cls.FLAG_ACTIVE]
|
||||||
"""
|
|
||||||
stock_item.can_view = json[cls.FLAG_CAN_VIEW]
|
|
||||||
stock_item.can_edit = json[cls.FLAG_CAN_EDIT]
|
|
||||||
stock_item.can_admin = json[cls.FLAG_CAN_ADMIN]
|
|
||||||
"""
|
|
||||||
return stock_item
|
return stock_item
|
||||||
"""
|
|
||||||
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
|
|
||||||
|
|
||||||
def output_lead_time(self):
|
|
||||||
return self.get_permutation_selected().output_lead_time()
|
|
||||||
def output_delivery_date(self):
|
|
||||||
return self.get_permutation_selected().output_delivery_date()
|
|
||||||
def output_price(self, is_included_VAT):
|
|
||||||
return self.get_permutation_selected().output_price(is_included_VAT)
|
|
||||||
def output_price_VAT_incl(self):
|
|
||||||
return self.get_permutation_selected().output_price(True)
|
|
||||||
def output_price_VAT_excl(self):
|
|
||||||
return self.get_permutation_selected().output_price(False)
|
|
||||||
def get_price_local(self, is_included_VAT):
|
|
||||||
if is_included_VAT:
|
|
||||||
return self.get_price_local_VAT_incl()
|
|
||||||
else:
|
|
||||||
return self.get_price_local_VAT_excl()
|
|
||||||
def get_price_local_VAT_incl(self):
|
|
||||||
return self.get_permutation_selected().get_price_local_VAT_incl()
|
|
||||||
def get_price_local_VAT_excl(self):
|
|
||||||
return self.get_permutation_selected().get_price_local_VAT_excl()
|
|
||||||
def get_quantity_min(self):
|
|
||||||
return self.get_permutation_selected().quantity_min
|
|
||||||
def get_id_permutation(self):
|
|
||||||
return self.get_permutation_selected().id_permutation
|
|
||||||
def get_image_from_index(self, index_image):
|
|
||||||
return self.get_permutation_selected().images[index_image]
|
|
||||||
def get_name(self):
|
|
||||||
return self.get_permutation_selected().name
|
|
||||||
def get_description(self):
|
|
||||||
return self.get_permutation_selected().description
|
|
||||||
def output_currency(self):
|
|
||||||
return self.get_permutation_selected().get_price().symbol_currency
|
|
||||||
def add_form_basket_add(self):
|
|
||||||
self.form_basket_add = None
|
|
||||||
|
|
||||||
def add_form_basket_edit(self):
|
|
||||||
self.form_basket_edit = None
|
|
||||||
"""
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'''Product
|
return f'''Stock Item
|
||||||
|
id_stock: {self.id_stock}
|
||||||
|
id_permutation: {self.id_permutation}
|
||||||
id_product: {self.id_product}
|
id_product: {self.id_product}
|
||||||
id_category: {self.id_category}
|
id_category: {self.id_category}
|
||||||
name: {self.name}
|
variations: {self.variation_tree.to_preview_str() if self.variation_tree is not None else 'None'}
|
||||||
display_order: {self.display_order}
|
storage_location: {self.storage_location}
|
||||||
can_view: {self.can_view}
|
currency: {self.currency_cost}
|
||||||
can_edit: {self.can_edit}
|
cost_local_VAT_excl: {self.cost_local_VAT_excl}
|
||||||
can_admin: {self.can_admin}
|
cost_local_VAT_incl: {self.cost_local_VAT_incl}
|
||||||
has_variations: {self.has_variations}
|
date_purchased: {self.date_purchased}
|
||||||
permutations: {self.permutations}
|
date_received: {self.date_received}
|
||||||
variation trees: {self.variation_trees}
|
is_sealed: {self.is_sealed}
|
||||||
|
date_unsealed: {self.date_unsealed}
|
||||||
|
date_expiration: {self.date_expiration}
|
||||||
|
is_consumed: {self.is_consumed}
|
||||||
|
date_consumed: {self.date_consumed}
|
||||||
|
active: {self.active}
|
||||||
'''
|
'''
|
||||||
def to_json(self):
|
def to_json(self):
|
||||||
return {
|
return {
|
||||||
**self.get_shared_json_attributes(self),
|
**self.get_shared_json_attributes(self),
|
||||||
self.ATTR_ID_PRODUCT: {self.id_product},
|
self.ATTR_ID_STOCK_ITEM: self.id_stock,
|
||||||
self.ATTR_ID_PRODUCT_CATEGORY: {self.id_category},
|
self.ATTR_ID_PRODUCT_PERMUTATION: self.id_permutation,
|
||||||
self.FLAG_NAME: {self.name},
|
self.ATTR_ID_PRODUCT: self.id_product,
|
||||||
self.FLAG_DISPLAY_ORDER: {self.display_order},
|
self.ATTR_ID_PRODUCT_CATEGORY: self.id_category,
|
||||||
self.FLAG_CAN_VIEW: {self.can_view},
|
self.FLAG_STORAGE_LOCATION: self.storage_location.to_json(),
|
||||||
self.FLAG_CAN_EDIT: {self.can_edit},
|
self.FLAG_CURRENCY_COST: self.currency_cost.to_json(),
|
||||||
self.FLAG_CAN_ADMIN: {self.can_admin},
|
self.FLAG_COST_LOCAL_VAT_EXCL: self.cost_local_VAT_excl,
|
||||||
self.FLAG_HAS_VARIATIONS: {self.has_variations},
|
self.FLAG_COST_LOCAL_VAT_INCL: self.cost_local_VAT_incl,
|
||||||
self.FLAG_PRODUCT_PERMUTATION: {self.permutations},
|
|
||||||
self.FLAG_PRODUCT_VARIATION_TREES: {self.variation_trees},
|
|
||||||
}
|
}
|
||||||
def has_permutations(self):
|
def has_permutations(self):
|
||||||
return len(self.permutations) > 0
|
return len(self.permutations) > 0
|
||||||
@@ -224,12 +187,11 @@ class Parameters_Stock_Item(Get_Many_Parameters_Base):
|
|||||||
a_ids_region_storage: str
|
a_ids_region_storage: str
|
||||||
a_get_all_plant_storage: bool
|
a_get_all_plant_storage: bool
|
||||||
a_get_inactive_plant_storage: bool
|
a_get_inactive_plant_storage: bool
|
||||||
a_get_first_plant_storage_only: bool
|
|
||||||
a_ids_plant_storage: str
|
a_ids_plant_storage: str
|
||||||
a_get_all_location_storage: bool
|
a_get_all_location_storage: bool
|
||||||
a_get_inactive_location_storage: bool
|
a_get_inactive_location_storage: bool
|
||||||
a_ids_location_storage: str
|
a_ids_location_storage: str
|
||||||
a_date_received_to: datetime
|
a_date_received_to: Optional[datetime] = None
|
||||||
a_get_sealed_stock_item_only: bool
|
a_get_sealed_stock_item_only: bool
|
||||||
a_get_unsealed_stock_item_only: bool
|
a_get_unsealed_stock_item_only: bool
|
||||||
a_get_expired_stock_item_only: bool
|
a_get_expired_stock_item_only: bool
|
||||||
@@ -244,7 +206,7 @@ class Parameters_Stock_Item(Get_Many_Parameters_Base):
|
|||||||
def get_default(cls):
|
def get_default(cls):
|
||||||
return cls(
|
return cls(
|
||||||
# a_id_user = id_user,
|
# a_id_user = id_user,
|
||||||
a_get_all_product_permutation = True,
|
a_get_all_product_permutation = False,
|
||||||
a_get_inactive_product_permutation = False,
|
a_get_inactive_product_permutation = False,
|
||||||
a_ids_product_permutation = '',
|
a_ids_product_permutation = '',
|
||||||
a_get_all_stock_item = True,
|
a_get_all_stock_item = True,
|
||||||
@@ -270,4 +232,71 @@ class Parameters_Stock_Item(Get_Many_Parameters_Base):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_form_stock_item(cls, form):
|
def from_form_stock_item(cls, form):
|
||||||
return cls.get_default()
|
return cls.get_default()
|
||||||
|
|
||||||
|
|
||||||
|
class Stock_Item_Temp(db.Model, Store_Base):
|
||||||
|
__tablename__: ClassVar[str] = 'Shop_Stock_Item_Temp'
|
||||||
|
__table_args__ = { 'extend_existing': True }
|
||||||
|
id_stock: int = db.Column(db.Integer, primary_key=True)
|
||||||
|
# id_category: int = db.Column(db.Integer)
|
||||||
|
id_product: int = db.Column(db.Integer)
|
||||||
|
# has_variations: bool = db.Column(db.Boolean)
|
||||||
|
id_permutation: int = db.Column(db.Integer)
|
||||||
|
id_pairs_variations: str = db.Column(db.String(4000))
|
||||||
|
date_purchased: datetime = db.Column(db.DateTime)
|
||||||
|
date_received: datetime = db.Column(db.DateTime, nullable=True)
|
||||||
|
id_location_storage: int = db.Column(db.Integer)
|
||||||
|
id_currency_cost: int = db.Column(db.Integer)
|
||||||
|
cost_local_VAT_excl: float = db.Column(db.Float)
|
||||||
|
cost_local_VAT_incl: float = db.Column(db.Float)
|
||||||
|
is_sealed: bool = db.Column(db.Boolean)
|
||||||
|
date_unsealed: datetime = db.Column(db.DateTime, nullable=True)
|
||||||
|
date_expiration: datetime = db.Column(db.DateTime, nullable=True)
|
||||||
|
is_consumed: bool = db.Column(db.Boolean)
|
||||||
|
date_consumed: datetime = db.Column(db.DateTime, nullable=True)
|
||||||
|
active: bool = db.Column(db.Boolean)
|
||||||
|
guid: str = db.Column(db.String(36))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_stock_item(cls, stock_item):
|
||||||
|
row = cls()
|
||||||
|
row.id_stock = stock_item.id_stock
|
||||||
|
# row.id_category = stock_item.id_category
|
||||||
|
row.id_product = stock_item.id_product
|
||||||
|
row.id_permutation = stock_item.id_permutation
|
||||||
|
# row.has_variations = stock_item.has_variations
|
||||||
|
row.id_pairs_variations = stock_item.variation_tree.to_json_str() if stock_item.variation_tree is not None else ''
|
||||||
|
row.date_purchased = stock_item.date_purchased
|
||||||
|
row.date_received = stock_item.date_received if stock_item.date_received else None
|
||||||
|
row.id_location_storage = stock_item.id_location_storage
|
||||||
|
row.id_currency_cost = stock_item.id_currency_cost
|
||||||
|
row.cost_local_VAT_excl = stock_item.cost_local_VAT_excl
|
||||||
|
row.cost_local_VAT_incl = stock_item.cost_local_VAT_incl
|
||||||
|
row.is_sealed = 1 if stock_item.is_sealed else 0
|
||||||
|
row.date_unsealed = stock_item.date_unsealed if stock_item.date_unsealed else None
|
||||||
|
row.date_expiration = stock_item.date_expiration if stock_item.date_expiration else None
|
||||||
|
row.is_consumed = 1 if stock_item.is_consumed else 0
|
||||||
|
row.date_consumed = stock_item.date_consumed if stock_item.date_consumed else None
|
||||||
|
row.active = 1 if stock_item.active else 0
|
||||||
|
return row
|
||||||
|
def __repr__(self):
|
||||||
|
return f'''
|
||||||
|
id_stock: {self.id_stock}
|
||||||
|
id_product: {self.id_product}
|
||||||
|
id_permutation: {self.id_permutation}
|
||||||
|
id_pairs_variations: {self.id_pairs_variations}
|
||||||
|
date_purchased: {self.date_purchased}
|
||||||
|
date_received: {self.date_received}
|
||||||
|
id_location_storage: {self.id_location_storage}
|
||||||
|
id_currency_cost: {self.id_currency_cost}
|
||||||
|
cost_local_VAT_excl: {self.cost_local_VAT_excl}
|
||||||
|
cost_local_VAT_incl: {self.cost_local_VAT_incl}
|
||||||
|
is_sealed: {self.is_sealed}
|
||||||
|
date_unsealed: {self.date_unsealed}
|
||||||
|
date_expiration: {self.date_expiration}
|
||||||
|
is_consumed: {self.is_consumed}
|
||||||
|
date_consumed: {self.date_consumed}
|
||||||
|
active: {self.active}
|
||||||
|
guid: {self.guid}
|
||||||
|
'''
|
||||||
@@ -12,6 +12,7 @@ Business object for product
|
|||||||
|
|
||||||
# internal
|
# internal
|
||||||
import lib.argument_validation as av
|
import lib.argument_validation as av
|
||||||
|
from business_objects.store.plant import Plant
|
||||||
from business_objects.store.store_base import Store_Base
|
from business_objects.store.store_base import Store_Base
|
||||||
from extensions import db
|
from extensions import db
|
||||||
# external
|
# external
|
||||||
@@ -27,19 +28,33 @@ class Storage_Location(db.Model, Store_Base):
|
|||||||
code = db.Column(db.String(50))
|
code = db.Column(db.String(50))
|
||||||
name = db.Column(db.String(255))
|
name = db.Column(db.String(255))
|
||||||
active = db.Column(db.Boolean)
|
active = db.Column(db.Boolean)
|
||||||
|
|
||||||
|
# plant = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
Store_Base.__init__(self)
|
Store_Base.__init__(self)
|
||||||
|
self.plant = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_DB_storage_location(cls, query_row):
|
def from_DB_storage_location(cls, query_row):
|
||||||
location = cls()
|
location = cls()
|
||||||
location.id_location = query_row[0]
|
location.id_location = query_row[0]
|
||||||
location.id_plant = query_row[1]
|
location.id_plant = query_row[1]
|
||||||
|
location.plant = Plant.from_DB_storage_location(query_row)
|
||||||
location.code = query_row[2]
|
location.code = query_row[2]
|
||||||
location.name = query_row[3]
|
location.name = query_row[3]
|
||||||
location.active = query_row[4]
|
location.active = query_row[4]
|
||||||
return location
|
return location
|
||||||
|
@classmethod
|
||||||
|
def from_DB_stock_item(cls, query_row):
|
||||||
|
location = cls()
|
||||||
|
location.id_location = query_row[4]
|
||||||
|
location.id_plant = query_row[5]
|
||||||
|
location.code = query_row[8]
|
||||||
|
location.name = query_row[9]
|
||||||
|
location.plant = Plant.from_DB_stock_item(query_row)
|
||||||
|
return location
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'''
|
return f'''
|
||||||
{self.ATTR_ID_STORAGE_LOCATION}: {self.id_location}
|
{self.ATTR_ID_STORAGE_LOCATION}: {self.id_location}
|
||||||
@@ -67,3 +82,6 @@ class Storage_Location(db.Model, Store_Base):
|
|||||||
location.name = json[cls.FLAG_NAME],
|
location.name = json[cls.FLAG_NAME],
|
||||||
location.active = json[cls.FLAG_ACTIVE]
|
location.active = json[cls.FLAG_ACTIVE]
|
||||||
return location
|
return location
|
||||||
|
|
||||||
|
def get_full_name(self):
|
||||||
|
return f'{self.plant.name} - {self.name}'
|
||||||
@@ -58,9 +58,9 @@ class I_Store_Base():
|
|||||||
|
|
||||||
class Store_Base(Base):
|
class Store_Base(Base):
|
||||||
# ATTR_ID_CURRENCY_COST: ClassVar[str] = 'id_currency_cost'
|
# ATTR_ID_CURRENCY_COST: ClassVar[str] = 'id_currency_cost'
|
||||||
|
ATTR_ID_DELIVERY_OPTION: ClassVar[str] = 'id_delivery_option'
|
||||||
ATTR_ID_DISCOUNT: ClassVar[str] = 'id_discount'
|
ATTR_ID_DISCOUNT: ClassVar[str] = 'id_discount'
|
||||||
ATTR_ID_IMAGE: ClassVar[str] = 'id_image'
|
ATTR_ID_IMAGE: ClassVar[str] = 'id_image'
|
||||||
ATTR_ID_LOCATION_STORAGE: ClassVar[str] = 'id_location_storage'
|
|
||||||
ATTR_ID_PLANT: ClassVar[str] = 'id_plant'
|
ATTR_ID_PLANT: ClassVar[str] = 'id_plant'
|
||||||
ATTR_ID_PRODUCT: ClassVar[str] = 'id_product'
|
ATTR_ID_PRODUCT: ClassVar[str] = 'id_product'
|
||||||
ATTR_ID_PRODUCT_CATEGORY: ClassVar[str] = 'id_category'
|
ATTR_ID_PRODUCT_CATEGORY: ClassVar[str] = 'id_category'
|
||||||
@@ -70,10 +70,15 @@ class Store_Base(Base):
|
|||||||
ATTR_ID_PRODUCT_VARIATION: ClassVar[str] = 'id_variation'
|
ATTR_ID_PRODUCT_VARIATION: ClassVar[str] = 'id_variation'
|
||||||
ATTR_ID_PRODUCT_VARIATION_TYPE: ClassVar[str] = 'id_type'
|
ATTR_ID_PRODUCT_VARIATION_TYPE: ClassVar[str] = 'id_type'
|
||||||
ATTR_ID_STOCK_ITEM: ClassVar[str] = 'id_stock_item'
|
ATTR_ID_STOCK_ITEM: ClassVar[str] = 'id_stock_item'
|
||||||
FLAG_CURRENCY: ClassVar[str] = 'currency'
|
ATTR_ID_STORAGE_LOCATION: ClassVar[str] = 'id_location'
|
||||||
|
FLAG_COST_LOCAL: ClassVar[str] = 'cost_local'
|
||||||
|
FLAG_COST_LOCAL_VAT_EXCL: ClassVar[str] = FLAG_COST_LOCAL + '_vat_excl'
|
||||||
|
FLAG_COST_LOCAL_VAT_INCL: ClassVar[str] = FLAG_COST_LOCAL + '_vat_incl'
|
||||||
FLAG_DELIVERY_OPTION: ClassVar[str] = 'delivery_option'
|
FLAG_DELIVERY_OPTION: ClassVar[str] = 'delivery_option'
|
||||||
FLAG_HAS_VARIATIONS: ClassVar[str] = 'has_variations'
|
FLAG_HAS_VARIATIONS: ClassVar[str] = 'has_variations'
|
||||||
FLAG_IS_OUT_OF_STOCK: ClassVar[str] = 'is_out_of_stock'
|
FLAG_IS_OUT_OF_STOCK: ClassVar[str] = 'is_out_of_stock'
|
||||||
|
FLAG_DISCOUNT: ClassVar[str] = 'discount'
|
||||||
|
FLAG_PLANT: ClassVar[str] = 'plant'
|
||||||
FLAG_PRODUCT: ClassVar[str] = 'product'
|
FLAG_PRODUCT: ClassVar[str] = 'product'
|
||||||
FLAG_PRODUCT_CATEGORY: ClassVar[str] = 'product_category'
|
FLAG_PRODUCT_CATEGORY: ClassVar[str] = 'product_category'
|
||||||
FLAG_PRODUCT_IMAGE: ClassVar[str] = 'product_image'
|
FLAG_PRODUCT_IMAGE: ClassVar[str] = 'product_image'
|
||||||
@@ -85,6 +90,7 @@ class Store_Base(Base):
|
|||||||
FLAG_QUANTITY_MIN: ClassVar[str] = 'quantity_min'
|
FLAG_QUANTITY_MIN: ClassVar[str] = 'quantity_min'
|
||||||
FLAG_QUANTITY_MAX: ClassVar[str] = 'quantity_max'
|
FLAG_QUANTITY_MAX: ClassVar[str] = 'quantity_max'
|
||||||
FLAG_STOCK_ITEM: ClassVar[str] = 'stock_item'
|
FLAG_STOCK_ITEM: ClassVar[str] = 'stock_item'
|
||||||
|
FLAG_STORAGE_LOCATION: ClassVar[str] = 'storage_location'
|
||||||
FLAG_TEXT: ClassVar[str] = 'text'
|
FLAG_TEXT: ClassVar[str] = 'text'
|
||||||
FLAG_VALUE_TEXT: ClassVar[str] = 'value_text'
|
FLAG_VALUE_TEXT: ClassVar[str] = 'value_text'
|
||||||
|
|
||||||
@@ -38,7 +38,9 @@ class User(db.Model, Base):
|
|||||||
# is_logged_in: bool
|
# is_logged_in: bool
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.id_user = 0
|
||||||
self.is_logged_in = False
|
self.is_logged_in = False
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
def from_DB_user(query_row):
|
def from_DB_user(query_row):
|
||||||
_m = 'User.from_DB_user'
|
_m = 'User.from_DB_user'
|
||||||
@@ -62,7 +64,7 @@ class User(db.Model, Base):
|
|||||||
_m = 'User.from_json'
|
_m = 'User.from_json'
|
||||||
user = User()
|
user = User()
|
||||||
if json is None: return user
|
if json is None: return user
|
||||||
print(f'json: {json}')
|
print(f'{_m}\njson: {json}')
|
||||||
user.id_user = json['id_user']
|
user.id_user = json['id_user']
|
||||||
user.id_user_auth0 = json['id_user_auth0']
|
user.id_user_auth0 = json['id_user_auth0']
|
||||||
user.firstname = json['firstname']
|
user.firstname = json['firstname']
|
||||||
@@ -85,7 +87,7 @@ class User(db.Model, Base):
|
|||||||
_m = 'User.from_json_auth0'
|
_m = 'User.from_json_auth0'
|
||||||
user = User()
|
user = User()
|
||||||
if json is None: return user
|
if json is None: return user
|
||||||
print(f'json: {json}')
|
print(f'{_m}\njson: {json}')
|
||||||
user_info = json['userinfo']
|
user_info = json['userinfo']
|
||||||
user.id_user = None
|
user.id_user = None
|
||||||
user.id_user_auth0 = user_info['sub']
|
user.id_user_auth0 = user_info['sub']
|
||||||
@@ -136,11 +138,6 @@ class User(db.Model, Base):
|
|||||||
can_admin_user: {self.can_admin_user}
|
can_admin_user: {self.can_admin_user}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_default():
|
|
||||||
user = User()
|
|
||||||
user.id_user = None
|
|
||||||
return user
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -88,6 +88,11 @@ def services():
|
|||||||
def admin_home():
|
def admin_home():
|
||||||
try:
|
try:
|
||||||
model = Model_View_Admin_Home()
|
model = Model_View_Admin_Home()
|
||||||
|
if not model.is_user_logged_in:
|
||||||
|
# return redirect(url_for('routes_user.login', callback = Model_View_Admin_Home.HASH_PAGE_ADMIN_HOME))
|
||||||
|
return redirect(url_for('routes_core.home'))
|
||||||
|
if not (model.user.can_admin_store or model.user.can_admin_user):
|
||||||
|
return redirect(url_for('routes_core.home'))
|
||||||
html_body = render_template('pages/core/_admin_home.html', model = model)
|
html_body = render_template('pages/core/_admin_home.html', model = model)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify(error=str(e)), 403
|
return jsonify(error=str(e)), 403
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -111,6 +111,9 @@ def products():
|
|||||||
form_filters = Filters_Product()
|
form_filters = Filters_Product()
|
||||||
print(f'form_filters={form_filters}')
|
print(f'form_filters={form_filters}')
|
||||||
model = Model_View_Store_Product(form_filters)
|
model = Model_View_Store_Product(form_filters)
|
||||||
|
if not model.is_user_logged_in:
|
||||||
|
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Product.KEY_CALLBACK: Model_View_Store_Product.HASH_PAGE_STORE_PRODUCTS })))
|
||||||
|
return redirect(url_for('routes_core.home'))
|
||||||
return render_template('pages/store/_products.html', model = model)
|
return render_template('pages/store/_products.html', model = model)
|
||||||
|
|
||||||
@routes_store_product.route(Model_View_Store_Product.HASH_GET_STORE_PRODUCT, methods=['POST'])
|
@routes_store_product.route(Model_View_Store_Product.HASH_GET_STORE_PRODUCT, methods=['POST'])
|
||||||
@@ -124,6 +127,8 @@ def filter_product():
|
|||||||
Model_View_Store_Product.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'
|
Model_View_Store_Product.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'
|
||||||
})
|
})
|
||||||
model = Model_View_Store_Product(form_filters = form_filters)
|
model = Model_View_Store_Product(form_filters = form_filters)
|
||||||
|
if not model.is_user_logged_in:
|
||||||
|
raise Exception('User not logged in')
|
||||||
return jsonify({
|
return jsonify({
|
||||||
Model_View_Store_Product.FLAG_STATUS: Model_View_Store_Product.FLAG_SUCCESS,
|
Model_View_Store_Product.FLAG_STATUS: Model_View_Store_Product.FLAG_SUCCESS,
|
||||||
Model_View_Store_Product.KEY_DATA: model.category_list.to_json()
|
Model_View_Store_Product.KEY_DATA: model.category_list.to_json()
|
||||||
@@ -161,6 +166,8 @@ def save_product():
|
|||||||
save_errors = 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)
|
model_return = Model_View_Store_Product(form_filters=form_filters)
|
||||||
|
if not model_return.is_user_logged_in:
|
||||||
|
raise Exception('User not logged in')
|
||||||
print('nips')
|
print('nips')
|
||||||
return jsonify({
|
return jsonify({
|
||||||
Model_View_Store_Product.FLAG_STATUS: Model_View_Store_Product.FLAG_SUCCESS,
|
Model_View_Store_Product.FLAG_STATUS: Model_View_Store_Product.FLAG_SUCCESS,
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ def categories():
|
|||||||
return redirect(url_for('routes_store_product_category.categories', **filters.to_json()))
|
return redirect(url_for('routes_store_product_category.categories', **filters.to_json()))
|
||||||
"""
|
"""
|
||||||
model = Model_View_Store_Product_Category(form_filters)
|
model = Model_View_Store_Product_Category(form_filters)
|
||||||
|
if not model.is_user_logged_in:
|
||||||
|
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Product_Category.KEY_CALLBACK: Model_View_Store_Product_Category.HASH_PAGE_STORE_PRODUCT_CATEGORIES })))
|
||||||
|
return redirect(url_for('routes_core.home'))
|
||||||
return render_template('pages/store/_product_categories.html', model = model)
|
return render_template('pages/store/_product_categories.html', model = model)
|
||||||
|
|
||||||
@routes_store_product_category.route(Model_View_Store_Product_Category.HASH_GET_STORE_PRODUCT_CATEGORY, methods=['POST'])
|
@routes_store_product_category.route(Model_View_Store_Product_Category.HASH_GET_STORE_PRODUCT_CATEGORY, methods=['POST'])
|
||||||
@@ -70,6 +73,8 @@ def filter_category():
|
|||||||
# ToDo: manually validate category, product
|
# ToDo: manually validate category, product
|
||||||
# filters_form = Filters_Product_Category.from_form(form_filters)
|
# filters_form = Filters_Product_Category.from_form(form_filters)
|
||||||
model = Model_View_Store_Product_Category(form_filters = form_filters)
|
model = Model_View_Store_Product_Category(form_filters = form_filters)
|
||||||
|
if not model.is_user_logged_in:
|
||||||
|
raise Exception('User not logged in')
|
||||||
return jsonify({
|
return jsonify({
|
||||||
Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_SUCCESS,
|
Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_SUCCESS,
|
||||||
Model_View_Store_Product_Category.KEY_DATA: model.category_list.to_json()
|
Model_View_Store_Product_Category.KEY_DATA: model.category_list.to_json()
|
||||||
@@ -106,7 +111,8 @@ def save_category():
|
|||||||
Model_View_Store_Product_Category.save_categories(data.get('comment', 'No comment'), objsCategory)
|
Model_View_Store_Product_Category.save_categories(data.get('comment', 'No comment'), objsCategory)
|
||||||
|
|
||||||
model_return = Model_View_Store_Product_Category(form_filters=form_filters)
|
model_return = Model_View_Store_Product_Category(form_filters=form_filters)
|
||||||
print('nips')
|
if not model_return.is_user_logged_in:
|
||||||
|
raise Exception('User not logged in')
|
||||||
return jsonify({
|
return jsonify({
|
||||||
Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_SUCCESS,
|
Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_SUCCESS,
|
||||||
Model_View_Store_Product_Category.KEY_DATA: model_return.category_list.to_json()
|
Model_View_Store_Product_Category.KEY_DATA: model_return.category_list.to_json()
|
||||||
|
|||||||
@@ -96,6 +96,9 @@ def permutations():
|
|||||||
form_filters = Filters_Product_Permutation()
|
form_filters = Filters_Product_Permutation()
|
||||||
print(f'form_filters={form_filters}')
|
print(f'form_filters={form_filters}')
|
||||||
model = Model_View_Store_Product_Permutation(form_filters)
|
model = Model_View_Store_Product_Permutation(form_filters)
|
||||||
|
if not model.is_user_logged_in:
|
||||||
|
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Product_Permutation.KEY_CALLBACK: Model_View_Store_Product_Permutation.HASH_PAGE_STORE_PRODUCT_PERMUTATIONS })))
|
||||||
|
return redirect(url_for('routes_core.home'))
|
||||||
return render_template('pages/store/_product_permutations.html', model = model)
|
return render_template('pages/store/_product_permutations.html', model = model)
|
||||||
|
|
||||||
@routes_store_product_permutation.route(Model_View_Store_Product_Permutation.HASH_GET_STORE_PRODUCT_PERMUTATION, methods=['POST'])
|
@routes_store_product_permutation.route(Model_View_Store_Product_Permutation.HASH_GET_STORE_PRODUCT_PERMUTATION, methods=['POST'])
|
||||||
@@ -109,6 +112,8 @@ def filter_permutation():
|
|||||||
Model_View_Store_Product_Permutation.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'
|
Model_View_Store_Product_Permutation.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'
|
||||||
})
|
})
|
||||||
model = Model_View_Store_Product_Permutation(form_filters = form_filters)
|
model = Model_View_Store_Product_Permutation(form_filters = form_filters)
|
||||||
|
if not model.is_user_logged_in:
|
||||||
|
raise Exception('User not logged in')
|
||||||
return jsonify({
|
return jsonify({
|
||||||
Model_View_Store_Product_Permutation.FLAG_STATUS: Model_View_Store_Product_Permutation.FLAG_SUCCESS,
|
Model_View_Store_Product_Permutation.FLAG_STATUS: Model_View_Store_Product_Permutation.FLAG_SUCCESS,
|
||||||
Model_View_Store_Product_Permutation.KEY_DATA: model.category_list.to_json()
|
Model_View_Store_Product_Permutation.KEY_DATA: model.category_list.to_json()
|
||||||
@@ -146,6 +151,8 @@ def save_permutation():
|
|||||||
Model_View_Store_Product_Permutation.save_permutations(data.get('comment', 'No comment'), objsPermutation)
|
Model_View_Store_Product_Permutation.save_permutations(data.get('comment', 'No comment'), objsPermutation)
|
||||||
|
|
||||||
model_return = Model_View_Store_Product_Permutation(form_filters=form_filters)
|
model_return = Model_View_Store_Product_Permutation(form_filters=form_filters)
|
||||||
|
if not model_return.is_user_logged_in:
|
||||||
|
raise Exception('User not logged in')
|
||||||
print('nips')
|
print('nips')
|
||||||
return jsonify({
|
return jsonify({
|
||||||
Model_View_Store_Product_Permutation.FLAG_STATUS: Model_View_Store_Product_Permutation.FLAG_SUCCESS,
|
Model_View_Store_Product_Permutation.FLAG_STATUS: Model_View_Store_Product_Permutation.FLAG_SUCCESS,
|
||||||
|
|||||||
@@ -11,91 +11,26 @@ Initializes the Flask application, sets the configuration based on the environme
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# internal
|
# internal
|
||||||
from business_objects.store.product import Product, Parameters_Product, Product_Permutation
|
|
||||||
from business_objects.store.stock_item import Stock_Item
|
from business_objects.store.stock_item import Stock_Item
|
||||||
from forms.store.stock_item import Filters_Stock_Item
|
from forms.store.stock_item import Filters_Stock_Item
|
||||||
from models.model_view_base import Model_View_Base
|
|
||||||
from models.model_view_store import Model_View_Store
|
|
||||||
from models.model_view_store_supplier import Model_View_Store_Supplier
|
|
||||||
from models.model_view_store_product_category import Model_View_Store_Product_Category
|
|
||||||
from models.model_view_store_product_permutation import Model_View_Store_Product_Permutation
|
|
||||||
from models.model_view_store_stock_item import Model_View_Store_Stock_Item
|
from models.model_view_store_stock_item import Model_View_Store_Stock_Item
|
||||||
from helpers.helper_app import Helper_App
|
from helpers.helper_app import Helper_App
|
||||||
import lib.argument_validation as av
|
import lib.argument_validation as av
|
||||||
# external
|
# external
|
||||||
|
from datetime import datetime
|
||||||
from flask import Flask, render_template, jsonify, request, render_template_string, send_from_directory, redirect, url_for, session, Blueprint, current_app
|
from flask import Flask, render_template, jsonify, request, render_template_string, send_from_directory, redirect, url_for, session, Blueprint, current_app
|
||||||
from extensions import db, oauth
|
from extensions import db, oauth
|
||||||
from urllib.parse import quote_plus, urlencode
|
from urllib.parse import quote_plus, urlencode
|
||||||
from authlib.integrations.flask_client import OAuth
|
from authlib.integrations.flask_client import OAuth
|
||||||
from authlib.integrations.base_client import OAuthError
|
from authlib.integrations.base_client import OAuthError
|
||||||
from urllib.parse import quote, urlparse, parse_qs
|
from urllib.parse import quote, urlparse, parse_qs
|
||||||
|
import requests
|
||||||
|
|
||||||
routes_store_stock_item = Blueprint('routes_store_stock_item', __name__)
|
routes_store_stock_item = Blueprint('routes_store_stock_item', __name__)
|
||||||
|
|
||||||
"""
|
|
||||||
@routes_store_stock_item.route('/store/stock_items', methods=['GET'])
|
|
||||||
def stock():
|
|
||||||
filters = Filters_Stock_Item.get_default()
|
|
||||||
model = Model_View_Store_Stock_Item(filters_stock_item=filters)
|
|
||||||
return render_template('pages/store/_stock_items.html', model = model)
|
|
||||||
|
|
||||||
@routes_store_stock_item.route('/store/stock_item_filter', methods=['POST'])
|
|
||||||
def stock_filter():
|
|
||||||
data = Helper_App.get_request_data(request)
|
|
||||||
form_filters = None
|
|
||||||
try:
|
|
||||||
form_filters = get_Filters_Stock_Items(data)
|
|
||||||
if not form_filters.validate_on_submit():
|
|
||||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'})
|
|
||||||
# ToDo: manually validate category, product
|
|
||||||
filters_form = Filters_Stock_Item.from_form(form_filters)
|
|
||||||
model = Model_View_Store_Stock_Item(filters_stock_item=filters_form)
|
|
||||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS, 'Success': True, Model_View_Base.KEY_DATA: model.category_list.to_permutation_row_list()})
|
|
||||||
except Exception as e:
|
|
||||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Bad data received by controller.\n{e}'})
|
|
||||||
|
|
||||||
def get_Filters_Stock_Items(data_request):
|
|
||||||
data_form = data_request[Model_View_Store_Stock_Item.KEY_FORM]
|
|
||||||
form_filters = Filters_Stock_Item(**data_form)
|
|
||||||
form_filters.is_out_of_stock.data = av.input_bool(data_form['is_out_of_stock'], 'is_out_of_stock', 'permutations_post')
|
|
||||||
return form_filters
|
|
||||||
|
|
||||||
@routes_store_stock_item.route('/store/stock_item_save', methods=['POST'])
|
|
||||||
def stock_save():
|
|
||||||
data = Helper_App.get_request_data(request)
|
|
||||||
""
|
|
||||||
form_filters = None
|
|
||||||
try:
|
|
||||||
form_filters = get_Filters_Stock_Items(data)
|
|
||||||
if not form_filters.validate_on_submit():
|
|
||||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Filters form invalid.\n{form_filters.errors}'})
|
|
||||||
|
|
||||||
stock_items = data[Model_View_Store_Stock.KEY_PERMUTATIONS]
|
|
||||||
print(f'stock_items: {stock_items}')
|
|
||||||
if len(stock_items) == 0:
|
|
||||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_FAILURE, Model_View_Base.FLAG_MESSAGE: f'No stock items.'})
|
|
||||||
objsStockItem = []
|
|
||||||
for stock_item in stock_items:
|
|
||||||
objsStockItem.append(Product_Permutation.from_json(stock_item))
|
|
||||||
print(f'objsStockItem: {objsStockItem}')
|
|
||||||
|
|
||||||
# ToDo: manually validate category, product
|
|
||||||
filters_form = Stock_Filters.from_form(form_filters)
|
|
||||||
model_save = Model_View_Store_Stock(filters_product=filters_form)
|
|
||||||
model_save.save_stock_items(data.comment, objsPermutation)
|
|
||||||
|
|
||||||
model_return = Model_View_Store_Stock(filters_product=filters_form)
|
|
||||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS, 'Success': True, Model_View_Base.KEY_DATA: model_return.category_list.to_permutation_row_list()})
|
|
||||||
except Exception as e:
|
|
||||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Bad data received by controller.\n{e}'})
|
|
||||||
""
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
@routes_store_stock_item.route(Model_View_Store_Stock_Item.HASH_PAGE_STORE_STOCK_ITEMS, methods=['GET'])
|
@routes_store_stock_item.route(Model_View_Store_Stock_Item.HASH_PAGE_STORE_STOCK_ITEMS, methods=['GET'])
|
||||||
def permutations():
|
def stock_items():
|
||||||
print('permutations')
|
print('stock_items')
|
||||||
try:
|
try:
|
||||||
form_filters = Filters_Stock_Item.from_json(request.args)
|
form_filters = Filters_Stock_Item.from_json(request.args)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -103,19 +38,39 @@ def permutations():
|
|||||||
form_filters = Filters_Stock_Item()
|
form_filters = Filters_Stock_Item()
|
||||||
print(f'form_filters={form_filters}')
|
print(f'form_filters={form_filters}')
|
||||||
model = Model_View_Store_Stock_Item(form_filters)
|
model = Model_View_Store_Stock_Item(form_filters)
|
||||||
return render_template('pages/store/_stock_items.html', model = model)
|
if not model.is_user_logged_in:
|
||||||
|
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Stock_Item.KEY_CALLBACK: Model_View_Store_Stock_Item.HASH_PAGE_STORE_STOCK_ITEMS })))
|
||||||
|
# return requests.post(f"{current_app.config['URL_HOST']}{url_for('routes_user.login')}", json={ Model_View_Store_Stock_Item.KEY_CALLBACK: Model_View_Store_Stock_Item.HASH_PAGE_STORE_STOCK_ITEMS })
|
||||||
|
return redirect(url_for('routes_core.home'))
|
||||||
|
return render_template('pages/store/_stock_items.html', model = model, datetime = datetime)
|
||||||
|
|
||||||
@routes_store_stock_item.route(Model_View_Store_Stock_Item.HASH_GET_STORE_STOCK_ITEM, methods=['POST'])
|
@routes_store_stock_item.route(Model_View_Store_Stock_Item.HASH_GET_STORE_STOCK_ITEM, methods=['POST'])
|
||||||
def filter_permutation():
|
def filter_stock_item():
|
||||||
data = Helper_App.get_request_data(request)
|
data = Helper_App.get_request_data(request)
|
||||||
try:
|
try:
|
||||||
form_filters = Filters_Stock_Item.from_json(data)
|
form_filters = Filters_Stock_Item.from_json(data)
|
||||||
if not form_filters.validate_on_submit():
|
if not form_filters.validate_on_submit():
|
||||||
return jsonify({
|
error_keys = list(form_filters.errors.keys())
|
||||||
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_FAILURE,
|
try:
|
||||||
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'
|
error_keys.remove(Stock_Item.ATTR_ID_PRODUCT_CATEGORY)
|
||||||
})
|
"""
|
||||||
model = Model_View_Store_Stock_Item(form_filters = form_filters)
|
if not av.val_int(form_filters.id_product_category.data):
|
||||||
|
form_filters.errors[Stock_Item.ATTR_ID_PRODUCT_CATEGORY] = ['Invalid category.']
|
||||||
|
"""
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
error_keys.remove(Stock_Item.ATTR_ID_PRODUCT)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if error_keys:
|
||||||
|
return jsonify({
|
||||||
|
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_FAILURE,
|
||||||
|
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'
|
||||||
|
})
|
||||||
|
model = Model_View_Store_Stock_Item(filters_stock_item = form_filters)
|
||||||
|
if not model.is_user_logged_in:
|
||||||
|
raise Exception('User not logged in.')
|
||||||
return jsonify({
|
return jsonify({
|
||||||
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_SUCCESS,
|
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_SUCCESS,
|
||||||
Model_View_Store_Stock_Item.KEY_DATA: model.category_list.to_json()
|
Model_View_Store_Stock_Item.KEY_DATA: model.category_list.to_json()
|
||||||
@@ -127,33 +82,55 @@ def filter_permutation():
|
|||||||
})
|
})
|
||||||
|
|
||||||
@routes_store_stock_item.route(Model_View_Store_Stock_Item.HASH_SAVE_STORE_STOCK_ITEM, methods=['POST'])
|
@routes_store_stock_item.route(Model_View_Store_Stock_Item.HASH_SAVE_STORE_STOCK_ITEM, methods=['POST'])
|
||||||
def save_permutation():
|
def save_stock_item():
|
||||||
data = Helper_App.get_request_data(request)
|
data = Helper_App.get_request_data(request)
|
||||||
try:
|
try:
|
||||||
form_filters = Filters_Stock_Item.from_json(data[Model_View_Store_Stock_Item.FLAG_FORM_FILTERS])
|
form_filters = Filters_Stock_Item.from_json(data[Model_View_Store_Stock_Item.FLAG_FORM_FILTERS])
|
||||||
|
"""
|
||||||
if not form_filters.validate_on_submit():
|
if not form_filters.validate_on_submit():
|
||||||
return jsonify({
|
error_keys = list(form_filters.errors.keys())
|
||||||
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_FAILURE,
|
try:
|
||||||
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'Filters form invalid.\n{form_filters.errors}'
|
error_keys.remove(Stock_Item.ATTR_ID_PRODUCT_CATEGORY)
|
||||||
})
|
""
|
||||||
|
if not av.val_int(form_filters.id_product_category.data):
|
||||||
|
form_filters.errors[Stock_Item.ATTR_ID_PRODUCT_CATEGORY] = ['Invalid category.']
|
||||||
|
""
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
error_keys.remove(Stock_Item.ATTR_ID_PRODUCT)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if error_keys:
|
||||||
|
return jsonify({
|
||||||
|
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_FAILURE,
|
||||||
|
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'
|
||||||
|
})
|
||||||
|
"""
|
||||||
# filters_form = Filters_Stock_Item.from_form(form_filters)
|
# filters_form = Filters_Stock_Item.from_form(form_filters)
|
||||||
print(f'form_filters: {form_filters}')
|
print(f'form_filters: {form_filters}')
|
||||||
|
|
||||||
permutations = data[Model_View_Store_Stock_Item.FLAG_STOCK_ITEM]
|
stock_items = data[Model_View_Store_Stock_Item.FLAG_STOCK_ITEM]
|
||||||
if len(permutations) == 0:
|
if len(stock_items) == 0:
|
||||||
return jsonify({
|
return jsonify({
|
||||||
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_FAILURE,
|
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_FAILURE,
|
||||||
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'No permutations.'
|
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'No stock items.'
|
||||||
})
|
})
|
||||||
objsPermutation = []
|
print(f'stock_items={stock_items}')
|
||||||
for permutation in permutations:
|
objs_stock_item = []
|
||||||
objsPermutation.append(Stock_Item.from_json(permutation))
|
for stock_item in stock_items:
|
||||||
|
objs_stock_item.append(Stock_Item.from_json(stock_item))
|
||||||
# model_save = Model_View_Store_Stock_Item() # filters_product=filters_form)
|
# model_save = Model_View_Store_Stock_Item() # filters_product=filters_form)
|
||||||
print(f'objsPermutation={objsPermutation}')
|
print(f'objs_stock_item={objs_stock_item}')
|
||||||
Model_View_Store_Stock_Item.save_permutations(data.get('comment', 'No comment'), objsPermutation)
|
save_errors = Model_View_Store_Stock_Item.save_stock_items(data.get('comment', 'No comment'), objs_stock_item)
|
||||||
|
if len(save_errors) > 0:
|
||||||
model_return = Model_View_Store_Stock_Item(form_filters=form_filters)
|
return jsonify({
|
||||||
print('nips')
|
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_FAILURE,
|
||||||
|
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'Save errors: {save_errors}'
|
||||||
|
})
|
||||||
|
model_return = Model_View_Store_Stock_Item(filters_stock_item=form_filters)
|
||||||
|
if not model_return.is_user_logged_in:
|
||||||
|
raise Exception('User not logged in.')
|
||||||
return jsonify({
|
return jsonify({
|
||||||
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_SUCCESS,
|
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_SUCCESS,
|
||||||
Model_View_Store_Stock_Item.KEY_DATA: model_return.category_list.to_json()
|
Model_View_Store_Stock_Item.KEY_DATA: model_return.category_list.to_json()
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ def supplier():
|
|||||||
# if not logged in:
|
# if not logged in:
|
||||||
try:
|
try:
|
||||||
model = Model_View_Store_Supplier(form)
|
model = Model_View_Store_Supplier(form)
|
||||||
|
if not model.is_user_logged_in:
|
||||||
|
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Supplier.KEY_CALLBACK: Model_View_Store_Supplier.HASH_PAGE_STORE_SUPPLIERS })))
|
||||||
|
return redirect(url_for('routes_core.home'))
|
||||||
# print('importing basket')
|
# print('importing basket')
|
||||||
# model.import_JSON_basket(data)
|
# model.import_JSON_basket(data)
|
||||||
model.get_basket(data)
|
model.get_basket(data)
|
||||||
|
|||||||
@@ -170,6 +170,9 @@ def logout_callback():
|
|||||||
def user():
|
def user():
|
||||||
try:
|
try:
|
||||||
model = Model_View_User(current_app, db)
|
model = Model_View_User(current_app, db)
|
||||||
|
if not model.is_user_logged_in:
|
||||||
|
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_User.KEY_CALLBACK: Model_View_User.HASH_PAGE_USER_ACCOUNT })))
|
||||||
|
return redirect(url_for('routes_core.home'))
|
||||||
html_body = render_template('pages/user/_user.html', model = model)
|
html_body = render_template('pages/user/_user.html', model = model)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -20,7 +20,7 @@ from business_objects.store.product_category import Product_Category_Container,
|
|||||||
from business_objects.store.currency import Currency
|
from business_objects.store.currency import Currency
|
||||||
from business_objects.store.image import Image
|
from business_objects.store.image import Image
|
||||||
from business_objects.store.delivery_option import Delivery_Option
|
from business_objects.store.delivery_option import Delivery_Option
|
||||||
from business_objects.store.delivery_region import Delivery_Region
|
from business_objects.store.delivery_region import Region
|
||||||
from business_objects.store.discount import Discount
|
from business_objects.store.discount import Discount
|
||||||
from business_objects.store.order import Order
|
from business_objects.store.order import Order
|
||||||
from business_objects.store.product import Product, Product_Permutation, Product_Price, Parameters_Product # Permutation_Variation_Link
|
from business_objects.store.product import Product, Product_Permutation, Product_Price, Parameters_Product # Permutation_Variation_Link
|
||||||
@@ -145,7 +145,7 @@ class DataStore_Base(BaseModel):
|
|||||||
result_set_1 = cursor.fetchall()
|
result_set_1 = cursor.fetchall()
|
||||||
regions = []
|
regions = []
|
||||||
for row in result_set_1:
|
for row in result_set_1:
|
||||||
region = Delivery_Region.make_from_DB_region(row)
|
region = Region.make_from_DB_region(row)
|
||||||
regions.append(region)
|
regions.append(region)
|
||||||
print(f'regions: {regions}')
|
print(f'regions: {regions}')
|
||||||
DataStore_Base.db_cursor_clear(cursor)
|
DataStore_Base.db_cursor_clear(cursor)
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ Datastore for Store
|
|||||||
# from routes import bp_home
|
# from routes import bp_home
|
||||||
from business_objects.store.basket import Basket, Basket_Item
|
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.product_category import Product_Category_Container, Product_Category
|
||||||
from business_objects.store.currency import Currency
|
from business_objects.currency import Currency
|
||||||
from business_objects.store.image import Image
|
from business_objects.store.image import Image
|
||||||
from business_objects.store.delivery_option import Delivery_Option
|
from business_objects.store.delivery_option import Delivery_Option
|
||||||
from business_objects.store.delivery_region import Delivery_Region
|
from business_objects.region import Region
|
||||||
from business_objects.store.discount import Discount
|
from business_objects.store.discount import Discount
|
||||||
from business_objects.store.order import Order
|
from business_objects.store.order import Order
|
||||||
from business_objects.store.product import Product, Product_Permutation, Parameters_Product
|
from business_objects.store.product import Product, Product_Permutation, Parameters_Product
|
||||||
@@ -235,7 +235,7 @@ class DataStore_Store_Base(DataStore_Base):
|
|||||||
result_set_1 = cursor.fetchall()
|
result_set_1 = cursor.fetchall()
|
||||||
regions = []
|
regions = []
|
||||||
for row in result_set_1:
|
for row in result_set_1:
|
||||||
region = Delivery_Region.from_DB_region(row)
|
region = Region.from_DB_region(row)
|
||||||
regions.append(region)
|
regions.append(region)
|
||||||
print(f'regions: {regions}')
|
print(f'regions: {regions}')
|
||||||
DataStore_Store_Base.db_cursor_clear(cursor)
|
DataStore_Store_Base.db_cursor_clear(cursor)
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ Datastore for Store Baskets
|
|||||||
import lib.argument_validation as av
|
import lib.argument_validation as av
|
||||||
from business_objects.store.basket import Basket, Basket_Item
|
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.product_category import Product_Category_Container, Product_Category
|
||||||
from business_objects.store.currency import Currency
|
from business_objects.currency import Currency
|
||||||
from business_objects.store.image import Image
|
from business_objects.store.image import Image
|
||||||
from business_objects.store.delivery_option import Delivery_Option
|
from business_objects.store.delivery_option import Delivery_Option
|
||||||
from business_objects.store.delivery_region import Delivery_Region
|
from business_objects.region import Region
|
||||||
from business_objects.store.discount import Discount
|
from business_objects.store.discount import Discount
|
||||||
from business_objects.store.order import Order
|
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, Product_Price, Parameters_Product
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ Datastore for Store Product Categories
|
|||||||
import lib.argument_validation as av
|
import lib.argument_validation as av
|
||||||
from business_objects.store.basket import Basket, Basket_Item
|
from business_objects.store.basket import Basket, Basket_Item
|
||||||
from business_objects.store.product_category import Product_Category_Container, Product_Category, Product_Category_Temp
|
from business_objects.store.product_category import Product_Category_Container, Product_Category, Product_Category_Temp
|
||||||
from business_objects.store.currency import Currency
|
from business_objects.currency import Currency
|
||||||
from business_objects.store.image import Image
|
from business_objects.store.image import Image
|
||||||
from business_objects.store.delivery_option import Delivery_Option
|
from business_objects.store.delivery_option import Delivery_Option
|
||||||
from business_objects.store.delivery_region import Delivery_Region
|
from business_objects.region import Region
|
||||||
from business_objects.store.discount import Discount
|
from business_objects.store.discount import Discount
|
||||||
from business_objects.store.order import Order
|
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, Product_Price, Parameters_Product
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ Datastore for Store Product Variations
|
|||||||
import lib.argument_validation as av
|
import lib.argument_validation as av
|
||||||
from business_objects.store.basket import Basket, Basket_Item
|
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.product_category import Product_Category_Container, Product_Category
|
||||||
from business_objects.store.currency import Currency
|
from business_objects.currency import Currency
|
||||||
from business_objects.store.image import Image
|
from business_objects.store.image import Image
|
||||||
from business_objects.store.delivery_option import Delivery_Option
|
from business_objects.store.delivery_option import Delivery_Option
|
||||||
from business_objects.store.delivery_region import Delivery_Region
|
from business_objects.region import Region
|
||||||
from business_objects.store.discount import Discount
|
from business_objects.store.discount import Discount
|
||||||
from business_objects.store.order import Order
|
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, Product_Price, Parameters_Product
|
||||||
|
|||||||
@@ -13,21 +13,10 @@ Datastore for Store Stock Items
|
|||||||
# internal
|
# internal
|
||||||
# from routes import bp_home
|
# from routes import bp_home
|
||||||
import lib.argument_validation as av
|
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.sql_error import SQL_Error
|
||||||
from business_objects.store.stock_item import Stock_Item
|
from business_objects.store.stock_item import Stock_Item, Parameters_Stock_Item, Stock_Item_Temp
|
||||||
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 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 models.model_view_store_checkout import Model_View_Store_Checkout # circular!
|
||||||
from extensions import db
|
from extensions import db
|
||||||
# external
|
# external
|
||||||
@@ -52,11 +41,11 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
|||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
# Stock Items
|
# Stock Items
|
||||||
def get_many_stock_item(self, Parameters_Stock_Item, category_list):
|
def get_many_stock_item(self, parameters_stock_item, category_list):
|
||||||
# redundant argument validation?
|
# redundant argument validation?
|
||||||
_m = 'DataStore_Store_Stock_Item.get_many_stock_item'
|
_m = 'DataStore_Store_Stock_Item.get_many_stock_item'
|
||||||
av.val_instance(Parameters_Stock_Item, 'Parameters_Stock_Item', _m, Parameters_Stock_Item)
|
av.val_instance(parameters_stock_item, 'parameters_stock_item', _m, Parameters_Stock_Item)
|
||||||
argument_dict = Parameters_Stock_Item.to_json()
|
argument_dict = parameters_stock_item.to_json()
|
||||||
user = self.get_user_session()
|
user = self.get_user_session()
|
||||||
"""
|
"""
|
||||||
argument_dict['a_id_user'] = user.id_user # 'auth0|6582b95c895d09a70ba10fef' # id_user
|
argument_dict['a_id_user'] = user.id_user # 'auth0|6582b95c895d09a70ba10fef' # id_user
|
||||||
@@ -67,6 +56,9 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
|||||||
, **argument_dict
|
, **argument_dict
|
||||||
, 'a_debug': 0
|
, 'a_debug': 0
|
||||||
}
|
}
|
||||||
|
ids_permutation = category_list.get_csv_ids_permutation()
|
||||||
|
print(f'ids_permutation: {ids_permutation}')
|
||||||
|
argument_dict['a_ids_product_permutation'] = ids_permutation
|
||||||
print(f'argument_dict: {argument_dict}')
|
print(f'argument_dict: {argument_dict}')
|
||||||
print('executing p_shop_get_many_stock_item')
|
print('executing p_shop_get_many_stock_item')
|
||||||
result = self.db_procedure_execute('p_shop_get_many_stock_item', argument_dict)
|
result = self.db_procedure_execute('p_shop_get_many_stock_item', argument_dict)
|
||||||
@@ -85,7 +77,7 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
|||||||
print(f'raw categories: {result_set_1}')
|
print(f'raw categories: {result_set_1}')
|
||||||
for row in result_set_1:
|
for row in result_set_1:
|
||||||
new_stock_item = Stock_Item.from_DB_stock_item(row)
|
new_stock_item = Stock_Item.from_DB_stock_item(row)
|
||||||
category_list.add_stock_item(new_stock_item, row)
|
category_list.add_stock_item(new_stock_item) # , row)
|
||||||
|
|
||||||
# Errors
|
# Errors
|
||||||
cursor.nextset()
|
cursor.nextset()
|
||||||
@@ -112,5 +104,47 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
|||||||
if 'region' in error.msg or 'currency' in error.msg:
|
if 'region' in error.msg or 'currency' in error.msg:
|
||||||
permutation.is_unavailable_in_currency_or_region = True
|
permutation.is_unavailable_in_currency_or_region = True
|
||||||
"""
|
"""
|
||||||
|
DataStore_Store_Stock_Item.db_cursor_clear(cursor)
|
||||||
return category_list, errors # categories, category_index
|
return category_list, errors # categories, category_index
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def save_stock_items(cls, comment, stock_items):
|
||||||
|
_m = 'DataStore_Store_Stock_Item.save_stock_items'
|
||||||
|
av.val_str(comment, 'comment', _m)
|
||||||
|
|
||||||
|
guid = Helper_DB_MySQL.create_guid_str()
|
||||||
|
now = datetime.now()
|
||||||
|
user = cls.get_user_session()
|
||||||
|
rows = []
|
||||||
|
for stock_item in stock_items:
|
||||||
|
# row = permutation.to_temporary_record()
|
||||||
|
row = Stock_Item_Temp.from_stock_item(stock_item)
|
||||||
|
row.guid = guid
|
||||||
|
rows.append(row)
|
||||||
|
|
||||||
|
print(f'rows: {rows}')
|
||||||
|
|
||||||
|
DataStore_Store_Base.upload_bulk(Stock_Item_Temp.__tablename__, rows, 1000)
|
||||||
|
print('bulk uploaded')
|
||||||
|
|
||||||
|
argument_dict_list = {
|
||||||
|
'a_comment': comment,
|
||||||
|
'a_guid': guid,
|
||||||
|
'a_id_user': user.id_user,
|
||||||
|
'a_debug': 0
|
||||||
|
}
|
||||||
|
result = cls.db_procedure_execute('p_shop_save_stock_item', argument_dict_list)
|
||||||
|
print('saved product permutations')
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
cursor = result.cursor
|
||||||
|
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}")
|
||||||
|
DataStore_Store_Stock_Item.db_cursor_clear(cursor)
|
||||||
|
return errors
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ Datastore for Store Stripe service
|
|||||||
import lib.argument_validation as av
|
import lib.argument_validation as av
|
||||||
from business_objects.store.basket import Basket, Basket_Item
|
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.product_category import Product_Category_Container, Product_Category
|
||||||
from business_objects.store.currency import Currency
|
from business_objects.currency import Currency
|
||||||
from business_objects.store.image import Image
|
from business_objects.store.image import Image
|
||||||
from business_objects.store.delivery_option import Delivery_Option
|
from business_objects.store.delivery_option import Delivery_Option
|
||||||
from business_objects.store.delivery_region import Delivery_Region
|
from business_objects.region import Region
|
||||||
from business_objects.store.discount import Discount
|
from business_objects.store.discount import Discount
|
||||||
from business_objects.store.order import Order
|
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, Product_Price, Parameters_Product
|
||||||
|
|||||||
@@ -139,6 +139,76 @@ class DataStore_User(DataStore_Base):
|
|||||||
'a_id_user': user.id_user
|
'a_id_user': user.id_user
|
||||||
, 'a_id_user_auth0': user.id_user_auth0
|
, 'a_id_user_auth0': user.id_user_auth0
|
||||||
, **user_filters.to_json()
|
, **user_filters.to_json()
|
||||||
|
, 'a_debug': 0
|
||||||
|
|
||||||
|
}
|
||||||
|
# argument_dict_list['a_guid'] = guid
|
||||||
|
result = self.db_procedure_execute('p_get_many_user', argument_dict_list)
|
||||||
|
"""
|
||||||
|
query = text(f"SELECT * FROM Shop_Calc_User_Temp UE_T WHERE UE_T.guid = '{guid}'")
|
||||||
|
result = self.db.session.execute(query)
|
||||||
|
"""
|
||||||
|
cursor = result.cursor
|
||||||
|
result_set = cursor.fetchall()
|
||||||
|
print(f'raw users: {result_set}')
|
||||||
|
print(f'type result set: {str(type(result_set))}')
|
||||||
|
print(f'len result set: {len(result_set)}')
|
||||||
|
"""
|
||||||
|
user_permission_evals = []
|
||||||
|
for row in result_set:
|
||||||
|
user_permission_eval = User_Permission_Evaluation.from_DB_user_eval(row)
|
||||||
|
user_permission_evals.append(user_permission_eval)
|
||||||
|
print(f'user_permission_evals: {user_permission_evals}')
|
||||||
|
"""
|
||||||
|
users = []
|
||||||
|
if len(result_set) > 0:
|
||||||
|
for row in result_set:
|
||||||
|
print(f'row: {row}')
|
||||||
|
user = User.from_DB_user(row)
|
||||||
|
users.append(user)
|
||||||
|
print(f'user {str(type(user))}: {user}')
|
||||||
|
print(f'type users: {str(type(users))}\n type user 0: {str(type(None if len(users) == 0 else users[0]))}')
|
||||||
|
# error_list, cursor = self.get_error_list_from_cursor(cursor)
|
||||||
|
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_User.db_cursor_clear(cursor)
|
||||||
|
|
||||||
|
return users, errors
|
||||||
|
|
||||||
|
def get_many_user(self, user_filters, user=None):
|
||||||
|
_m = 'DataStore_User.get_many_user'
|
||||||
|
print(_m)
|
||||||
|
# av.val_str(user_filters, 'user_filters', _m)
|
||||||
|
# av.val_list(permutations, 'list_permutations', _m, Product_Permutation, 1)
|
||||||
|
av.val_instance(user_filters, 'user_filters', _m, User_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
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
if user is None:
|
||||||
|
user = self.get_user_session()
|
||||||
|
argument_dict_list = {
|
||||||
|
# 'a_guid': guid
|
||||||
|
'a_id_user': user.id_user
|
||||||
|
, 'a_id_user_auth0': user.id_user_auth0
|
||||||
|
, **user_filters.to_json()
|
||||||
|
, 'a_debug': 0
|
||||||
|
|
||||||
}
|
}
|
||||||
# argument_dict_list['a_guid'] = guid
|
# argument_dict_list['a_guid'] = guid
|
||||||
result = self.db_procedure_execute('p_get_many_user', argument_dict_list)
|
result = self.db_procedure_execute('p_get_many_user', argument_dict_list)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -23,7 +23,7 @@ from abc import ABCMeta, abstractmethod
|
|||||||
|
|
||||||
|
|
||||||
class Filters_Access_Level(Form_Base):
|
class Filters_Access_Level(Form_Base):
|
||||||
active = BooleanField("Active only?")
|
active = BooleanField("Active only?", default = True)
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'{self.__class__.__name__}(active={self.active.data})'
|
return f'{self.__class__.__name__}(active={self.active.data})'
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ class Form_Supplier(FlaskForm):
|
|||||||
fax = StringField('Fax number')
|
fax = StringField('Fax number')
|
||||||
website = StringField('Website')
|
website = StringField('Website')
|
||||||
id_currency = SelectField('Currency ID')
|
id_currency = SelectField('Currency ID')
|
||||||
is_active = BooleanField('Active')
|
is_active = BooleanField('Active', default = True)
|
||||||
|
|
||||||
# class Form_Supplier_Purchase_Order(FlaskForm):
|
# class Form_Supplier_Purchase_Order(FlaskForm):
|
||||||
|
|
||||||
@@ -130,5 +130,5 @@ class Form_Supplier(FlaskForm):
|
|||||||
|
|
||||||
# User
|
# User
|
||||||
class Form_Filters_User(FlaskForm):
|
class Form_Filters_User(FlaskForm):
|
||||||
active = BooleanField('Active only?')
|
active = BooleanField('Active only?', default = True)
|
||||||
id_user = SelectField('User ID', validators=[Optional()], choices=[])
|
id_user = SelectField('User ID', validators=[Optional()], choices=[])
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -24,7 +24,7 @@ from flask_wtf.recaptcha import RecaptchaField
|
|||||||
class Filters_Product(FlaskForm):
|
class Filters_Product(FlaskForm):
|
||||||
id_category = SelectField('Category', validators=[Optional()], choices=[('', 'All')])
|
id_category = SelectField('Category', validators=[Optional()], choices=[('', 'All')])
|
||||||
is_not_empty = BooleanField('Not empty only?')
|
is_not_empty = BooleanField('Not empty only?')
|
||||||
active = BooleanField("Active only?")
|
active = BooleanField("Active only?", default = True)
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_filters_product(cls, filters_product):
|
def from_filters_product(cls, filters_product):
|
||||||
form = Filters_Product()
|
form = Filters_Product()
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ from abc import ABCMeta, abstractmethod
|
|||||||
|
|
||||||
class Filters_Product_Category(Form_Base):
|
class Filters_Product_Category(Form_Base):
|
||||||
is_not_empty = BooleanField('Not empty only?')
|
is_not_empty = BooleanField('Not empty only?')
|
||||||
active = BooleanField("Active only?")
|
active = BooleanField("Active only?", default = True)
|
||||||
"""
|
"""
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_filters(cls, filters):
|
def from_filters(cls, filters):
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ from flask_wtf.recaptcha import RecaptchaField
|
|||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
|
|
||||||
class Filters_Stock_Item(Form_Base):
|
class Filters_Stock_Item(Form_Base):
|
||||||
id_category = SelectField('Category', validators=[Optional()], choices=[])
|
id_category = SelectField('Category', choices=[Form_Base.get_choice_all()], default='')
|
||||||
id_product = SelectField('Product', validators=[Optional()], choices=[])
|
id_product = SelectField('Product', choices=[Form_Base.get_choice_all()], default='')
|
||||||
is_out_of_stock = BooleanField('Out of stock only?')
|
is_out_of_stock = BooleanField('Out of stock only?')
|
||||||
quantity_min = FloatField('Min stock')
|
quantity_min = FloatField('Min stock')
|
||||||
quantity_max = FloatField('Max stock')
|
quantity_max = FloatField('Max stock')
|
||||||
@@ -45,9 +45,9 @@ class Filters_Stock_Item(Form_Base):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, json):
|
def from_json(cls, json):
|
||||||
form = cls()
|
form = cls()
|
||||||
form.id_category.choices = [(json[Store_Base.ATTR_ID_PRODUCT_CATEGORY], json[Store_Base.ATTR_ID_PRODUCT_CATEGORY])]
|
# form.id_category.choices = [(json[Store_Base.ATTR_ID_PRODUCT_CATEGORY], json[Store_Base.ATTR_ID_PRODUCT_CATEGORY])]
|
||||||
form.id_category.data = json[Store_Base.ATTR_ID_PRODUCT_CATEGORY]
|
form.id_category.data = json[Store_Base.ATTR_ID_PRODUCT_CATEGORY]
|
||||||
form.id_product.choices = [(json[Store_Base.ATTR_ID_PRODUCT], json[Store_Base.ATTR_ID_PRODUCT])]
|
# form.id_product.choices = [(json[Store_Base.ATTR_ID_PRODUCT], json[Store_Base.ATTR_ID_PRODUCT])]
|
||||||
form.id_product.data = json[Store_Base.ATTR_ID_PRODUCT]
|
form.id_product.data = json[Store_Base.ATTR_ID_PRODUCT]
|
||||||
form.is_out_of_stock.data = av.input_bool(json[Store_Base.FLAG_IS_OUT_OF_STOCK], Store_Base.FLAG_IS_OUT_OF_STOCK, f'{cls.__name__}.from_json')
|
form.is_out_of_stock.data = av.input_bool(json[Store_Base.FLAG_IS_OUT_OF_STOCK], Store_Base.FLAG_IS_OUT_OF_STOCK, f'{cls.__name__}.from_json')
|
||||||
form.quantity_min.data = json[Store_Base.FLAG_QUANTITY_MIN]
|
form.quantity_min.data = json[Store_Base.FLAG_QUANTITY_MIN]
|
||||||
@@ -65,4 +65,12 @@ class Filters_Stock_Item(Form_Base):
|
|||||||
def get_default(cls):
|
def get_default(cls):
|
||||||
filters = cls()
|
filters = cls()
|
||||||
filters.id_category.choices = cls.get_choices_blank()
|
filters.id_category.choices = cls.get_choices_blank()
|
||||||
filters.id_product.choices = cls.get_choices_blank()
|
filters.id_product.choices = cls.get_choices_blank()
|
||||||
|
"""
|
||||||
|
def import_values(self, form_filters):
|
||||||
|
self.id_category.data = form_filters.id_category.data
|
||||||
|
self.id_product.data = form_filters.id_product.data
|
||||||
|
self.is_out_of_stock.data = form_filters.is_out_of_stock.data
|
||||||
|
self.quantity_min.data = form_filters.quantity_min.data
|
||||||
|
self.quantity_max.data = form_filters.quantity_max.data
|
||||||
|
"""
|
||||||
@@ -23,7 +23,7 @@ from abc import ABCMeta, abstractmethod
|
|||||||
|
|
||||||
|
|
||||||
class Filters_Unit_Measurement(Form_Base):
|
class Filters_Unit_Measurement(Form_Base):
|
||||||
active = BooleanField("Active only?")
|
active = BooleanField("Active only?", default = True)
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_filters(cls, filters):
|
def from_filters(cls, filters):
|
||||||
form = Filters_Unit_Measurement()
|
form = Filters_Unit_Measurement()
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user