commit f1b095ba83015ce89dc042ab6c6070bf1ec2ed82 Author: teddy Date: Wed Apr 17 15:07:51 2024 +0100 Initial commit diff --git a/DEPRECATED - routes.py b/DEPRECATED - routes.py new file mode 100644 index 00000000..4a2b23f6 --- /dev/null +++ b/DEPRECATED - routes.py @@ -0,0 +1,54 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Backend +Feature: Controller - Webpage routing + +Description: +Defines the routes and view functions for each page. +Manages the interaction between the frontend and backend. +""" + +from flask import render_template, url_for, Blueprint +from app import app +from app.forms import Form_Contact +# from forms import MyForm +# from app import MyForm +from models.model_view_contact import Model_View_Contact + +@app.route('/', methods=['GET']) +def home(): + return render_template('_home.html', title='Home') + +@app.route('/store', methods=['GET']) +def store_home(): + return render_template('_store_home.html', title='Store Home') + +@app.route('/contact', methods=['GET', 'POST']) +def contact(): + form = Form_Contact() + if form.validate_on_submit(): + # Handle form submission + email = form.sender_email.data + CC = form.sender_CC.data + name = form.sender_name.data + msg = form.sender_message.data + # return render_template('contact.html', form=form) + # return render_template('_contact.html', title='Contact Us') + return render_template('contact.html', model=Model_View_Contact(form)) + +""" +@app.route('/about') +def about(): + return render_template('about.html') + +@app.route('/contact', methods=['GET', 'POST']) +def contact(): + form = MyForm() + if form.validate_on_submit(): + # Handle form submission + pass + return render_template('contact.html', form=form) +""" \ No newline at end of file diff --git a/README b/README new file mode 100644 index 00000000..ccdef51f --- /dev/null +++ b/README @@ -0,0 +1,10 @@ +Precision and Research Technology Systems Limited +Website with online store + +Powered by flask + +host for machine: +python -m flask run + +host for local network: +python -m flask run --host=0.0.0.0 \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 00000000..03dc31cb --- /dev/null +++ b/__init__.py @@ -0,0 +1,20 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Backend +Feature: Initialisation + +Description: +Initializes the Flask application. +Initializes any extensions used in the project. +""" + +from flask import Flask + +app = Flask(__name__) +app.config.from_object('config') + +# from app import routes +# import business_objects, lib, models diff --git a/__pycache__/__init__.cpython-311.pyc b/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 00000000..070ea838 Binary files /dev/null and b/__pycache__/__init__.cpython-311.pyc differ diff --git a/__pycache__/app.cpython-311.pyc b/__pycache__/app.cpython-311.pyc new file mode 100644 index 00000000..ff497394 Binary files /dev/null and b/__pycache__/app.cpython-311.pyc differ diff --git a/__pycache__/argument_validation.cpython-311.pyc b/__pycache__/argument_validation.cpython-311.pyc new file mode 100644 index 00000000..34b94b60 Binary files /dev/null and b/__pycache__/argument_validation.cpython-311.pyc differ diff --git a/__pycache__/config.cpython-311.pyc b/__pycache__/config.cpython-311.pyc new file mode 100644 index 00000000..bed9d752 Binary files /dev/null and b/__pycache__/config.cpython-311.pyc differ diff --git a/__pycache__/forms.cpython-311.pyc b/__pycache__/forms.cpython-311.pyc new file mode 100644 index 00000000..dda69191 Binary files /dev/null and b/__pycache__/forms.cpython-311.pyc differ diff --git a/__pycache__/model_view_base.cpython-311.pyc b/__pycache__/model_view_base.cpython-311.pyc new file mode 100644 index 00000000..c7bbb367 Binary files /dev/null and b/__pycache__/model_view_base.cpython-311.pyc differ diff --git a/__pycache__/model_view_contact.cpython-311.pyc b/__pycache__/model_view_contact.cpython-311.pyc new file mode 100644 index 00000000..34085b2e Binary files /dev/null and b/__pycache__/model_view_contact.cpython-311.pyc differ diff --git a/__pycache__/model_view_home.cpython-311.pyc b/__pycache__/model_view_home.cpython-311.pyc new file mode 100644 index 00000000..c8aa483d Binary files /dev/null and b/__pycache__/model_view_home.cpython-311.pyc differ diff --git a/__pycache__/model_view_store.cpython-311.pyc b/__pycache__/model_view_store.cpython-311.pyc new file mode 100644 index 00000000..d0acdec3 Binary files /dev/null and b/__pycache__/model_view_store.cpython-311.pyc differ diff --git a/__pycache__/model_view_store_home.cpython-311.pyc b/__pycache__/model_view_store_home.cpython-311.pyc new file mode 100644 index 00000000..7d9d5d40 Binary files /dev/null and b/__pycache__/model_view_store_home.cpython-311.pyc differ diff --git a/__pycache__/pay_stripe.cpython-311.pyc b/__pycache__/pay_stripe.cpython-311.pyc new file mode 100644 index 00000000..6257e563 Binary files /dev/null and b/__pycache__/pay_stripe.cpython-311.pyc differ diff --git a/__pycache__/product.cpython-311.pyc b/__pycache__/product.cpython-311.pyc new file mode 100644 index 00000000..78513ec9 Binary files /dev/null and b/__pycache__/product.cpython-311.pyc differ diff --git a/__pycache__/routes.cpython-311.pyc b/__pycache__/routes.cpython-311.pyc new file mode 100644 index 00000000..6d33ccde Binary files /dev/null and b/__pycache__/routes.cpython-311.pyc differ diff --git a/app.py b/app.py new file mode 100644 index 00000000..82d77974 --- /dev/null +++ b/app.py @@ -0,0 +1,644 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: App General +Feature: App + +Description: +Initializes the Flask application, sets the configuration based on the environment, and defines two routes (/ and /about) that render templates with the specified titles. +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# METHODS + +# IMPORTS +# internal +from config import app_config, Config +# from routes import bp_home +from app.forms import Form_Contact, Form_Basket_Add, Form_Basket_Edit, Form_Billing, Form_Delivery_Region, Form_Currency # , Form_Product +from models.model_view_base import Model_View_Base +from models.model_view_home import Model_View_Home +from models.model_view_store import Model_View_Store +from models.model_view_store_home import Model_View_Store_Home +from models.model_view_store_product import Model_View_Store_Product +from models.model_view_store_basket import Model_View_Store_Basket +from models.model_view_store_checkout import Model_View_Store_Checkout +from models.model_view_store_checkout_success import Model_View_Store_Checkout_Success +from models.model_view_contact import Model_View_Contact +from business_objects.product import Product # , Product_Image_Filters, Resolution_Level_Enum +import lib.argument_validation as av +from business_objects.basket import Basket_Item +from datastores.datastore_store import DataStore_Store +from business_objects.product import Product_Filters +# external +from flask import Flask, render_template, jsonify, request, render_template_string, send_from_directory, redirect, url_for, session +from flask_cors import CORS +from flask_sqlalchemy import SQLAlchemy +import stripe +import json +from dotenv import load_dotenv, find_dotenv +import os +from urllib.parse import quote_plus, urlencode +from authlib.integrations.flask_client import OAuth +import jwt + + +# VARIABLE INSTANTIATION +app = Flask(__name__) +CORS(app) +# app.register_blueprint(bp_home, url_prefix='') +email_recipient = 'edward.middletonsmith@gmail.com' # 'noreply' + +app.config.from_object(app_config) +print(f'secret key = {app.secret_key}') +app.SQLALCHEMY_DATABASE_URI = Config.SQLALCHEMY_DATABASE_URI +app.SQLALCHEMY_TRACK_MODIFICATIONS = Config.SQLALCHEMY_TRACK_MODIFICATIONS +app.ID_AUTH0_CLIENT = Config.ID_AUTH0_CLIENT +app.ID_AUTH0_CLIENT_SECRET = Config.ID_AUTH0_CLIENT_SECRET +app.DOMAIN_AUTH0 = Config.DOMAIN_AUTH0 +app.ID_TOKEN_USER = Config.ID_TOKEN_USER +""" +app.is_included_VAT = Config.is_included_VAT +app.KEY_IS_INCLUDED_VAT = Config.KEY_IS_INCLUDED_VAT +app.code_currency = Config.code_currency +app.KEY_CODE_CURRENCY = Config.KEY_CODE_CURRENCY +app.code_region_delivery = Config.code_region_delivery +app.KEY_CODE_REGION_DELIVERY = Config.KEY_CODE_REGION_DELIVERY +app.KEY_ID_CURRENCY = Config.KEY_ID_CURRENCY +app.KEY_ID_REGION_DELIVERY = Config.KEY_ID_REGION_DELIVERY +app.id_currency = Config.id_currency +app.id_region_delivery = Config.id_region_delivery +""" + +db = SQLAlchemy(app) + +oauth = OAuth(app) +oauth.register( + "auth0", + client_id = app.ID_AUTH0_CLIENT, + client_secret = app.ID_AUTH0_CLIENT_SECRET, # =env.get("AUTH0_CLIENT_SECRET"), + client_kwargs={ + "scope": "openid profile email", + }, + server_metadata_url=f'https://{app.DOMAIN_AUTH0}/.well-known/openid-configuration' +) +# session[app.ID_TOKEN_USER] = {'userinfo': {'sub': ''}} + + +# METHODS + + +# ROUTING +@app.route('/', methods=['GET']) +def home(): + return render_template('_page_home.html', model=Model_View_Home(db, get_info_user(), app)) + + +@app.route('/contact', methods=['GET', 'POST']) +def contact(): + form = Form_Contact() + if form.validate_on_submit(): + # Handle form submission + email = form.email.data + CC = form.CC.data # not in use + name = form.name.data + msg = form.msg.data + # send email + pass + return render_template('_page_contact.html', model=Model_View_Contact(db, get_info_user(), app, form)) + + +# Store +@app.route('/store', methods=['GET']) +def store_home(): + print("store home") + try: + data = request.json + except: + data = {} + print(f'data={data}') + try: + id_currency = data.id_currency + except: + id_currency = Model_View_Store.ID_CURRENCY_DEFAULT + print(f"id_currency = {id_currency}") + try: + id_region_delivery = data.id_region_delivery + except: + id_region_delivery = Model_View_Store.ID_REGION_DELIVERY_DEFAULT + print(f"id_region_delivery = {id_region_delivery}") + model = Model_View_Store_Home(db, get_info_user(), app, id_currency, id_region_delivery) + # model.get_regions_and_currencies() + # model.categories = Model_View_Store_Home.get_many_product_category(db) + # product = categories[list(categories.keys())[0]][0] + model.get_many_product_category(Product_Filters( + model.id_user, + True, '', False, + True, '', False, False, + True, '', False, + False, '', False, True, + False, id_region_delivery, False, + False, id_currency, False, + True, '', False + )) + """ + for cat in model.categories: + # for product in model.categories[cat]: + i_cat = model.category_index[cat.id_category] + for p in cat.products: + print(f'adding basket add form for product with id: {p.id_product}') + model.categories[i_cat].products[model.categories[i_cat].product_index[p.id_product]].add_form_basket_add() + model.categories[i_cat].products[model.categories[i_cat].product_index[p.id_product]].form_basket_add = Form_Basket_Add() + print('form added') + # print('form added for product {p.id}') + print('rendering page store home') + """ + for cat in model.category_list.categories: + # for product in model.categories[cat]: + # i_cat = model.category_index[cat.id_category] + print(f'category: {cat.name}') + for p in cat.products: + print(f'product: {p.name}') + print(f'selected permutation: {p.get_permutation_selected()}') + return render_template('_page_store_home.html', model = model) # "

Boobs

" + # POST request + # return jsonify(Success=True, data={'html_block': render_template('_page_store_home.html', model = model)}) + +# update with local basket, if not logged in- partial +@app.route('/store/basket_load', methods=['POST']) +def basket_load(): + _m = 'basket_load' + print(f'{_m}\nstarting...') + data = request.json + print(f'data={data}') + + # model, html_block = render_basket_from_JSON(data) + id_currency, id_region_delivery, is_included_VAT = DataStore_Store.get_metadata_basket(data) + model = Model_View_Store_Home(db, get_info_user(), app, id_currency, id_region_delivery) + # model.import_JSON_basket(data) + model.get_basket(data) + model.is_included_VAT = is_included_VAT + + html_block = render_template('_block_store_basket.html', model = model) + print(f'html_block:\n{html_block}') + return jsonify(Success=True, data={'html_block': html_block, 'basket': model.basket.to_json()}) # {'items': [b_i.to_json() for b_i in model.basket]}}) # { 'html': render_template('_block_store_basket.html', model = model), 'basket': model.basket }) + +@app.route('/store/basket_add', methods=['POST']) +def basket_add(): + _m = 'basket_add' + data = request.json # .get('data') + print(f'data: {data}') + id_currency, id_region_delivery, is_included_VAT = DataStore_Store.get_metadata_basket(data) + model = Model_View_Store_Home(db, get_info_user(), app, id_currency, id_region_delivery) + model.is_included_VAT = is_included_VAT + form_data = data[Model_View_Store.key_form] + print(f'form_data: {form_data}') + form = Form_Basket_Add(**form_data) + print('form acquired') + print(form.__repr__) + if form.validate_on_submit(): + print('valid form') + # model = input_JSON_basket(model, data) + # if not logged in: + try: + print('importing basket') + # print('success' if model.import_JSON_basket(data) else 'failure') + model.get_basket(data) + permutation_id, quantity = model.import_JSON_basket_item(data, form) + print(f'permutation_id: {permutation_id}\nquantity: {quantity}') + print(f'editing basket:') + model.basket_item_edit(permutation_id, quantity, True) # new_basket = + except: + return jsonify({'status': 'failure', 'Message': 'Bad data received by controller'}) + # return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket }) + html_block = render_template('_block_store_basket.html', model = model) + # print(f'html_block:\n{html_block}') + return jsonify(Success = True, data = { 'html_block': html_block, 'basket': {'items': model.basket.to_json_list()}}) # 'items': [b_i.to_json() for b_i in model.basket]}}) + return jsonify({'status': 'failure', 'Message': 'Invalid quantities'}) + + + +@app.route('/store/basket_edit', methods=['POST']) +def basket_edit(): + _m = 'basket_edit' + data = request.json # .get('data') + print(f'data: {data}') + id_currency, id_region_delivery, is_included_VAT = DataStore_Store.get_metadata_basket(data) + model = Model_View_Store_Home(db, get_info_user(), app, id_currency, id_region_delivery) + model.is_included_VAT = is_included_VAT + form_data = data[Model_View_Store.key_form] + print(f'form_data: {form_data}') + form = Form_Basket_Edit(**form_data) + print('form acquired') + print(form.__repr__) + if form.validate_on_submit(): + print('valid form') + # model = input_JSON_basket(model, data) + # if not logged in: + try: + # print('importing basket') + # model.import_JSON_basket(data) + model.get_basket(data) + permutation_id, quantity = model.import_JSON_basket_item(data, form) + model.basket_item_edit(permutation_id, quantity, False) # new_basket = + except: + return jsonify({'status': 'failure', 'Message': 'Bad data received by controller'}) + # return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket }) + html_block = render_template('_block_store_basket.html', model = model) + # print(f'html_block:\n{html_block}') + return jsonify(Success = True, data = { 'html_block': html_block, 'basket': {'items': model.basket.to_json_list()}}) + return jsonify({'status': 'failure', 'Message': 'Invalid quantities'}) + +@app.route('/store/basket_delete', methods=['POST']) +def basket_delete(): + _m = 'basket_delete' + data = request.json # .get('data') + print(f'data: {data}') + id_currency, id_region_delivery, is_included_VAT = DataStore_Store.get_metadata_basket(data) + model = Model_View_Store_Home(db, get_info_user(), app, id_currency, id_region_delivery) + model.is_included_VAT = is_included_VAT + try: + # print('importing basket') + # model.import_JSON_basket(data) + model.get_basket(data) + permutation_id, quantity = model.import_JSON_basket_item(data) + model.basket_item_edit(permutation_id, 0, False) # new_basket = + except: + return jsonify({'status': 'failure', 'Message': 'Bad data received by controller'}) + # return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket }) + html_block = render_template('_block_store_basket.html', model = model) + # print(f'html_block:\n{html_block}') + return jsonify(Success = True, data = { 'html_block': html_block, 'basket': {'items': model.basket.to_json_list()}}) + # delete basket item with product_id + item_deleted = False + for basket_item in model.basket: + if basket_item.product.id_product == product_id: + model.basket.remove(basket_item) + item_deleted = True + break + if not item_deleted: + return jsonify({'status': 'failure', 'Message': 'Basket item removal failure: product not found in basket.'}) + # return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket }) + html_block = render_template('_block_store_basket.html', model = model) + # print(f'html_block:\n{html_block}') + return jsonify(Success = True, data = { 'html_block': html_block, 'basket': {'items': [b_i.to_json() for b_i in model.basket]}}) + +@app.route('/store/basket', methods=['GET']) # 'POST' +def store_basket(): + # _m = 'basket_review' + try: + data = request.json + id_currency, id_region_delivery, is_included_VAT = DataStore_Store.get_metadata_basket(data) + model = Model_View_Store_Basket(db, get_info_user(), app, id_currency, id_region_delivery) + model.is_included_VAT = is_included_VAT + except: + raise Exception('Bad data received by controller') + return render_template('_page_store_basket.html', model=model) + data = request.json # .get('data') + print(f'data: {data}') + # if logged in + #html_block = render_template('_page_store_basket.html', model = model) # with basket from database + try: + print('importing basket') + model.import_JSON_basket(data) + except: + return jsonify({'status': 'failure', 'Message': 'Bad basket data received by controller'}) + # return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket }) + html_block = render_template('_page_store_billing.html', model = model) + # print(f'html_block:\n{html_block}') + return jsonify(Success = True, data = { 'html_block': html_block, 'basket': {'items': [b_i.to_json() for b_i in model.basket]}}) + +@app.route('/store/basket_info', methods=['POST']) +def basket_info(): + _m = 'basket_info' + data = request.json # .get('data') + print(f'data: {data}') + model = Model_View_Store_Basket(db, get_info_user(), app) + form_data = data[Model_View_Store.key_form] + print(f'form_data: {form_data}') + form = Form_Billing(**form_data) + print('form acquired') + print(form.__repr__) + if form.validate_on_submit(): + print('valid form') + # model = input_JSON_basket(model, data) + # if not logged in: + data_info = {} + try: + info_type = data[model.key_info_type] + print('importing address information') + data_info[model.key_region] = form.region.data + print(f'region: {data_info[model.key_region]}') + data_info[model.key_name_full] = form.name_full.data + print(f'full name: {data_info[model.key_name_full]}') + data_info[model.key_phone_number] = form.phone_number.data + print(f'phone number: {data_info[model.key_phone_number]}') + data_info[model.key_postcode] = form.postcode.data + print(f'postcode: {data_info[model.key_postcode]}') + data_info[model.key_address1] = form.address_1.data + print(f'address line 1: {data_info[model.key_address1]}') + data_info[model.key_address2] = form.address_2.data + print(f'address line 2: {data_info[model.key_address2]}') + data_info[model.key_city] = form.city.data + print(f'city: {data_info[model.key_city]}') + data_info[model.key_county] = form.county.data + print(f'county: {data_info[model.key_county]}') + data_info[model.key_info_identical] = form.identical + print(f'identical: {data_info[model.key_info_identical]}') + except: + return jsonify({'status': 'failure', 'Message': 'Bad form data received by controller'}) + # return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket }) + # html_block = render_template('_block_store_basket.html', model = model) + # print(f'html_block:\n{html_block}') + data = {} + data[model.key_info_type] = model.key_info_billing if (info_type == model.key_info_billing) else model.key_info_delivery + data[info_type] = data_info + return jsonify(Success = True, data = data) + return jsonify({'status': 'failure', 'Message': f'Invalid address information\n{form.errors}'}) + + +@app.route('/store/product?permutationId=regionId=&¤cyId=', methods=['GET']) # & +def store_product(permutation_id, region_id, currency_id): + _m = 'store_product' + """ + av.full_val_int(product_id, 'product_id', _m) + product_id = int(product_id) + print(f'product_id: {product_id}') + if permutation_id == 'None' or str(type(permutation_id)) == "": + permutation_id = None + else: + """ + # app.id_region_delivery = region_id + # app.id_currency = currency_id + av.full_val_int(permutation_id, 'permutation_id', _m) + permutation_id = int(permutation_id) + print(f'{_m}\nstarting...') + # print(f'product id: {product_id}') + print(f'permutation id: {permutation_id}') + try: + model = Model_View_Store_Product(db, get_info_user(), app, permutation_id, currency_id, region_id) + print('model reached') + # model.id_currency, model.id_region_delivery, model.is_included_VAT = DataStore_Store.get_metadata_basket(request.json) + # model.get_many_product_category(product_ids = str(product_id)) + # print('categories reached') + # product = model.categories[0].products[0]# [list(categories.keys())[0]][0] + # print('product reached') + # return jsonify({'data': render_template('_page_store_product.html', model=model)}) + permutation_selected = model.product.get_permutation_selected() + print(f'selected permutation: {permutation_selected}') + return render_template('_page_store_product.html', model=model) + except: + print('except reached') + return jsonify({'status': 'error'}) + +# Stripe +@app.route('/config', methods=['GET']) +def get_publishable_key(): + price = stripe.Price.retrieve(Model_View_Store_Checkout.get_price_id(Product.template().id)) + return jsonify({ + 'publicKey': Model_View_Store_Checkout.key_public_stripe, # os.getenv('KEY_PUBLIC_STRIPE'), + 'unitAmount': price['unit_amount'], + 'currency': price['currency'] + }) + +# Create Stripe prices +@app.route('/store/product_create_all', methods=['GET']) +def product_create_all(): + # _m = 'product_create_all' + model = Model_View_Store_Checkout(db, get_info_user(), app) + products, currencies = model.get_many_product_new() + html = f"" + for product in products: + product.id_stripe_product = model.create_product(product) + html += f"

product id = {product.id}


id_stripe_product = {product.id_stripe_product}

" + html += "" + + return html + +@app.route('/store/price_create_all', methods=['GET']) +def price_create_all(): + # _m = 'price_create_all' + model = Model_View_Store_Checkout(db, get_info_user(), app) + products, currencies = model.get_many_price_new() + html = f"" + for product in products: + product.id_stripe_price = model.create_price(product, currencies[product.id]) + html += f"

product id = {product.id}


id_stripe_price = {product.id_stripe_price}


currency = {currencies[product.id]}

" + html += "" + + return html + +# Fetch the Checkout Session to display the JSON result on the success page +@app.route('/store/checkout_session?', methods=['GET']) +def get_checkout_session(session_id): + id = request.args.get('session_id') + _m = 'get_checkout_session' + # av.full_val_int(session_id, 'session_id', _m) + av.val_str(session_id, 'session_id', _m) + print(f'url var normal session id: {session_id}') + print(f'{_m}\nstarting...') + # session_id = id + session_id = session_id + print(f'request.args checkout session id: {session_id}') # for function + checkout_session = stripe.checkout.Session.retrieve(session_id) + return jsonify(checkout_session) + + +@app.route('/store/checkout', methods=['POST', 'GET']) +def create_checkout_session(): + # quantity = request.form.get('quantity', 1) + # domain_url = os.getenv('DOMAIN') + model = Model_View_Store_Checkout(db, get_info_user(), app) + print('checkout model created') + try: + data = request.json # .get('data') + print(f'data: {data}') + print('importing basket') + model.get_basket(data) + model.id_currency, model.id_region_delivery, model.is_included_VAT = DataStore_Store.get_metadata_basket(data) + # model.import_JSON_basket(data) + # print('getting is subscription') + # is_subscription_checkout_session = data[model.key_is_subscription] + code_currency = 'GBP' # data[model.key_code_currency] + print(f'currency code: {code_currency}') + except: + return jsonify({'status': 'failure', 'Message': 'Bad form data received by controller'}) + items = [] + for item in model.basket.items: + permutation = item.product.get_permutation_selected() + price = permutation.get_price_from_code_currency(code_currency) + items.append({'price': price.id_stripe_price, + 'quantity': item.quantity }) + # if is_subscription_checkout_session: + # break + print(f'items = {items}') + try: + # Create new Checkout Session for the order + # Other optional params include: + # [billing_address_collection] - to display billing address details on the page + # [customer] - if you have an existing Stripe Customer ID + # [payment_intent_data] - lets capture the payment later + # [customer_email] - lets you prefill the email input in the form + # [automatic_tax] - to automatically calculate sales tax, VAT and GST in the checkout page + # For full details see https://stripe.com/docs/api/checkout/sessions/create + stripe.api_key = model.key_secret_stripe + # ?session_id={CHECKOUT_SESSION_ID} means the redirect will have the session ID set as a query param + checkout_session = stripe.checkout.Session.create( + success_url=Model_View_Store_Checkout.url_host + '/store/checkout_success%3Fsession_id={CHECKOUT_SESSION_ID}', + cancel_url=Model_View_Store_Checkout.url_host + '/store/checkout_cancelled', + mode='subscription' if False else 'payment', # is_subscription_checkout_session + # automatic_tax={'enabled': True}, + line_items=items + ) + data_out = {} + # data_out['Success'] = True + data_out[f'{model.key_id_checkout}'] = checkout_session.id + data_out[f'{model.key_url_checkout}'] = checkout_session.url + # return jsonify(Success = True, data = data_out) # Success = True, f'{model.key_id_checkout}' = checkout_session.id) + print(f'checkout session url: {checkout_session.url}') + # redirect(checkout_session.url) # , code=303) + return jsonify(Success = True, data = data_out) + # return get_checkout_session(checkout_session.id) + except Exception as e: + return jsonify(error=str(e)), 403 + +@app.route('/store/checkout_success?', methods=['GET']) +def checkout_success(session_id): + _m = 'store checkout success' + # av.full_val_int(session_id, 'session_id', _m) + av.val_str(session_id, 'session_id', _m) + if (session_id[:len('session_id=')] == 'session_id='): + session_id = session_id[len('session_id='):] + print(f'url var normal session id: {session_id}') + print(f'{_m}\nstarting...') + id = request.args.get('sessionId') + print(f'request.args checkout session id: {id}') + + checkout_session = stripe.checkout.Session.retrieve(session_id) + print(f'checkout session data: {checkout_session}') + + # validate billing information + + + model = Model_View_Store_Checkout_Success(db, get_info_user(), app) + + return render_template('_page_store_checkout_success.html', model=model) + +@app.route('/store/checkout_cancelled', methods=['GET']) +def checkout_cancelled(): + _m = 'store checkout success' + print(f'{_m}\nstarting...') + return render_template('_page_store_checkout_cancelled.html', model=Model_View_Store_Checkout(db, get_info_user(), app)) + + +# include VAT in prices? +@app.route('/store/set_is_included_VAT', methods=['POST']) +def set_is_included_VAT(): + _m = 'set_is_included_VAT' + print(f'{_m}\nstarting...') + data = request.json + print(f'data={data}') + app.is_included_VAT = not app.is_included_VAT # session[app.KEY_IS_INCLUDED_VAT] # data[app.KEY_IS_INCLUDED_VAT] + return jsonify(Success=True, data={Model_View_Base.KEY_IS_INCLUDED_VAT: app.is_included_VAT}) + +# delivery region +@app.route('/store/set_delivery_region', methods=['POST']) +def set_delivery_region(): + _m = 'set_delivery_region' + print(f'{_m}\nstarting...') + data = request.json + print(f'data={data}') + # model = Model_View_Store(db, get_info_user(), app) + form_data = data[Model_View_Store.key_form] + print(f'form_data: {form_data}') + """ + form = Form_Delivery_Region(**form_data) + print('form acquired') + print(form.__repr__) + if form.validate_on_submit(): + app.id_region_delivery = form.id_region_delivery.data + """ + app.id_region_delivery = form_data[Model_View_Base.KEY_ID_REGION_DELIVERY] + print(f'id_region_delivery: {app.id_region_delivery}') + return jsonify(Success=True, data={Model_View_Base.KEY_ID_REGION_DELIVERY: app.id_region_delivery}) + +# currency +@app.route('/store/set_currency', methods=['POST']) +def set_currency(): + _m = 'set_currency' + print(f'{_m}\nstarting...') + data = request.json + print(f'data={data}') + # model = Model_View_Store(db, get_info_user(), app) + form_data = data[Model_View_Store.key_form] + print(f'form_data: {form_data}') + """ + form = Form_Currency(**form_data) + print('form acquired') + print(form.__repr__) + if form.validate_on_submit(): + app.id_currency = form.id_currency.data + print(f'id_currency: {app.id_currency}') + """ + app.id_currency = form_data[Model_View_Base.KEY_ID_CURRENCY] + print(f'id_currency: {app.id_currency}') + return jsonify(Success=True, data={Model_View_Base.KEY_ID_CURRENCY: app.id_currency}) + + +# User authentication +@app.route("/login") +def login(): + print(f'redirect uri: {url_for("login_callback", _external=True)}') + return oauth.auth0.authorize_redirect( + redirect_uri=url_for("login_callback", _external=True) + ) + +@app.route("/login_callback", methods=["GET", "POST"]) +def login_callback(): + token = oauth.auth0.authorize_access_token() + session[app.ID_TOKEN_USER] = token + + # import user id + print(f'str(type(token)) = {str(type(token))}') + print(f'token = {token}') + userinfo = token.get('userinfo') + print(f'user info: {userinfo}') + # id_user = token.get('sub') + id_user = userinfo.get('sub') + print(f'user ID: {id_user}') + + # id_user = get_id_user() + # add user to database + # DataStore_Store(db, userinfo).add_new_user(id_user) # this is part of get basket - should occur on page load + + return redirect("/") + +@app.route("/logout") +def logout(): + session.clear() + return redirect( + "https://" + app.DOMAIN_AUTH0 + + "/v2/logout?" + + urlencode( + { + "returnTo": url_for("home", _external=True), + "client_id": app.ID_AUTH0_CLIENT, + }, + quote_via=quote_plus, + ) + ) + +def get_info_user(): + try: + return session[app.ID_TOKEN_USER].get('userinfo') # .get('sub') + except: + return {'sub': ''} + + +# Onload +if __name__ == '__main__': + # app.run() + app.run(debug=True, host="0.0.0.0", port=5000) \ No newline at end of file diff --git a/business_objects/__init__.py b/business_objects/__init__.py new file mode 100644 index 00000000..0ed1a26c --- /dev/null +++ b/business_objects/__init__.py @@ -0,0 +1,11 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Module Initialisation +Feature: Business Objects + +Description: +Initialises business objects module. +""" diff --git a/business_objects/__pycache__/__init__.cpython-311.pyc b/business_objects/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 00000000..c98cc42e Binary files /dev/null and b/business_objects/__pycache__/__init__.cpython-311.pyc differ diff --git a/business_objects/__pycache__/basket.cpython-311.pyc b/business_objects/__pycache__/basket.cpython-311.pyc new file mode 100644 index 00000000..0c1f504e Binary files /dev/null and b/business_objects/__pycache__/basket.cpython-311.pyc differ diff --git a/business_objects/__pycache__/category.cpython-311.pyc b/business_objects/__pycache__/category.cpython-311.pyc new file mode 100644 index 00000000..65343486 Binary files /dev/null and b/business_objects/__pycache__/category.cpython-311.pyc differ diff --git a/business_objects/__pycache__/currency.cpython-311.pyc b/business_objects/__pycache__/currency.cpython-311.pyc new file mode 100644 index 00000000..8908a0d6 Binary files /dev/null and b/business_objects/__pycache__/currency.cpython-311.pyc differ diff --git a/business_objects/__pycache__/delivery_option.cpython-311.pyc b/business_objects/__pycache__/delivery_option.cpython-311.pyc new file mode 100644 index 00000000..ee996e8d Binary files /dev/null and b/business_objects/__pycache__/delivery_option.cpython-311.pyc differ diff --git a/business_objects/__pycache__/delivery_region.cpython-311.pyc b/business_objects/__pycache__/delivery_region.cpython-311.pyc new file mode 100644 index 00000000..c0f6e2b4 Binary files /dev/null and b/business_objects/__pycache__/delivery_region.cpython-311.pyc differ diff --git a/business_objects/__pycache__/discount.cpython-311.pyc b/business_objects/__pycache__/discount.cpython-311.pyc new file mode 100644 index 00000000..f581f319 Binary files /dev/null and b/business_objects/__pycache__/discount.cpython-311.pyc differ diff --git a/business_objects/__pycache__/image.cpython-311.pyc b/business_objects/__pycache__/image.cpython-311.pyc new file mode 100644 index 00000000..c04cd308 Binary files /dev/null and b/business_objects/__pycache__/image.cpython-311.pyc differ diff --git a/business_objects/__pycache__/order.cpython-311.pyc b/business_objects/__pycache__/order.cpython-311.pyc new file mode 100644 index 00000000..aebfe3f3 Binary files /dev/null and b/business_objects/__pycache__/order.cpython-311.pyc differ diff --git a/business_objects/__pycache__/product.cpython-311.pyc b/business_objects/__pycache__/product.cpython-311.pyc new file mode 100644 index 00000000..f2d0372b Binary files /dev/null and b/business_objects/__pycache__/product.cpython-311.pyc differ diff --git a/business_objects/__pycache__/sql_error.cpython-311.pyc b/business_objects/__pycache__/sql_error.cpython-311.pyc new file mode 100644 index 00000000..98bcccb1 Binary files /dev/null and b/business_objects/__pycache__/sql_error.cpython-311.pyc differ diff --git a/business_objects/__pycache__/variation.cpython-311.pyc b/business_objects/__pycache__/variation.cpython-311.pyc new file mode 100644 index 00000000..99b191c2 Binary files /dev/null and b/business_objects/__pycache__/variation.cpython-311.pyc differ diff --git a/business_objects/basket.py b/business_objects/basket.py new file mode 100644 index 00000000..3ee058f5 --- /dev/null +++ b/business_objects/basket.py @@ -0,0 +1,164 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: Basket Business Object + +Description: +Business object for basket +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# CLASSES +# METHODS + +# IMPORTS +# internal +import lib.argument_validation as av +# from lib import data_types +from business_objects.product import Product, Product_Filters +from business_objects.discount import Discount +from business_objects.delivery_option import Delivery_Option +# from forms import Form_Product +# from models.model_view_store import Model_View_Store # circular +# from datastores.datastore_store import DataStore_Store # circular +# from forms import Form_Basket_Add, Form_Basket_Edit # possibly circular +# external +# from enum import Enum +from flask import jsonify +import locale + + +# VARIABLE INSTANTIATION + +# CLASSES +class Basket_Item(): + product: Product + quantity: int + delivery_option: Delivery_Option + discounts: list + # form: Form_Product + is_included_VAT: bool + + """ + def __init__(self): + self.is_unavailable_in_currency_or_region = False + self.is_available = True + """ + + def make_from_product_and_quantity_and_VAT_included(product, quantity, is_included_VAT): + # Initialiser - validation + _m = 'Basket_Item.make_from_product_and_quantity' + v_arg_type = 'class attribute' + av.val_instance(product, 'product', _m, Product, v_arg_type=v_arg_type) + av.full_val_float(quantity, 'quantity', _m, product.get_quantity_min(), v_arg_type=v_arg_type) + basket_item = Basket_Item() + basket_item.product = product + basket_item.quantity = quantity + basket_item.is_included_VAT = is_included_VAT + return basket_item + + def add_discount(self, discount): + av.val_instance(discount, 'discount', 'Basket_Item.add_discount', Discount, v_arg_type='class attribute') + self.discounts.append(discount) + + def set_delivery_option(self, delivery_option): + av.val_instance(delivery_option, 'delivery_option', 'Basket_Item.set_delivery_option', Delivery_Option, v_arg_type='class attribute') + self.delivery_option = delivery_option + + def update_quantity(self, quantity): + _m = 'Basket_Item.update_quantity' + v_arg_type = 'class attribute' + av.full_val_float(quantity, 'quantity', _m, self.product.get_quantity_min(), v_arg_type=v_arg_type) + self.quantity = quantity + + def jsonify(self): + return jsonify(self) + + def to_json(self): + permutation = self.product.get_permutation_selected() + return { + 'product_id': self.product.id_product, + 'permutation_id': permutation.id_permutation, + 'price': permutation.output_price(self.is_included_VAT), + 'quantity': self.quantity + } + + def get_subtotal(self): + permutation = self.product.get_permutation_selected() + return round(self.product.get_price_local(self.is_included_VAT) * self.quantity, 2) if permutation.is_available else 0 + + def output_currency(self): + return self.product.output_currency() + + def output_subtotal(self): + locale.setlocale(locale.LC_ALL, '') + subtotal = self.get_subtotal() + permutation = self.product.get_permutation_selected() + return 'Not available in this currency or region' if permutation.is_unavailable_in_currency_or_region else 'Not available' if not permutation.is_available else f'{self.product.output_currency()} {locale.format_string("%d", subtotal, grouping=True)}' + + def __repr__(self): + return f''' + product: {self.product} + quantity: {self.quantity} + subtotal: {self.get_subtotal()} + ''' + +class Basket(): + items: list + def __init__(self): + self.items = [] + def add_item(self, item): + av.val_instance(item, 'item', 'Basket.add_item', Basket_Item) + self.items.append(item) + def to_csv(self): + ids_permutation = '' + quantities_permutation = '' + for b_i in range(len(self.items)): + basket_item = self.items[b_i] + product = basket_item.product + if b_i > 0: + ids_permutation += ',' + quantities_permutation += ',' + ids_permutation += str(product.get_id_permutation()) + quantities_permutation += str(basket_item.quantity) + print(f'ids_permutation_basket = {ids_permutation}') + print(f'quantities_permutation_basket = {quantities_permutation}') + return ids_permutation, quantities_permutation + def to_json_list(self): + json_list = [] + for item in self.items: + json_list.append(item.to_json()) + return json_list + def to_json(self): + return {'items': self.to_json_list()} + def output_total(self): + sum = 0 + for b_i in self.items: + sum += b_i.get_subtotal() + symbol = self.items[0].output_currency() if len(self.items) > 0 else '' + + return f'{symbol} {locale.format_string("%d", sum, grouping=True)}' + def len(self): + return len(self.items) + """ + def get_key_product_index_from_ids_product_permutation(id_product, id_permutation): + return f'{id_product},{"" if id_permutation is None else id_permutation}' + """ + def __repr__(self): + repr = f'Basket:' + for basket_item in self.items: + print(f'{basket_item}') + repr = f'{repr}\n{basket_item}' + return repr + + def get_ids_permutation_unavailable(self): + ids_permutation = [] + for item in self.items: + permutation = item.product.get_permutation_selected() + if not permutation.is_available: + ids_permutation.append(permutation.id_permutation) + return ids_permutation \ No newline at end of file diff --git a/business_objects/category.py b/business_objects/category.py new file mode 100644 index 00000000..c696cecd --- /dev/null +++ b/business_objects/category.py @@ -0,0 +1,273 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: Product Category Business Object + +Description: +Business object for product +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# CLASSES +# METHODS + +# IMPORTS +# internal +import lib.argument_validation as av +from lib import data_types +from forms import Form_Basket_Add, Form_Basket_Edit # Form_Product +from business_objects.product import Product, Product_Permutation, Price +from business_objects.variation import Variation +from business_objects.image import Image +from business_objects.delivery_option import Delivery_Option +from business_objects.discount import Discount +# external +from enum import Enum +from datetime import datetime, timedelta +import locale +from flask_sqlalchemy import SQLAlchemy + + +# VARIABLE INSTANTIATION +db = SQLAlchemy() + + +# CLASSES +class Enum_Product_Category(Enum): + ASSISTIVE_DEVICES = 0 + HOME_DECOR = 1 + MISCELLANEOUS = 99 + + def text(self): + return Enum_Product_Category.Enum_Product_Category_Text(self) + + def Enum_Product_Category_Text(category): + av.val_instance(category, 'category', 'Product_Category_Enum_Text', Enum_Product_Category) + if category == Enum_Product_Category.ASSISTIVE_DEVICES: + return 'Assistive devices' + elif category == Enum_Product_Category.HOME_DECOR: + return 'Home decor' + else: + return 'Other' + + def get_member_by_text(text): + av.val_str(text, 'text', 'Enum_Product_Category.get_member_by_text') + return data_types.get_enum_member_by_text(Enum_Product_Category, text.upper()) + + +class Category(db.Model): + id_category = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(255)) + description = db.Column(db.String(4000)) + display_order = db.Column(db.Integer) + """ + def __new__(cls, id, name, description, display_order): + _m = 'Category.__new__' + v_arg_type = 'class attribute' + av.val_int(id, 'id', _m, 0, v_arg_type=v_arg_type) + av.val_str(name, 'name', _m, max_len=256, v_arg_type=v_arg_type) + av.val_str(description, 'description', _m, max_len=4001, v_arg_type=v_arg_type) + av.val_int(display_order, 'display_order', _m, v_arg_type=v_arg_type) + return super(Category, cls).__new__(cls) + """ + def __init__(self): # , id, name, description, display_order): + """ + self.id_category = id + self.name = name + self.description = description + self.display_order = display_order + """ + self.products = [] + self.product_index = {} + super().__init__() + + def make_from_DB_product(query_row): + category = Category() + category.id_category = query_row[0] + category.name = query_row[1] + category.description = query_row[2] + category.display_order = query_row[3] + return category + """ + def key_product_index_from_ids_product_permutation(id_product, id_permutation): + return f'{id_product},{"" if id_permutation is None else id_permutation}' + def key_product_index_from_product(product): + av.val_instance(product, 'product', 'Category.key_product_index_from_product', Product) + return f'{product.id_product},{"" if product.id_permutation is None else product.id_permutation}' + """ + def get_index_product(self, product): + return self.get_index_product_from_id(product.id_product) + def get_index_product_from_id(self, id_product): + try: + return self.product_index[id_product] + except: + raise KeyError(f'product id: {id_product} not in product index keys: {self.product_index.keys()} with category id: {self.id_category}') + def get_index_product_from_id_permutation(self, id_permutation): + for product in self.products: + try: + index_permutation = product.get_index_permutation_from_id(id_permutation) + return self.get_index_product(product) + except: + pass + raise KeyError(f'permutation id: {id_permutation} not in category id: {self.id_category}') + + def add_product(self, product): + _m = 'Category.add_product' + av.val_instance(product, 'product', _m, Product) + # self.product_index.append(len(self.products)) + # self.product_index[Category.key_product_index_from_ids_product_permutation(product.id_product, product.id_permutation)] = len(self.products) + try: + self.get_index_product(product) + raise ValueError(f"{av.error_msg_str(product, 'product', _m, Product)}\nProduct already in category.") + except KeyError: + self.product_index[product.id_product] = len(self.products) + self.products.append(product) + def add_permutation(self, permutation): + _m = 'Category.add_permutation' + av.val_instance(permutation, 'permutation', _m, Product_Permutation) + # self.product_index.append(len(self.products)) + # self.product_index[Category.key_product_index_from_ids_product_permutation(product.id_product, product.id_permutation)] = len(self.products) + index_product = self.get_index_product_from_id(permutation.id_product) + # index_product = self.product_index[permutation.id_product] + self.products[index_product].add_permutation(permutation) + def add_variation(self, variation): + av.val_instance(variation, 'variation', 'Category.add_variation', Variation) + index_product = self.get_index_product_from_id(variation.id_product) + self.products[index_product].add_variation(variation) + def add_price(self, price): + av.val_instance(price, 'price', 'Category.add_price', Price) + index_product = self.get_index_product_from_id(price.id_product) + self.products[index_product].add_price(price) + def add_image(self, image): + av.val_instance(image, 'image', 'Category.add_image', Image) + index_product = self.get_index_product_from_id(image.id_product) + self.products[index_product].add_image(image) + def add_delivery_option(self, delivery_option): + av.val_instance(delivery_option, 'delivery_option', 'Category.add_delivery_option', Delivery_Option) + index_product = self.get_index_product_from_id(delivery_option.id_product) + self.products[index_product].add_delivery_option(delivery_option) + def add_discount(self, discount): + av.val_instance(discount, 'discount', 'Category.add_discount', Discount) + index_product = self.get_index_product_from_id(discount.id_product) + self.products[index_product].add_discount(discount) + + def get_all_variation_trees(self): + for product in self.products: + if product.has_variations: + print(f'product with id:{product.id_product} has variations') + product.get_variation_trees() + + """ + def index_product_from_ids_product_permutation(self, id_product, id_permutation): + key = Category.key_product_index_from_ids_product_permutation(id_product, id_permutation) + print(f'product_index: {self.product_index}') + print(f'Key Error: {key}') + try: + return self.product_index[key] + except KeyError: + pass + """ + def __repr__(self): + return f''' + id: {self.id_category} + name: {self.name} + description: {self.description} + display_order: {self.display_order} + products: {self.products} + ''' + + def get_permutation_first(self): + if not (len(self.products) == 0): + print(f'getting first permutation from product') + return None if len(self.products) == 0 else self.products[0].get_permutation_selected() + + +class Product_Category_Filters(): + category_ids: str # csv + product_ids: str # csv + + def __new__(cls, product_ids, product_categories): + # Initialiser - validation + _m = 'Product_Filters.__new__' + v_arg_type = 'class attribute' + # av.val_list_instances(product_ids, 'product_ids', _m, str, v_arg_type=v_arg_type) + # av.val_list_instances(product_categories, 'product_categories', _m, Product_Category_Enum, v_arg_type=v_arg_type) + av.val_str(product_ids, 'product_ids', _m, v_arg_type=v_arg_type) + av.val_str(product_categories, 'product_categories', _m, v_arg_type=v_arg_type) + return super(Product_Category_Filters, cls).__new__(cls) + + def __init__(self, product_ids, product_categories): + # Constructor + self.ids = product_ids + self.categories = product_categories + +class Category_List(): + categories: list + def __init__(self): + self.categories = [] + def add_category(self, category): + av.val_instance(category, 'category', 'Category_List.add_category', Category) + self.categories.append(category) + def get_index_category_from_id(self, id_category): + for index_category in range(len(self.categories)): + category = self.categories[index_category] + if category.id_category == id_category: + return index_category + raise ValueError(f"{av.error_msg_str(id_category, 'id_category', 'Category_List.get_index_category_from_id', int)}\nID not in list") + def get_index_category_from_id_permutation(self, id_permutation): + for index_category in range(len(self.categories)): + category = self.categories[index_category] + try: + index_product = category.get_index_product_from_id_permutation(id_permutation) + return index_category + except: + pass + raise ValueError(f"{av.error_msg_str(id_permutation, 'id_permutation', 'Category_List.get_index_category_from_id_permutation', int)}. Permutation ID not in list") + def add_product(self, product): + av.val_instance(product, 'product', 'Category_List.add_product', Product) + index_category = self.get_index_category_from_id(product.id_category) + self.categories[index_category].add_product(product) + def add_permutation(self, permutation): + av.val_instance(permutation, 'permutation', 'Category_List.add_permutation', Product_Permutation) + index_category = self.get_index_category_from_id(permutation.id_category) + self.categories[index_category].add_permutation(permutation) + def add_variation(self, variation): + av.val_instance(variation, 'variation', 'Category.add_variation', Variation) + index_category = self.get_index_category_from_id(variation.id_category) + self.categories[index_category].add_variation(variation) + def add_price(self, price): + av.val_instance(price, 'price', 'Category.add_price', Price) + index_category = self.get_index_category_from_id(price.id_category) + self.categories[index_category].add_price(price) + def add_image(self, image): + av.val_instance(image, 'image', 'Category.add_image', Image) + index_category = self.get_index_category_from_id(image.id_category) + self.categories[index_category].add_image(image) + def add_delivery_option(self, delivery_option): + av.val_instance(delivery_option, 'delivery_option', 'Category.add_delivery_option', Delivery_Option) + index_category = self.get_index_category_from_id(delivery_option.id_category) + self.categories[index_category].add_delivery_option(delivery_option) + def add_discount(self, discount): + av.val_instance(discount, 'discount', 'Category.add_discount', Discount) + index_category = self.get_index_category_from_id(discount.id_category) + self.categories[index_category].add_discount(discount) + + def get_all_variation_trees(self): + for category in self.categories: + category.get_all_variation_trees() + + def __repr__(self): + return f'categories: {self.categories}' + + def get_permutation_first(self): + print(f'getting first permutation from category list') + if not (len(self.categories) == 0): + print(f'getting first permutation from category') + return None if len(self.categories) == 0 else self.categories[0].get_permutation_first() + + def get_count_categories(self): + return len(self.categories) \ No newline at end of file diff --git a/business_objects/currency.py b/business_objects/currency.py new file mode 100644 index 00000000..bd1e38f9 --- /dev/null +++ b/business_objects/currency.py @@ -0,0 +1,96 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: Product Business Object + +Description: +Business object for product +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# CLASSES +# METHODS + +# IMPORTS +# internal +import lib.argument_validation as av +from lib import data_types +from forms import Form_Basket_Add, Form_Basket_Edit # Form_Product +# external +from enum import Enum +from datetime import datetime, timedelta +import locale +from flask_sqlalchemy import SQLAlchemy + + +# VARIABLE INSTANTIATION +db = SQLAlchemy() + + +# CLASSES +""" +class Currency_Enum(Enum): + GBP = 1 + + def text(self): + return Currency_Enum.Currency_Enum_Text(self) + + def Currency_Enum_Text(currency): + av.val_instance(currency, 'currency', 'Currency_Enum_Text', Currency_Enum) + if currency == Currency_Enum.GBP: + return 'GBP' + else: + # return 'Unknown' + raise ValueError("Unknown Currency Enum.") + + def get_member_by_text(text): + for member in Resolution_Level_Enum.__members__.values(): + if member.name == text: + return member + raise ValueError("Unknown Currency Enum.") + # return Resolution_Level_Enum.HIGH +""" + +class Currency(db.Model): + id_currency = db.Column(db.Integer, primary_key=True) + code = db.Column(db.String) + name = db.Column(db.String) + symbol = db.Column(db.String) + factor_from_GBP = db.Column(db.Float) + display_order = db.Column(db.Integer) + + def make_from_DB_currency(query_row): + # _m = 'Currency.make_from_DB_currency' + # v_arg_type = 'class attribute' + currency = Currency() + currency.id_currency = query_row[0] + currency.code = query_row[1] + currency.name = query_row[2] + currency.symbol = query_row[3] + currency.factor_from_GBP = query_row[4] + currency.display_order = query_row[5] + return currency + """ + def make_from_DB_product(query_row): + _m = 'Currency.make_from_DB_product' + v_arg_type = 'class attribute' + currency = Currency() + currency.id_permutation = query_row[0] + currency.id_product = query_row[1] + currency.id_category = query_row[2] + currency.id_variation = query_row[3] + return currency + """ + def __repr__(self): + return f''' + id: {self.id_currency} + name: {self.name} + code: {self.code} + symbol: {self.symbol} + factor from GBP: {self.factor_from_GBP} + display_order: {self.display_order} + ''' \ No newline at end of file diff --git a/business_objects/delivery_option.py b/business_objects/delivery_option.py new file mode 100644 index 00000000..f93b933d --- /dev/null +++ b/business_objects/delivery_option.py @@ -0,0 +1,115 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: Product Delivery Option Business Object + +Description: +Business object for delivery option +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# CLASSES +# METHODS + +# IMPORTS +# internal +import lib.argument_validation as av +from lib import data_types +from forms import Form_Basket_Add, Form_Basket_Edit # Form_Product +# external +from enum import Enum +from datetime import datetime, timedelta +import locale +from flask_sqlalchemy import SQLAlchemy + + +# VARIABLE INSTANTIATION +db = SQLAlchemy() + + +# CLASSES +""" +class Delivery_Option(): + name: str + delay_min: int # days + delay_max: int + quantity_min: float + quantity_max: float + regions: list # [Enum_Delivery_Region] + cost: float + + def __new__(cls, name, delay_min, delay_max, quantity_min, quantity_max, regions, cost): + _m = 'Delivery_Option.__new__' + v_arg_type = 'class attribute' + av.val_str(name, 'name', _m, v_arg_type = v_arg_type) + av.val_int(delay_min, 'delay_min', _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_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_float(cost, 'cost', _m, 0, v_arg_type = v_arg_type) + return super(Delivery_Option, cls).__new__(cls) + + def __init__(self, name, delay_min, delay_max, quantity_min, quantity_max, regions, cost): + self.name = name + self.delay_min = delay_min + self.delay_max = delay_max + self.quantity_min = quantity_min + self.quantity_max = quantity_max + self.regions = regions + self.cost = cost +""" +class Delivery_Option(db.Model): + id_option = db.Column(db.Integer, primary_key=True) + id_product = db.Column(db.Integer) + id_permutation = db.Column(db.Integer) + id_category = db.Column(db.Integer) + code = db.Column(db.String(50)) + name = db.Column(db.String(100)) + latency_min = db.Column(db.Integer) + latency_max = db.Column(db.Integer) + quantity_min = db.Column(db.Integer) + quantity_max = db.Column(db.Integer) + codes_region = db.Column(db.String(4000)) + names_region = db.Column(db.String(4000)) + price_GBP = db.Column(db.Float) + display_order = db.Column(db.Integer) + def __init__(self): + self.delivery_regions = [] + def make_from_DB_product(query_row): + option = Delivery_Option() + option.id_option = query_row[0] + option.id_product = query_row[1] + option.id_permutation = query_row[2] + option.id_category = query_row[3] + option.code = query_row[4] + option.name = query_row[5] + option.latency_min = query_row[6] + option.latency_max = query_row[7] + option.quantity_min = query_row[8] + option.quantity_max = query_row[9] + option.codes_region = query_row[10] + option.names_region = query_row[11] + option.price_GBP = query_row[12] + option.display_order = query_row[13] + return option + def __repr__(self): + return f''' + id: {self.id_option} + id_product: {self.id_product} + id_category: {self.id_category} + name: {self.name} + code: {self.code} + latency_min: {self.latency_min} + latency_max: {self.latency_max} + quantity_min: {self.quantity_min} + quantity_max: {self.quantity_max} + codes_region: {self.codes_region} + names_region: {self.names_region} + price_GBP: {self.price_GBP} + display_order: {self.display_order} + ''' diff --git a/business_objects/delivery_region.py b/business_objects/delivery_region.py new file mode 100644 index 00000000..002a0d93 --- /dev/null +++ b/business_objects/delivery_region.py @@ -0,0 +1,96 @@ +""" +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 +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# CLASSES +# METHODS + +# IMPORTS +# internal +import lib.argument_validation as av +from lib import data_types +from forms import Form_Basket_Add, Form_Basket_Edit # Form_Product +# external +from enum import Enum +from datetime import datetime, timedelta +import locale +from flask_sqlalchemy import SQLAlchemy + + +# VARIABLE INSTANTIATION +db = SQLAlchemy() + + +# CLASSES +class Enum_Delivery_Region(Enum): + UK = 0 + +class Delivery_Region(db.Model): + 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 + """ + def make_from_DB_product(query_row): + region = Delivery_Region() + region.id_region = query_row[0] + region.name = query_row[1] + region.code = query_row[2] + # self.display_order = query_row[3] + return region + def make_from_DB_region(query_row): + region = Delivery_Region() + region.id_region = query_row[0] + region.code = query_row[1] + region.name = query_row[2] + region.active = query_row[3] + 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} + ''' + + + diff --git a/business_objects/discount.py b/business_objects/discount.py new file mode 100644 index 00000000..2a28e9b1 --- /dev/null +++ b/business_objects/discount.py @@ -0,0 +1,92 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: Product Discount Business Object + +Description: +Business object for discount +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# CLASSES +# METHODS + +# IMPORTS +# internal +import lib.argument_validation as av +from lib import data_types +from forms import Form_Basket_Add, Form_Basket_Edit # Form_Product +# external +from enum import Enum +from datetime import datetime, timedelta +import locale +from flask_sqlalchemy import SQLAlchemy + + +# VARIABLE INSTANTIATION +db = SQLAlchemy() + + +# CLASSES +class Discount(db.Model): + id_discount = db.Column(db.Integer, primary_key=True) + id_category = db.Column(db.Integer) + id_product = db.Column(db.Integer) + id_permutation = db.Column(db.Integer) + code = db.Column(db.String(50)) + name = db.Column(db.String(200)) + multiplier = db.Column(db.Float) + subtractor = db.Column(db.Float) + apply_multiplier_first = db.Column(db.Boolean) + quantity_min = db.Column(db.Integer) + quantity_max = db.Column(db.Integer) + date_start = db.Column(db.DateTime) + date_end = db.Column(db.DateTime) + codes_region = db.Column(db.String(4000)) + names_region = db.Column(db.String(4000)) + codes_currency = db.Column(db.String(4000)) + names_currency = db.Column(db.String(4000)) + display_order = db.Column(db.Integer) + + def __init__(self): + self.delivery_regions = [] + def make_from_DB_product(query_row): + discount = Discount() + discount.id_discount = query_row[0] + discount.id_category = query_row[1] + discount.id_product = query_row[2] + discount.id_permutation = query_row[3] + discount.code = query_row[4] + discount.name = query_row[5] + discount.multiplier = query_row[6] + discount.subtractor = query_row[7] + discount.apply_multiplier_first = query_row[8] + discount.quantity_min = query_row[9] + discount.quantity_max = query_row[10] + discount.date_start = query_row[11] + discount.date_end = query_row[12] + discount.codes_region = query_row[13] + discount.names_region = query_row[14] + discount.codes_currency = query_row[15] + discount.names_currency = query_row[16] + discount.display_order = query_row[17] + return discount + def __repr__(self): + return f''' + id: {self.id_discount} + id_category: {self.id_category} + id_product: {self.id_product} + name: {self.name} + code: {self.code} + multiplier: {self.multiplier} + quantity_min: {self.quantity_min} + quantity_max: {self.quantity_max} + date_start: {self.date_start} + date_end: {self.date_end} + display_order: {self.display_order} + ''' + diff --git a/business_objects/image.py b/business_objects/image.py new file mode 100644 index 00000000..8fdebfaf --- /dev/null +++ b/business_objects/image.py @@ -0,0 +1,132 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: Product Image Business Object + +Description: +Business object for product image +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# CLASSES +# METHODS + +# IMPORTS +# internal +import lib.argument_validation as av +from lib import data_types +from forms import Form_Basket_Add, Form_Basket_Edit # Form_Product +# external +from enum import Enum +from datetime import datetime, timedelta +import locale +from flask_sqlalchemy import SQLAlchemy + + +# VARIABLE INSTANTIATION +db = SQLAlchemy() + + +# CLASSES +class Resolution_Level_Enum(Enum): + THUMBNAIL = 0 + LOW = 1 + HIGH = 2 + FULL = 3 + + def text(self): + return Resolution_Level_Enum.Resolution_Level_Enum_Text(self) + + def Resolution_Level_Enum_Text(category): + av.val_instance(category, 'category', 'Resolution_Level_Enum_Text', Resolution_Level_Enum) + if category == Resolution_Level_Enum.THUMBNAIL: + return 'Thumbnail' + elif category == Resolution_Level_Enum.LOW: + return 'Low resolution' + elif category == Resolution_Level_Enum.HIGH: + return 'High resolution' + elif category == Resolution_Level_Enum.FULL: + return 'Full resolution' + else: + return 'Unknown' + + def get_member_by_text(text): + for member in Resolution_Level_Enum.__members__.values(): + if member.name == text: + return member + return Resolution_Level_Enum.HIGH + + +class Image(db.Model): + id_image = db.Column(db.Integer, primary_key=True) + id_product = db.Column(db.Integer) + id_permutation = db.Column(db.Integer) + id_category = db.Column(db.Integer) + url = db.Column(db.String(255)) + active = db.Column(db.Boolean) + display_order = db.Column(db.Integer) + """ + def __new__(cls, id, id_product, id_category, url, display_order): + _m = 'Image.__new__' + v_arg_type = 'class attribute' + av.val_int(id, 'id', _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_category, 'id_category', _m, 0, v_arg_type=v_arg_type) + av.val_str(url, 'url', _m, max_len=254, v_arg_type=v_arg_type) + av.val_int(display_order, 'display_order', _m, v_arg_type=v_arg_type) + return super(Image, cls).__new__(cls) + + def __init__(self, id, id_product, id_category, url, display_order): + self.id_image = id + self.id_product = id_product + self.id_category = id_category + self.url = url + self.display_order = display_order + super().__init__() +""" + def make_from_DB_product(query_row): + _m = 'Image.make_from_DB_product' + # print(f'image: {query_row}') + image = Image() + image.id_image = query_row[0] + image.id_product = query_row[1] + image.id_permutation = query_row[2] + image.id_category = query_row[3] + image.url = query_row[4] + image.active = query_row[5] + image.display_order = query_row[6] + return image + def __repr__(self): + return f''' + id: {self.id_image} + id_product: {self.id_product} + id_category: {self.id_category} + url: {self.url} + display_order: {self.display_order} + ''' + + +class Product_Image_Filters(): + product_id: int + get_thumbnail: bool + get_remaining_LQ: bool + + def __new__(cls, product_id, get_thumbnail, get_remaining_LQ): + # Initialiser - validation + _m = 'Product_Filters.__new__' + v_arg_type = 'class attribute' + av.val_int(product_id, 'product_id', _m, v_arg_type=v_arg_type) + av.val_bool(get_thumbnail, 'get_thumbnail', _m, v_arg_type=v_arg_type) + av.val_bool(get_remaining_LQ, 'get_remaining_LQ', _m, v_arg_type=v_arg_type) + return super(Product, cls).__new__(cls) + + def __init__(self, product_id, get_thumbnail, get_remaining_LQ): + # Constructor + self.product_id = product_id + self.get_thumbnail = get_thumbnail + self.get_remaining_LQ = get_remaining_LQ + diff --git a/business_objects/order.py b/business_objects/order.py new file mode 100644 index 00000000..3be12e72 --- /dev/null +++ b/business_objects/order.py @@ -0,0 +1,93 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: Order Business Object + +Description: +Business object for order +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# CLASSES +# METHODS + +# IMPORTS +# internal +import lib.argument_validation as av +# from lib import data_types +from business_objects.product import Product +from business_objects.delivery_option import Delivery_Option +# from forms import Form_Product +# from models.model_view_store import Model_View_Store # circular +# external +# from enum import Enum +from flask import jsonify +import locale + + +# VARIABLE INSTANTIATION + +# CLASSES +class Order(): + category: str + product: Product + quantity: int + subtotal: float + delivery_option: Delivery_Option + # form: Form_Product + + def __new__(cls, category, product, quantity): + # Initialiser - validation + _m = 'Product.__new__' + v_arg_type = 'class attribute' + av.val_str(category, 'category', _m, v_arg_type=v_arg_type) + av.val_instance(product, 'product', _m, Product, v_arg_type=v_arg_type) + av.full_val_float(quantity, 'quantity', _m, product.quantity_min, v_arg_type=v_arg_type) + return super(Basket_Item, cls).__new__(cls) + + def __init__(self, category, product, quantity): + # Constructor + self.category = category + self.product = product + self.quantity = quantity + self.subtotal = round(self.product.price_GBP_full * self.quantity, 2) + """ + self.form = Form_Product() + if self.form.validate_on_submit(): + # Handle form submission + + pass + """ + + def update_quantity(self, quantity): + _m = 'Basket_Item.update_quantity' + v_arg_type = 'class attribute' + av.full_val_float(quantity, 'quantity', _m, self.product.quantity_min, v_arg_type=v_arg_type) + self.quantity = quantity + self.subtotal = round(self.product.price_GBP_full * self.quantity, 2) + + def jsonify(self): + return jsonify(self) + + def to_json(self): + return { + 'product_id': self.product.id_product, + 'price': self.product.price_GBP_full, + 'quantity': self.quantity + } + + def output_subtotal(self): + locale.setlocale(locale.LC_ALL, '') + return locale.format_string("%d", self.subtotal, grouping=True) + + def __repr__(self): + return f''' + category: {self.category} + product: {self.product} + quantity: {self.quantity} + subtotal: {self.subtotal} + ''' \ No newline at end of file diff --git a/business_objects/product.py b/business_objects/product.py new file mode 100644 index 00000000..5060058d --- /dev/null +++ b/business_objects/product.py @@ -0,0 +1,704 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: Product Business Object + +Description: +Business object for product +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# CLASSES +# METHODS + +# IMPORTS +# internal +import lib.argument_validation as av +from lib import data_types +from forms import Form_Basket_Add, Form_Basket_Edit # Form_Product +from business_objects.discount import Discount +from business_objects.variation import Variation +from business_objects.image import Image +from business_objects.delivery_option import Delivery_Option +# external +from enum import Enum +from datetime import datetime, timedelta +import locale +from flask_sqlalchemy import SQLAlchemy +from dataclasses import dataclass + +# VARIABLE INSTANTIATION +db = SQLAlchemy() + + +# CLASSES +class Enum_Status_Stock(Enum): + OUT = 0 + LOW = 1 + IN = 99 + + def text(self): + return Enum_Status_Stock.Enum_Status_Stock_Text(self) + + def Enum_Status_Stock_Text(status): + av.val_instance(status, 'category', 'Enum_Status_Stock_Text', Enum_Status_Stock) + if status == Enum_Status_Stock.OUT: + return 'Out of stock' + elif status == Enum_Status_Stock.LOW: + return 'Low on stock' + else: + return 'Fully stocked' + + def get_member_by_text(text): + return data_types.get_enum_member_by_text(Enum_Status_Stock, text.upper()) + +class Variation_Tree_Node(): + variation: Variation + node_parent: None + nodes_child: list + def __init__(self): + self.nodes_child = [] + def make_from_variation_and_node_parent(variation, node_parent): + node = Variation_Tree_Node() + node.variation = variation + node.node_parent = node_parent + return node + def make_from_node_parent(node_parent): + node = Variation_Tree_Node() + node.node_parent = node_parent + return node + def add_child(self, node_child): + self.nodes_child.append(node_child) + def is_leaf(self): + return (len(self.nodes_child) == 0) +class Variation_Tree: + node_root: Variation_Tree_Node + def make_from_node_root(node_root): + tree = Variation_Tree() + tree.node_root = node_root + return tree + def get_variation_type_list(self): + variation_types = [] + node = self.node_root + at_leaf_node = node.is_leaf() + while not at_leaf_node: + variation_types.append(node.variation.name_variation_type) + at_leaf_node = node.is_leaf() + if not at_leaf_node: + node = node.nodes_child[0] + return variation_types + def is_equal(self, tree): + my_type_list = self.get_variation_type_list() + sz_me = len(my_type_list) + other_type_list = tree.get_variation_type_list() + sz_other = len(other_type_list) + is_equal = (sz_me == sz_other) + if is_equal: + for index_type in range(sz_me): + if sz_me[index_type] != sz_other[index_type]: + is_equal = False + break + return is_equal + def make_from_product_permutation(product_permutation): + depth_max = len(product_permutation.variations) + node_root = Variation_Tree_Node.make_from_variation_and_node_parent(product_permutation.variations[0], None) + node = node_root + for depth in range(depth_max - 1): + node = Variation_Tree_Node.make_from_variation_and_node_parent(product_permutation.variations[depth + 1], node) + return Variation_Tree.make_from_node_root(node_root) + +class Product(db.Model): + id_product = db.Column(db.Integer, primary_key=True) + id_category = db.Column(db.Integer) + name = db.Column(db.String(255)) + display_order = db.Column(db.Integer) + can_view = db.Column(db.Boolean) + can_edit = db.Column(db.Boolean) + can_admin = db.Column(db.Boolean) + # form_basket_add: Form_Basket_Add + # form_basket_edit: Form_Basket_Edit + # has_variations: bool + # index_permutation_selected: int + + def __init__(self): + self.permutations = [] + self.permutation_index = {} + self.variation_trees = [] + self.index_permutation_selected = None + self.has_variations = False + super().__init__() + self.form_basket_add = Form_Basket_Add() + self.form_basket_edit = Form_Basket_Edit() + + def make_from_DB_product(query_row): + _m = 'Product.make_from_DB_product' + v_arg_type = 'class attribute' + product = Product() + product.id_product = query_row[0] + product.id_category = query_row[5] + product.name = query_row[2] + product.has_variations = av.input_bool(query_row[4], "has_variations", _m, v_arg_type=v_arg_type) + product.display_order = query_row[17] + product.can_view = av.input_bool(query_row[19], "can_view", _m, v_arg_type=v_arg_type) + product.can_edit = av.input_bool(query_row[20], "can_edit", _m, v_arg_type=v_arg_type) + product.can_admin = av.input_bool(query_row[21], "can_admin", _m, v_arg_type=v_arg_type) + return product + """ + def make_from_permutation(permutation, has_variations = False): + _m = 'Product.make_from_permutation' + v_arg_type = 'class attribute' + av.val_instance(permutation, 'permutation', _m, Product_Permutation, v_arg_type=v_arg_type) + product = Product() + product.has_variations = has_variations + product.index_permutation_selected = 0 + product.id_product = permutation.id_product + product.id_category = permutation.id_category + product.display_order = permutation.display_order + product.can_view = permutation.can_view + product.can_edit = permutation.can_edit + product.can_admin = permutation.can_admin + product.permutations.append(permutation) + # product.get_variation_trees() + return product + """ + def add_permutation(self, permutation): + _m = 'Product.add_permutation' + av.val_instance(permutation, 'permutation', _m, Product_Permutation) + try: + self.permutation_index[permutation.id_permutation] + raise ValueError(f"{av.error_msg_str(permutation, 'permutation', _m, Product_Permutation)}\nPermutation ID already in product") + except KeyError: + self.permutation_index[permutation.id_permutation] = len(self.permutations) + self.permutations.append(permutation) + """ + if self.has_variations: + self.has_variations = False + """ + if self.index_permutation_selected is None: + self.index_permutation_selected = self.permutation_index[permutation.id_permutation] + print(f'setting selected permutation for product {self.id_product} to {self.index_permutation_selected}') # :\n{self.permutations[self.index_permutation_selected]} + """ + def make_from_permutations(permutations): + _m = 'Product.make_from_permutations' + v_arg_type = 'class attribute' + if len(permutations) == 0: + raise ValueError(av.error_msg_str(permutations, 'permutations', _m, list, v_arg_type=v_arg_type)) + product = Product() + product.has_variations = True + product.index_permutation_selected = 0 + product.id_product = permutations[0].id_product + product.id_category = permutations[0].id_category + product.display_order = permutations[0].display_order + product.can_view = True + product.can_edit = True + product.can_admin = True + for permutation in permutations: + product.can_view &= permutation.can_view + product.can_edit &= permutation.can_edit + product.can_admin &= permutation.can_admin + product.permutations.append(permutations) + product.get_variation_trees() + return product + """ + def get_variation_trees(self): + for index_permutation in range(len(self.permutations)): + variation_tree = Variation_Tree.make_from_product_permutation(self.permutations[index_permutation]) + found_variation_tree_match = False + for index_tree in range(len(self.variation_trees)): + if self.variation_trees[index_tree].is_equal(variation_tree): + found_variation_tree_match = True + break + if not found_variation_tree_match: + self.variation_trees.append(variation_tree) + + def make_from_DB_Stripe_product(query_row): + permutation = Product_Permutation.make_from_DB_Stripe_product(query_row) + product = Product.make_from_permutation(permutation) + return product + + def make_from_DB_Stripe_price(query_row): + permutation = Product_Permutation.make_from_DB_Stripe_price(query_row) + product = Product.make_from_permutation(permutation) + return product + + def make_from_json(json_basket_item, key_id_product, key_id_permutation): + permutation = Product_Permutation.make_from_json(json_basket_item, key_id_product, key_id_permutation) + product = Product.make_from_permutation(permutation) + return product + + def get_permutation_selected(self): + try: + return self.permutations[self.index_permutation_selected] + except: + raise ValueError(f'list index {self.index_permutation_selected} out of range') + 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): + return f'''Product + id_product: {self.id_product} + id_category: {self.id_category} + name: {self.name} + display_order: {self.display_order} + can_view: {self.can_view} + can_edit: {self.can_edit} + can_admin: {self.can_admin} + has_variations: {self.has_variations} + permutations: {self.permutations} + variation trees: {self.variation_trees} + ''' + """ + def get_index_permutation_from_id(self, id_permutation): + if id_permutation is None and not self.has_variations: + return 0 + for index_permutation in range(len(self.permutations)): + permutation = self.permutations[index_permutation] + if permutation.id_permutation == id_permutation: + return index_permutation + raise ValueError(f"{av.error_msg_str(id_permutation, 'id_permutation', 'Product.get_index_permutation_from_id', int)}\nPermutation ID not found.") + """ + def add_variation(self, variation): + av.val_instance(variation, 'variation', 'Product.add_variation', Variation) + # print(f'variation: {variation}') + index_permutation = self.permutation_index[variation.id_permutation] # self.get_index_permutation_from_id(variation.id_permutation) + self.permutations[index_permutation].add_variation(variation) + def add_price(self, price): + av.val_instance(price, 'price', 'Product.add_price', Price) + index_permutation = self.permutation_index[price.id_permutation] # self.get_index_permutation_from_id(price.id_permutation) + self.permutations[index_permutation].add_price(price) + def add_image(self, image): + av.val_instance(image, 'image', 'Product.add_image', Image) + index_permutation = self.permutation_index[image.id_permutation] # self.get_index_permutation_from_id(image.id_permutation) + self.permutations[index_permutation].add_image(image) + def add_delivery_option(self, delivery_option): + av.val_instance(delivery_option, 'delivery_option', 'Product.add_delivery_option', Delivery_Option) + index_permutation = self.permutation_index[delivery_option.id_permutation] # self.get_index_permutation_from_id(delivery_option.id_permutation) + self.permutations[index_permutation].add_delivery_option(delivery_option) + def add_discount(self, discount): + av.val_instance(discount, 'discount', 'Product.add_discount', Discount) + index_permutation = self.permutation_index[discount.id_permutation] # self.get_index_permutation_from_id(discount.id_permutation) + self.permutations[index_permutation].add_discount(discount) + + +class Product_Permutation(db.Model): + id_product = db.Column(db.Integer, primary_key=True) + id_permutation = db.Column(db.Integer, primary_key=True) + # name = db.Column(db.String(255)) + description = db.Column(db.String(4000)) + # price_GBP_full = db.Column(db.Float) + # price_GBP_min = db.Column(db.Float) + has_variations = db.Column(db.Boolean) + id_category = db.Column(db.Integer) + latency_manufacture = db.Column(db.Integer) + quantity_min = db.Column(db.Float) + quantity_max = db.Column(db.Float) + quantity_step = db.Column(db.Float) + quantity_stock = db.Column(db.Float) + id_stripe_product = db.Column(db.String(100)) + is_subscription = db.Column(db.Boolean) + name_recurrence_interval = db.Column(db.String(255)) + name_plural_recurrence_interval = db.Column(db.String(256)) + count_recurrence_interval = db.Column(db.Integer) + display_order = db.Column(db.Integer) + can_view = db.Column(db.Boolean) + can_edit = db.Column(db.Boolean) + can_admin = db.Column(db.Boolean) + # form_basket_add: Form_Basket_Add + # form_basket_edit: Form_Basket_Edit + # is_unavailable_in_currency_or_region: bool + # is_available: bool + + def __init__(self): + self.variations = [] + self.variation_index = {} + self.prices = [] + self.price_index = {} + self.images = [] + self.image_index = {} + self.delivery_options = [] + self.delivery_option_index = {} + self.discounts = [] + self.discount_index = {} + super().__init__() + self.form_basket_add = Form_Basket_Add() + self.form_basket_edit = Form_Basket_Edit() + self.is_unavailable_in_currency_or_region = False + self.is_available = True + + def make_from_DB_product(query_row): + _m = 'Product_Permutation.make_from_DB_product' + v_arg_type = 'class attribute' + print(f'query_row: {query_row}') + permutation = Product_Permutation() + permutation.id_product = query_row[0] + permutation.id_permutation = query_row[1] + # permutation.name = query_row[2] + permutation.description = query_row[3] + # permutation.price_GBP_full = query_row[4] + # permutation.price_GBP_min = query_row[5] + permutation.has_variations = query_row[4] + permutation.id_category = query_row[5] + permutation.latency_manufacture = query_row[6] + permutation.quantity_min = query_row[7] + permutation.quantity_max = query_row[8] + permutation.quantity_step = query_row[9] + permutation.quantity_stock = query_row[10] + permutation.id_stripe_product = query_row[11] + permutation.is_subscription = av.input_bool(query_row[12], "is_subscription", _m, v_arg_type=v_arg_type) + permutation.name_recurrence_interval = query_row[13] + permutation.name_plural_recurrence_interval = query_row[14] + permutation.count_recurrence_interval = query_row[15] + permutation.display_order = query_row[18] + permutation.can_view = av.input_bool(query_row[19], "can_view", _m, v_arg_type=v_arg_type) + permutation.can_edit = av.input_bool(query_row[20], "can_edit", _m, v_arg_type=v_arg_type) + permutation.can_admin = av.input_bool(query_row[21], "can_admin", _m, v_arg_type=v_arg_type) + return permutation + + def make_from_DB_Stripe_product(query_row): + _m = 'Product_Permutation.make_from_DB_Stripe_product' + v_arg_type = 'class attribute' + permutation = Product_Permutation() + permutation.id_product = query_row[0] + # permutation.name = query_row[1] + permutation.description = query_row[2] + return permutation + + def make_from_DB_Stripe_price(query_row): + _m = 'Product_Permutation.make_from_DB_Stripe_price' + v_arg_type = 'class attribute' + permutation = Product_Permutation() + permutation.id_product = query_row[0] + # permutation.price_GBP_full = query_row[1] + permutation.id_stripe_product = query_row[2] + permutation.is_subscription = av.input_bool(query_row[3], "is_subscription", _m, v_arg_type=v_arg_type) + permutation.name_recurrence_interval = query_row[4] + permutation.count_recurrence_interval = query_row[5] + return permutation + + def make_from_json(json_basket_item, key_id_product, key_id_permutation): + _m = 'Product_Permutation.make_from_json' + v_arg_type = 'class attribute' + permutation = Product_Permutation() + permutation.id_product = json_basket_item[key_id_product] + permutation.id_permutation = json_basket_item[key_id_permutation] + return permutation + + def get_price(self): + 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 == 1 else f'{self.latency_manufacture} days' + + def output_delivery_date(self): + return (datetime.now() + timedelta(days=self.latency_manufacture)).strftime('%A, %d %B %Y') + + def output_price(self, is_included_VAT): + if self.is_unavailable_in_currency_or_region: + return 'Not available in currency and region' + if not self.is_available: + return 'Not available' + price = self.get_price() + locale.setlocale(locale.LC_ALL, '') + if is_included_VAT: + return f'{price.symbol_currency} {locale.format_string("%d", price.value_local_VAT_incl, grouping=True)}' + else: + 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 + """ + 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): + return f'''Product_Permutation + id_product: {self.id_product} + id_permutation: {self.id_permutation} + description: {self.description} + id_category: {self.id_category} + latency_manufacture: {self.latency_manufacture} + quantity_min: {self.quantity_min} + quantity_max: {self.quantity_max} + quantity_step: {self.quantity_step} + quantity_stock: {self.quantity_stock} + id_stripe_product: {self.id_stripe_product} + is_subscription: {self.is_subscription} + name_recurrence_interval: {self.name_recurrence_interval} + name_plural_recurrence_interval: {self.name_plural_recurrence_interval} + count_recurrence_interval: {self.count_recurrence_interval} + display_order: {self.display_order} + can_view: {self.can_view} + can_edit: {self.can_edit} + can_admin: {self.can_admin} + variations: {self.variations} + images: {self.images} + delivery_options: {self.delivery_options} + prices: {self.prices} + ''' + """ + price_GBP_full: {self.price_GBP_full} + price_GBP_min: {self.price_GBP_min} + """ + + def add_variation(self, variation): + _m = 'Product_Permutation.add_variation' + av.val_instance(variation, 'variation', _m, Variation) + try: + self.variation_index[variation.id_variation] + raise ValueError(f"{av.error_msg_str(variation, 'variation', _m, Variation)}\nVariation already in product.") + except KeyError: + self.variation_index[variation.id_variation] = len(self.variations) + self.variations.append(variation) + def add_price(self, price): + _m = 'Product_Permutation.add_price' + av.val_instance(price, 'price', _m, Price) + try: + self.price_index[price.display_order] + raise ValueError(f"{av.error_msg_str(price, 'price', _m, Price)}\nPrice already in product.") + except KeyError: + self.price_index[price.display_order] = len(self.prices) + self.prices.append(price) + def add_image(self, image): + _m = 'Product_Permutation.add_image' + av.val_instance(image, 'image', _m, Image) + try: + self.image_index[image.id_image] + raise ValueError(f"{av.error_msg_str(image, 'image', _m, Image)}\nImage already in product.") + except KeyError: + self.image_index[image.id_image] = len(self.images) + self.images.append(image) + def add_delivery_option(self, delivery_option): + _m = 'Product_Permutation.add_delivery_option' + av.val_instance(delivery_option, 'delivery_option', _m, Delivery_Option) + try: + self.delivery_option_index[delivery_option.id_option] + raise ValueError(f"{av.error_msg_str(delivery_option, 'delivery_option', _m, Delivery_Option)}\nDelivery_Option already in product.") + except KeyError: + self.delivery_option_index[delivery_option.id_option] = len(self.delivery_options) + self.delivery_options.append(delivery_option) + def add_discount(self, discount): + _m = 'Product_Permutation.add_discount' + av.val_instance(discount, 'discount', _m, Discount) + try: + self.discount_index[discount.display_order] + raise ValueError(f"{av.error_msg_str(discount, 'discount', _m, Discount)}\nDiscount already in product.") + except KeyError: + self.discount_index[discount.display_order] = len(self.discounts) + self.discounts.append(discount) + + def get_image_from_index(self, index_image): + try: + return self.images[index_image] + except: + raise IndexError(f"Invalid image index: {index_image}") + + def get_price_from_code_currency(self, code_currency): + for price in self.prices: + if price.code_currency == code_currency: + return price + +""" +class Product_Filters(): + ids: str # csv + categories: str # csv + + def __new__(cls, product_ids, product_categories): + # Initialiser - validation + _m = 'Product_Filters.__new__' + v_arg_type = 'class attribute' + # av.val_list_instances(product_ids, 'product_ids', _m, str, v_arg_type=v_arg_type) + # av.val_list_instances(product_categories, 'product_categories', _m, Product_Category_Enum, v_arg_type=v_arg_type) + av.val_str(product_ids, 'product_ids', _m, v_arg_type=v_arg_type) + av.val_str(product_categories, 'product_categories', _m, v_arg_type=v_arg_type) + return super(Product, cls).__new__(cls) + + def __init__(self, product_ids, product_categories): + # Constructor + self.ids = product_ids + self.categories = product_categories + +class Price(): + product: Product + currency: Currency_Enum + + def make_from_product_currency(product, code_currency): + name_method = 'make_from_product_currency' + av.val_instance(product, 'product', name_method, Product) + price = Price() + price.product = product + price.currency = Currency_Enum.get_member_by_text(code_currency) +""" + +class Price(db.Model): + id_price = db.Column(db.Integer) + id_product = db.Column(db.Integer) + id_permutation = db.Column(db.Integer) + id_category = db.Column(db.Integer) + id_currency = db.Column(db.Integer) + code_currency = db.Column(db.String) + name_currency = db.Column(db.String) + symbol_currency = db.Column(db.String) + id_region = db.Column(db.Integer) + value_local_VAT_incl = db.Column(db.Float) + value_local_VAT_excl = db.Column(db.Float) + display_order = db.Column(db.Float, primary_key=True) + + def make_from_DB_product(query_row): + _m = 'Price.make_from_DB_product' + price = Price() + price.id_price = query_row[0] + price.id_permutation = query_row[1] + price.id_product = query_row[2] + price.id_category = query_row[3] + price.id_currency = query_row[4] + price.code_currency = query_row[5] + price.name_currency = query_row[6] + price.symbol_currency = query_row[7] + price.id_region = query_row[8] + price.value_local_VAT_incl = query_row[9] + price.value_local_VAT_excl = query_row[10] + price.display_order = query_row[11] + return price + + def __repr__(self): + return f'''Price + id: {self.id_price} + id_permutation: {self.id_permutation} + id_product: {self.id_product} + id_category: {self.id_category} + id_currency: {self.id_currency} + code_currency: {self.code_currency} + name_currency: {self.name_currency} + symbol_currency: {self.symbol_currency} + id_region: {self.id_region} + value_local (VAT incl): {self.value_local_VAT_incl} + value_local (VAT excl): {self.value_local_VAT_excl} + display_order (UID): {self.display_order} + ''' +""" +class Permutation_Variation_Link(db.Model): + id_permutation = db.Column(db.Integer) + id_product = db.Column(db.Integer) + id_category = db.Column(db.Integer) + id_variation = db.Column(db.Integer) + + def make_from_DB_product(query_row): + _m = 'Permutation_Variation_Link.make_from_DB_product' + v_arg_type = 'class attribute' + link = Permutation_Variation_Link() + link.id_permutation = query_row[0] + link.id_product = query_row[1] + link.id_category = query_row[2] + link.id_variation = query_row[3] + return link +""" + +@dataclass +class Product_Filters(): + id_user: str + get_all_category: bool + ids_category: str + get_inactive_category: bool + get_all_product: bool + ids_product: str + get_inactive_product: bool + get_first_product_only: bool + get_all_permutation: bool + ids_permutation: str + get_inactive_permutation: bool + get_all_image: bool + ids_image: str + get_inactive_image: bool + get_first_image_only: bool + get_all_region: bool + ids_region: str + get_inactive_region: bool + get_all_currency: bool + ids_currency: str + get_inactive_currency: bool + get_all_discount: bool + ids_discount: str + get_inactive_discount: bool + def to_json(self): + return { + 'a_id_user': self.id_user, + 'a_get_all_category': self.get_all_category, + 'a_ids_category': self.ids_category, + 'a_get_inactive_category': self.get_inactive_category, + 'a_get_all_product': self.get_all_product, + 'a_ids_product': self.ids_product, + 'a_get_inactive_product': self.get_inactive_product, + 'a_get_first_product_only': self.get_first_product_only, + 'a_get_all_permutation': self.get_all_permutation, + 'a_ids_permutation': self.ids_permutation, + 'a_get_inactive_permutation': self.get_inactive_permutation, + 'a_get_all_image': self.get_all_image, + 'a_ids_image': self.ids_image, + 'a_get_inactive_image': self.get_inactive_image, + 'a_get_first_image_only': self.get_first_image_only, + 'a_get_all_delivery_region': self.get_all_region, + 'a_ids_delivery_region': self.ids_region, + 'a_get_inactive_delivery_region': self.get_inactive_region, + 'a_get_all_currency': self.get_all_currency, + 'a_ids_currency': self.ids_currency, + 'a_get_inactive_currency': self.get_inactive_currency, + 'a_get_all_discount': self.get_all_discount, + 'a_ids_discount': self.ids_discount, + 'a_get_inactive_discount': self.get_inactive_discount + } \ No newline at end of file diff --git a/business_objects/sql_error.py b/business_objects/sql_error.py new file mode 100644 index 00000000..0256c1fe --- /dev/null +++ b/business_objects/sql_error.py @@ -0,0 +1,65 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: SQL Error Business Object + +Description: +Business object for SQL errors +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# CLASSES +# METHODS + +# IMPORTS +# internal +import lib.argument_validation as av +from lib import data_types +from forms import Form_Basket_Add, Form_Basket_Edit # Form_Product +# external +from enum import Enum +from datetime import datetime, timedelta +import locale +from flask_sqlalchemy import SQLAlchemy + + +# VARIABLE INSTANTIATION +db = SQLAlchemy() + + +# CLASSES +class SQL_Error(db.Model): + display_order = db.Column(db.Integer, primary_key=True) + code = db.Column(db.String(50)) + msg = db.Column(db.String(4000)) + name = db.Column(db.String(500)) + description = db.Column(db.String(4000)) + + """ + def __new__(cls, display_order, code, msg): + _m = 'SQL_Error.__new__' + v_arg_type = 'class attribute' + av.val_int(display_order, 'display_order', _m) + av.val_str(code, 'code', _m, max_len=50, v_arg_type=v_arg_type) + av.val_str(msg, 'msg', _m, max_len=4000, v_arg_type=v_arg_type) + return super(SQL_Error, cls).__new__(cls) + + def __init__(self, display_order, code, msg): + self.display_order = display_order + self.code = code + self.msg = msg + super().__init__() + """ + + def make_from_DB_record(record): + error = SQL_Error() + error.display_order = record[0] + error.code = record[1] + error.msg = record[2] + error.name = record[3] + error.description = record[4] + return error \ No newline at end of file diff --git a/business_objects/stripe.py b/business_objects/stripe.py new file mode 100644 index 00000000..f85a8611 --- /dev/null +++ b/business_objects/stripe.py @@ -0,0 +1,164 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: Stripe Business Object + +Description: +Business objects for Stripe +""" + +# internal +import lib.argument_validation as av +from lib import data_types +from forms import Form_Basket_Add, Form_Basket_Edit # Form_Product + +# external +from enum import Enum +from datetime import datetime, timedelta +import locale +from flask_sqlalchemy import SQLAlchemy + +db = SQLAlchemy() + +class Stripe_Product(db.Model): + id_product = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(255)) + description = db.Column(db.String(4000)) + price_GBP_full = db.Column(db.Float) + id_category = db.Column(db.Integer) + lead_time_manuf = db.Column(db.Integer) + quantity_min = db.Column(db.Float) + quantity_max = db.Column(db.Float) + quantity_step = db.Column(db.Float) + quantity_stock = db.Column(db.Float) + id_stripe_product = db.Column(db.String(255)) + id_stripe_price = db.Column(db.String(255)) + is_subscription = db.Column(db.Boolean) + name_recurring_interval = db.Column(db.String(255)) + name_plural_recurring_interval = db.Column(db.String(256)) + count_recurring_interval = db.Column(db.Integer) + display_order = db.Column(db.Integer) + can_view = db.Column(db.Boolean) + can_edit = db.Column(db.Boolean) + can_admin = db.Column(db.Boolean) + # form_basket_add: Form_Basket_Add + # form_basket_edit: Form_Basket_Edit + + def __new__(cls, id, name, description, price_GBP_full, id_category, lead_time_manuf, quantity_min, quantity_max, quantity_step, quantity_stock, id_stripe_product, id_stripe_price, + is_subscription, name_recurring_interval, name_plural_recurring_interval, count_recurring_interval, display_order, can_view, can_edit, can_admin): + _m = 'Product.__new__' + v_arg_type = 'class attribute' + av.val_int(id, 'id', _m, 0, v_arg_type=v_arg_type) + av.val_str(name, 'name', _m, max_len=256, v_arg_type=v_arg_type) + av.val_str(description, 'description', _m, max_len=4000, v_arg_type=v_arg_type) + av.full_val_float(price_GBP_full, 'price_GBP_full', _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(lead_time_manuf, 'lead_time_manuf', _m, 0, v_arg_type=v_arg_type) + av.full_val_float(quantity_step, 'quantity_step', _m, 0., v_arg_type=v_arg_type) + av.full_val_float(quantity_min, 'quantity_min', _m, quantity_step, v_arg_type=v_arg_type) + av.full_val_float(quantity_max, 'quantity_max', _m, quantity_min, v_arg_type=v_arg_type) + av.full_val_float(quantity_stock, 'quantity_stock', _m, 0, v_arg_type=v_arg_type) + av.val_str(id_stripe_product, 'id_stripe_product', _m, max_len=100, v_arg_type=v_arg_type) + av.val_str(id_stripe_price, 'id_stripe_price', _m, max_len=100, v_arg_type=v_arg_type) + av.full_val_bool(is_subscription, 'is_subscription', _m, v_arg_type=v_arg_type) + print(f'is_subscription: {is_subscription}, {av.input_bool(is_subscription, "is_subscription", _m, v_arg_type=v_arg_type)}') + is_subscription = av.input_bool(is_subscription, "is_subscription", _m, v_arg_type=v_arg_type) + if is_subscription: + av.val_str(name_recurring_interval, 'name_recurring_interval', _m, max_len=255, v_arg_type=v_arg_type) + av.val_str(name_plural_recurring_interval, 'name_plural_recurring_interval', _m, max_len=256, v_arg_type=v_arg_type) + av.val_int(count_recurring_interval, 'count_recurring_interval', _m, 0, v_arg_type=v_arg_type) + av.val_int(display_order, 'display_order', _m, v_arg_type=v_arg_type) + av.full_val_bool(can_view, 'can_view', _m, v_arg_type=v_arg_type) + # can_view = av.input_bool(can_view, "can_view", _m, v_arg_type=v_arg_type) + av.full_val_bool(can_edit, 'can_edit', _m, v_arg_type=v_arg_type) + # can_edit = av.input_bool(can_edit, "can_edit", _m, v_arg_type=v_arg_type) + av.full_val_bool(can_admin, 'can_admin', _m, v_arg_type=v_arg_type) + # can_admin = av.input_bool(can_admin, "can_admin", _m, v_arg_type=v_arg_type) + return super(Product, cls).__new__(cls) # , id, name, description, price_GBP, id_category, lead_time_manuf, quantity_min, quantity_max, quantity_step, quantity_stock, id_stripe_product, id_stripe_price, + # is_subscription, name_recurring_interval, name_plural_recurring_interval, count_recurring_interval, can_view, can_edit, can_admin) + + def __init__(self, id, name, description, price_GBP_full, id_category, lead_time_manuf, quantity_min, quantity_max, quantity_step, quantity_stock, id_stripe_product, id_stripe_price, + is_subscription, name_recurring_interval, name_plural_recurring_interval, count_recurring_interval, display_order, can_view, can_edit, can_admin): + _m = 'Product.__new__' + v_arg_type = 'class attribute' + self.id_product = id + self.name = name + self.description = description + self.price_GBP_full = price_GBP_full + self.id_category = id_category + self.lead_time_manuf = lead_time_manuf + self.quantity_min = quantity_min + self.quantity_max = quantity_max + self.quantity_step = quantity_step + self.quantity_stock = quantity_stock + self.id_stripe_product = id_stripe_product + self.id_stripe_price = id_stripe_price + self.is_subscription = av.input_bool(is_subscription, "is_subscription", _m, v_arg_type=v_arg_type) + self.name_recurring_interval = name_recurring_interval + self.name_plural_recurring_interval = name_plural_recurring_interval + self.count_recurring_interval = count_recurring_interval + self.display_order = display_order + self.can_view = av.input_bool(can_view, "can_view", _m, v_arg_type=v_arg_type) + self.can_edit = av.input_bool(can_edit, "can_edit", _m, v_arg_type=v_arg_type) + self.can_admin = av.input_bool(can_admin, "can_admin", _m, v_arg_type=v_arg_type) + self.variations = [] + self.images = [] + self.delivery_options = [] + self.discounts = [] + self.discount_index = {} + super().__init__() + self.form_basket_add = Form_Basket_Add() + self.form_basket_edit = Form_Basket_Edit() + + def output_lead_time(self): + return '1 day' if self.lead_time_manuf == 1 else f'{self.lead_time_manuf} days' + + def output_delivery_date(self): + return (datetime.now() + timedelta(days=self.lead_time_manuf)).strftime('%A, %d %B %Y') + + def output_price(self): + locale.setlocale(locale.LC_ALL, '') + return locale.format_string("%d", self.price_GBP_full, 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): + return f'''Product + id: {self.id_product} + name: {self.name} + description: {self.description} + price_GBP_full: {self.price_GBP_full} + id_category: {self.id_category} + lead_time_manuf: {self.lead_time_manuf} + quantity_min: {self.quantity_min} + quantity_max: {self.quantity_max} + quantity_step: {self.quantity_step} + quantity_stock: {self.quantity_stock} + id_stripe_product: {self.id_stripe_product} + id_stripe_price: {self.id_stripe_price} + is_subscription: {self.is_subscription} + name_recurring_interval: {self.name_recurring_interval} + name_plural_recurring_interval: {self.name_plural_recurring_interval} + count_recurring_interval: {self.count_recurring_interval} + display_order: {self.display_order} + can_view: {self.can_view} + can_edit: {self.can_edit} + can_admin: {self.can_admin} + variations: {self.variations} + images: {self.images} + delivery_options: {self.delivery_options} + ''' + + def add_discount(self, discount): + _m = 'Category.add_product' + av.val_instance(discount, 'discount', _m, Discount) + # self.product_index.append(len(self.products)) + self.discount_index[discount.id_discount] = len(self.discounts) + self.discounts.append(discount) \ No newline at end of file diff --git a/business_objects/variation.py b/business_objects/variation.py new file mode 100644 index 00000000..6803afe6 --- /dev/null +++ b/business_objects/variation.py @@ -0,0 +1,94 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: Product Variation Business Object + +Description: +Business object for product variation +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# CLASSES +# METHODS + +# IMPORTS +# internal +import lib.argument_validation as av +from lib import data_types +from forms import Form_Basket_Add, Form_Basket_Edit # Form_Product +# external +from enum import Enum +from datetime import datetime, timedelta +import locale +from flask_sqlalchemy import SQLAlchemy + + +# VARIABLE INSTANTIATION +db = SQLAlchemy() + + +# CLASSES +class Variation(db.Model): + id_variation = db.Column(db.Integer, primary_key=True) + id_product = db.Column(db.Integer) + id_permutation = db.Column(db.Integer) + id_category = db.Column(db.Integer) + code_variation_type = db.Column(db.String(50)) + name_variation_type = db.Column(db.String(255)) + code_variation = db.Column(db.String(50)) + name_variation = db.Column(db.String(255)) + display_order = db.Column(db.Integer) + + """ + def __new__(cls, id, id_product, id_category, name_type, code_type, name, code, display_order): + _m = 'Variation.__new__' + v_arg_type = 'class attribute' + av.val_int(id, 'id', _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_category, 'id_category', _m, 0, v_arg_type=v_arg_type) + av.val_str(code_type, 'code_type', _m, max_len=50, v_arg_type=v_arg_type) + av.val_str(name_type, 'name_type', _m, max_len=256, 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=256, v_arg_type=v_arg_type) + av.val_int(display_order, 'display_order', _m, v_arg_type=v_arg_type) + return super(Variation, cls).__new__(cls) + + def __init__(self, id, id_product, id_category, name_type, code_type, name, code, display_order): + self.id_variation = id + self.id_product = id_product + self.id_category = id_category + self.name_variation_type = name_type + self.code_variation_type = code_type + self.name_variation = name + self.code_variation = code + self.display_order = display_order + super().__init__() + """ + def make_from_DB_product(query_row): + variation = Variation() + variation.id_variation = query_row[0] + variation.id_product = query_row[1] + variation.id_permutation = query_row[2] + variation.id_category = query_row[3] + variation.code_variation_type = query_row[4] + variation.name_variation_type = query_row[5] + variation.code_variation = query_row[6] + variation.name_variation = query_row[7] + variation.display_order = query_row[8] + return variation + def __repr__(self): + return f''' + id: {self.id_variation} + id_product: {self.id_product} + id_permutation: {self.id_permutation} + id_category: {self.id_category} + code_variation_type: {self.code_variation_type} + name_variation_type: {self.name_variation_type} + code_variation: {self.code_variation} + name_variation: {self.name_variation} + display_order: {self.display_order} + ''' diff --git a/config.py b/config.py new file mode 100644 index 00000000..e7978608 --- /dev/null +++ b/config.py @@ -0,0 +1,59 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Backend +Feature: Configuration + +Description: +Configuration variables +""" + +# IMPORTS +import os + +# CLASSES +class Config: + DEBUG = False + TESTING = False + SECRET_KEY = os.getenv('KEY_SECRET_FLASK') # gen cmd: openssl rand -hex 32 + # Add other configuration variables as needed + SQLALCHEMY_DATABASE_URI = os.getenv('SQLALCHEMY_DATABASE_URI') + SQLALCHEMY_TRACK_MODIFICATIONS = False + ID_AUTH0_CLIENT = os.getenv('ID_AUTH0_CLIENT') + ID_AUTH0_CLIENT_SECRET = os.getenv('ID_AUTH0_CLIENT_SECRET') + DOMAIN_AUTH0 = os.getenv('DOMAIN_AUTH0') + ID_TOKEN_USER = 'user' + is_included_VAT = True + """ + KEY_IS_INCLUDED_VAT = 'is_included_VAT' + code_currency = 1 + KEY_CODE_CURRENCY = 'id_currency' + code_region_delivery = 1 + KEY_CODE_REGION_DELIVERY = 'id_region_delivery' + KEY_ID_CURRENCY = 'id_currency' + KEY_ID_REGION_DELIVERY = 'id_region_delivery' + """ + id_currency = 1 + id_region_delivery = 1 + +class DevelopmentConfig(Config): + DEBUG = True + # Add development-specific configuration variables + +class ProductionConfig(Config): + # Add production-specific configuration variables + pass + +# Set the configuration class based on the environment +# You can change 'development' to 'production' when deploying +config_env = 'development' +if config_env == 'development': + app_config = DevelopmentConfig +elif config_env == 'production': + app_config = ProductionConfig +else: + raise ValueError("Invalid configuration environment") + + diff --git a/datastores/__init__.py b/datastores/__init__.py new file mode 100644 index 00000000..c05a52e4 --- /dev/null +++ b/datastores/__init__.py @@ -0,0 +1,11 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Module Initialisation +Feature: DataStores + +Description: +Initialises datastores module. +""" diff --git a/datastores/__pycache__/__init__.cpython-311.pyc b/datastores/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 00000000..9022d72f Binary files /dev/null and b/datastores/__pycache__/__init__.cpython-311.pyc differ diff --git a/datastores/__pycache__/datastore_store.cpython-311.pyc b/datastores/__pycache__/datastore_store.cpython-311.pyc new file mode 100644 index 00000000..c081b60b Binary files /dev/null and b/datastores/__pycache__/datastore_store.cpython-311.pyc differ diff --git a/datastores/datastore_store.py b/datastores/datastore_store.py new file mode 100644 index 00000000..4c876d54 --- /dev/null +++ b/datastores/datastore_store.py @@ -0,0 +1,738 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: DataStores +Feature: Store DataStore + +Description: +Datastore for Store +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# METHODS + +# IMPORTS +# internal +# from routes import bp_home +import lib.argument_validation as av +from business_objects.category import Category_List, Category +from business_objects.product import Product, Product_Permutation, Price, Product_Filters # Permutation_Variation_Link +from business_objects.variation import Variation +from business_objects.image import Image +from business_objects.currency import Currency +from business_objects.delivery_region import Delivery_Region +from business_objects.delivery_option import Delivery_Option +from business_objects.discount import Discount +from business_objects.basket import Basket, Basket_Item +from business_objects.order import Order +from business_objects.sql_error import SQL_Error +# from models.model_view_store_checkout import Model_View_Store_Checkout # circular! +# external +# from abc import ABC, abstractmethod, abstractproperty +from flask_sqlalchemy import SQLAlchemy +from sqlalchemy import text +import stripe +import os + + +# VARIABLE INSTANTIATION + + +# CLASSES +class DataStore_Store(): + KEY_IS_INCLUDED_VAT = 'is_included_VAT' + KEY_ID_CURRENCY = 'id_currency' + KEY_ID_REGION_DELIVERY = 'id_region_delivery' + # Attributes + db: SQLAlchemy + # Global constants + + def __new__(cls, db, info_user, app): + # Initialiser - validation + _m = 'DataStore_Store.__new__' + v_arg_type = 'class attribute' + av.val_instance(db, 'db', _m, SQLAlchemy, v_arg_type=v_arg_type) + return super(DataStore_Store, cls).__new__(cls) + + def __init__(self, db, info_user, app): + # Constructor + self.db = db + self.info_user = info_user + self.app = app + self.key_secret_stripe = os.environ.get("KEY_SECRET_STRIPE") + self.key_public_stripe = os.environ.get("KEY_PUBLIC_STRIPE") + + # For sample support and debugging, not required for production: + stripe.set_app_info( + 'stripe-samples/checkout-one-time-payments', + version='0.0.1', + url='https://github.com/stripe-samples/checkout-one-time-payments') + + stripe.api_key = self.key_secret_stripe + + + def get_many_product_category(self, product_filters): + # redundant argument validation? + _m = 'DataStore_Store.get_many_product_category' + av.val_instance(product_filters, 'product_filters', _m, Product_Filters) + """ + av.val_str(category_ids, 'category_ids', _m) + av.val_str(product_ids, 'product_ids', _m) + av.val_bool(get_all_category, 'get_all_category', _m) + av.val_bool(get_all_product, 'get_all_product', _m) + av.val_int(max_products_per_category, 'max_products_per_category', _m) + argument_dict_list = { + 'a_id_user': self.info_user.get('sub'), + 'a_get_all_categories': 0, + 'a_ids_category': category_ids, + 'a_get_inactive_categories': 0, + 'a_ids_product': product_ids, + 'a_get_inactive_products': 0, + 'a_get_first_product_only': 1 if (max_products_per_category == 1) else 0, + 'a_get_all_products': 1 if get_all_product else 0, + 'a_ids_image': '', + 'a_get_inactive_images': 0, + 'a_get_first_image_only': 0, + 'a_get_all_images': 1 + } + """ + argument_dict = product_filters.to_json() + print(f'argument_dict: {argument_dict}') + print('executing p_shop_get_many_product') + result = self.db_procedure_execute('p_shop_get_many_product', argument_dict) + cursor = result.cursor + print('data received') + # categories, category_index = DataStore_Store.input_many_product(cursor) + category_list, errors = DataStore_Store.input_many_product(cursor) + DataStore_Store.db_cursor_clear(cursor) + + return category_list, errors # categories, category_index + + + def edit_basket(self, ids_permutation_basket, quantities_permutation_basket, id_permutation_edit, quantity_permutation_edit, sum_not_edit, id_currency, id_region_delivery): + # redundant argument validation? + _m = 'DataStore_Store.edit_basket' + print(f'{_m}\nstarting...') + # av.val_instance(filters, 'filters', _m, Product_Category_Filters) + # av.val_str(ids_product_basket, 'ids_product_basket', _m) + av.val_str(ids_permutation_basket, 'ids_permutation_basket', _m) + # av.val_str(quantities_product_basket, 'quantities_product_basket', _m) + av.val_str(quantities_permutation_basket, 'quantities_permutation_basket', _m) + """ + if id_product_edit == 'None': + id_product_edit = None + else: + print(f'id_product_edit: {id_product_edit}') + av.val_int(id_product_edit, 'id_product_edit', _m) + """ + if id_permutation_edit == 'None' or str(type(id_permutation_edit)) =="": + id_permutation_edit = None + else: + print(f'id_permutation_edit: {id_permutation_edit}') + print(str(type(id_permutation_edit))) + av.val_int(id_permutation_edit, 'id_permutation_edit', _m) + if quantity_permutation_edit == 'None' or str(type(quantity_permutation_edit)) =="": + quantity_permutation_edit = None + else: + print(f'quantity_permutation_edit: {quantity_permutation_edit}') + av.val_int(quantity_permutation_edit, 'quantity_permutation_edit', _m) + if sum_not_edit == 'None': + sum_not_edit = None + else: + print(f'sum_not_edit: {sum_not_edit}') + av.val_bool(sum_not_edit, 'sum_not_edit', _m) + + argument_dict_list = { + 'a_id_user': self.info_user.get('sub'), + # 'a_ids_product_basket': ids_product_basket, + 'a_ids_permutation_basket': ids_permutation_basket, + # 'a_quantities_product_basket': quantities_product_basket, + 'a_quantities_permutation_basket': quantities_permutation_basket, + # 'a_id_product_edit': id_product_edit if id_permutation_edit is None else None, + 'a_id_permutation_edit': id_permutation_edit, + 'a_quantity_permutation_edit': quantity_permutation_edit, + 'a_sum_not_edit': 1 if sum_not_edit else 0, + 'a_id_currency': id_currency, + 'a_id_region_purchase': id_region_delivery + } + + result = self.db_procedure_execute('p_shop_edit_user_basket', argument_dict_list) + print('data received') + + cursor = result.cursor + + # categories, category_index = DataStore_Store.input_many_product(cursor) + category_list, errors = DataStore_Store.input_many_product(cursor) + + print(f'cursor: {str(cursor)}') + + # Basket + if not cursor.nextset(): + raise Exception("No more query results! Cannot open basket contents") + result_set = cursor.fetchall() + print(f'raw basket: {result_set}') + # print(f'variations: {result_set_3}') + # variations = [Variation(**row) for row in result_set_3] + basket = Basket() + for row in result_set: + index_category = category_list.get_index_category_from_id(row[0]) + category = category_list.categories[index_category] + index_product = category.get_index_product_from_id(row[1]) + product = category.products[index_product] + basket_item = Basket_Item.make_from_product_and_quantity_and_VAT_included(product, row[7], self.app.is_included_VAT) + print(f'adding basket item: {row}') + print(f'basket item: {basket_item}') + basket.add_item(basket_item) # basket.append(basket_item) # Basket_Item(category.name, product, row[4])) + + print(f'basket: {basket}') + + # Errors + cursor.nextset() + result_set_e = cursor.fetchall() + print(f'raw errors: {result_set_e}') + if len(result_set_e) > 0: + errors = [SQL_Error.make_from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_2] + for error in errors: + print(f"Error [{error.code}]: {error.msg}") + + DataStore_Store.db_cursor_clear(cursor) + + return basket + + def edit_user(self): + # redundant argument validation? + _m = 'DataStore_Store.edit_user' + # av.val_instance(filters, 'filters', _m, Product_Category_Filters) + + argument_dict_list = { + 'a_id_user': self.info_user.get('sub'), + 'a_name': self.info_user.get('name'), + 'a_email': self.info_user.get('email'), + 'a_email_verified': 1 if self.info_user.get('email_verified') == 'True' else 0 + } + + result = self.db_procedure_execute('p_shop_edit_user', argument_dict_list) + cursor = result.cursor + + result_set_1 = cursor.fetchall() + print(f'raw user data: {result_set_1}') + + # Errors + cursor.nextset() + result_set_e = cursor.fetchall() + print(f'raw errors: {result_set_e}') + if len(result_set_e) > 0: + errors = [SQL_Error.make_from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_2] + for error in errors: + print(f"Error [{error.code}]: {error.msg}") + + DataStore_Store.db_cursor_clear(cursor) + + return (result_set_1[0][1] == b'\x01') + + + def db_procedure_execute(self, proc_name, argument_dict_list = None): + # Argument validation + _m = 'DataStore_Store.db_procedure_execute' + av.val_str(proc_name, 'proc_name', _m) + has_arguments = not str(type(argument_dict_list)) == "" + if has_arguments: + # av.val_list_instances(argument_dict_list, 'argument_dict_list', _m, dict) + pass + # Methods + proc_string = f'CALL {proc_name}(' + if has_arguments: + arg_keys = list(argument_dict_list.keys()) + for i in range(len(arg_keys)): + proc_string += f'{"" if i == 0 else ", "}:{arg_keys[i]}' + proc_string += ')' + proc_string = text(proc_string) + print(f'{_m}\nproc_string: {proc_string}\nargs: {argument_dict_list}') + # with self.db.session.begin() as session: + if has_arguments: + result = self.db.session.execute(proc_string, argument_dict_list) + else: + result = self.db.session.execute(proc_string) + print(f'result: {result}') + return result + cursor = result.cursor + result_set_1 = cursor.fetchall() + print(f'categories: {result_set_1}') + cursor.nextset() + result_set_2 = cursor.fetchall() + print(f'products: {result_set_2}') + + """ + def get_many_id_price(self, product_ids): + _m = 'DataStore_Store.get_many_id_price' + av.val_str(product_ids, 'product_ids', _m) + price_ids = [] + for product_id in product_ids.split(','): + if product_id == 'prod_PB0NUOSEs06ymG': + price_ids.append() # get price id + return price_ids + """ + + def input_many_product(cursor): + _m = 'DataStore_Store.input_many_product' + category_list = Category_List() + # Categories + result_set_1 = cursor.fetchall() + print(f'raw categories: {result_set_1}') + # categories = [Category(row[0], row[1], row[2], row[3]) for row in result_set_1] + # categories = [] + # category_index = {} + for row in result_set_1: + new_category = Category.make_from_DB_product(row) # Category(row[0], row[1], row[2], row[3]) + # category_index[new_category.id_category] = len(categories) + # categories.append(new_category) + category_list.add_category(new_category) + # print(f'categories: {[c.id_category for c in categories]}') + + # Products + cursor.nextset() + result_set_2 = cursor.fetchall() + # print(f'products: {result_set_2}') + products = [] # [Product(**row) for row in result_set_2] + product_index = {} + for row in result_set_2: + new_permutation = Product_Permutation.make_from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19]) + index_category = category_list.get_index_category_from_id(new_permutation.id_category) + category = category_list.categories[index_category] + try: + index_product = category.get_index_product_from_id(new_permutation.id_product) + category_list.add_permutation(new_permutation) + # product = products[index_product] + # product.add_permutation(new_permutation) + except KeyError: + product_index[new_permutation.id_product] = len(products) + product = Product.make_from_DB_product(row) + product.add_permutation(new_permutation) + products.append(product) + # categories[category_index[new_product.id_category]].add_product(new_product) + category_list.add_product(product) + # category_list.add_permutation(new_permutation) + # print(f'products: {[p.id_product for p in products]}') # {products}') + print(f'category_list: {category_list}') + + # Variations + cursor.nextset() + result_set_3 = cursor.fetchall() + # print(f'variations: {result_set_3}') + # variations = [Variation(**row) for row in result_set_3] + variations = [] + for row in result_set_3: + new_variation = Variation.make_from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]) + variations.append(new_variation) + # products[product_index[new_variation.id_product]].variations.append(new_variation) + # index_category = category_index[new_variation.id_category] + # index_product = categories[index_category].index_product_from_ids_product_permutation(new_variation.id_product, new_variation.id_permutation) + # categories[index_category].products[index_product].variations.append(new_variation) + category_list.add_variation(new_variation) + # print(f'variations: {variations}') + # print(f'products: {[p.id_product for p in products]}') + + """ + # Permutation Variation Links + cursor.nextset() + result_set_4 = cursor.fetchall() + # print(f'variations: {result_set_3}') + # variations = [Variation(**row) for row in result_set_3] + permutation_variation_links = [] + for row in result_set_3: + permutation_variation_link = Permutation_Variation_Link.make_from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]) + permutation_variation_links.append(permutation_variation_link) + # categories[category_index[new_variation.id_category]].products[categories[category_index[new_variation.id_category]].product_index[new_variation.id_product]].variations.append(new_variation) + categories[category_index[new_variation.id_category]].products[categories[category_index[new_variation.id_category]].product_index[new_variation.id_product]].variations.append(new_variation) + print(f'variations: {variations}') + print(f'products: {[p.id_product for p in products]}') + """ + + # Prices + cursor.nextset() + result_set_4 = cursor.fetchall() + # print(f'variations: {result_set_3}') + # variations = [Variation(**row) for row in result_set_3] + prices = [] + for row in result_set_4: + price = Price.make_from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]) + prices.append(price) + """ + index_category = category_index[price.id_category] + index_product = categories[index_category].index_product_from_ids_product_permutation(price.id_product, price.id_permutation) + categories[index_category].products[index_product].prices.append(price) + """ + category_list.add_price(price) + # print(f'prices: {prices}') + # print(f'products: {[p.id_product for p in products]}') + + """ + # Currencies + cursor.nextset() + result_set_5 = cursor.fetchall() + # print(f'variations: {result_set_3}') + # variations = [Variation(**row) for row in result_set_3] + prices = [] + for row in result_set_4: + price = Price.make_from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]) + prices.append(price) + index_category = category_index[price.id_category] + categories[index_category].products[index_category].product_index[price.id_product].prices.append(price) + print(f'prices: {prices}') + print(f'products: {[p.id_product for p in products]}') + """ + + # Images + cursor.nextset() + result_set_5 = cursor.fetchall() + # print(f'images: {result_set_4}') + # images = [Image(**row) for row in result_set_4] + images = [] + for row in result_set_5: + new_image = Image.make_from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4]) + images.append(new_image) + # products[product_index[new_image.id_product]].images.append(new_image) + """ + index_category = category_index[new_image.id_category] + index_product = categories[index_category].index_product_from_ids_product_permutation(new_image.id_product, new_image.id_permutation) + categories[index_category].products[index_product].images.append(new_image) + """ + category_list.add_image(new_image) + # print(f'images: {images}') + # print(f'products: {[p.id_product for p in products]}') + + # Delivery options + cursor.nextset() + result_set_7 = cursor.fetchall() + delivery_options = [] + for row in result_set_7: + new_delivery_option = Delivery_Option.make_from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12]) + delivery_options.append(new_delivery_option) + # products[product_index[new_delivery_option.id_product]].delivery_options.append(new_delivery_option) + """ + index_category = category_index[new_delivery_option.id_category] + index_product = categories[index_category].index_product_from_ids_product_permutation(new_delivery_option.id_product, new_delivery_option.id_permutation) + categories[index_category].products[index_product].delivery_options.append(new_delivery_option) + """ + category_list.add_delivery_option(new_delivery_option) + # print(f'delivery_options: {delivery_options}') + # print(f'products: {products}') + + # Discounts + cursor.nextset() + result_set_8 = cursor.fetchall() + discounts = [] + for row in result_set_8: + new_discount = Discount.make_from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10]) + discounts.append(new_discount) + # i_cat = category_index[new_discount.id_category] + # categories[i_cat].products[categories[i_cat].product_index[new_delivery_option.id_product]].discounts.append(new_delivery_option) + # categories[i_cat].products[categories[i_cat].product_index[new_delivery_option.id_product]].discount_index[new_discount.id_discount] = len(categories[i_cat].products[categories[i_cat].product_index[new_delivery_option.id_product]].discounts) + # categories[i_cat].products[categories[i_cat].product_index[new_delivery_option.id_product]].discounts.append(new_discount) + """ + index_category = category_index[new_discount.id_category] + index_product = categories[index_category].index_product_from_ids_product_permutation(new_discount.id_product, new_discount.id_permutation) + categories[index_category].products[index_product].add_discount(new_discount) + """ + category_list.add_discount(new_discount) + # print(f'discounts: {discounts}') + # print(f'products: {products}') + + """ + # Delivery Regions + cursor.nextset() + result_set_6 = cursor.fetchall() + delivery_regions = [] + for row in result_set_6: + new_delivery_region = Delivery_Region.make_from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6]) + delivery_regions.append(new_delivery_region) + # products[product_index[new_delivery_option.id_product]].delivery_regions.append(new_delivery_region) + i_cat = category_index[new_delivery_region.id_category] + i_prod = categories[i_cat].product_index[new_delivery_region.id_product] + categories[i_cat].products[i_prod].discounts[categories[i_cat].products[i_prod]. + categories[i_cat].products[i_prod].discounts[categories[i_cat].products[i_prod].discount_index[new_delivery_region.id_discount]].delivery_regions.append(new_delivery_region) + print(f'delivery_regions: {delivery_regions}') + print(f'products: {products}') + """ + + # Errors + cursor.nextset() + result_set_e = cursor.fetchall() + print(f'raw errors: {result_set_e}') + errors = [] + if len(result_set_e) > 0: + errors = [SQL_Error.make_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}") + + category_list.get_all_variation_trees() + """ + for category in category_list.categories: + print(f'category: {category.name}') + for product in category.products: + permutation = product.get_permutation_selected() + print(f'product: {product.name}\nselected permutation: {permutation}') + """ + + if len(errors) > 0: + for error in errors: + if error.code == 'PRODUCT_AVAILABILITY': + ids_permutation_unavailable = DataStore_Store.get_ids_permutation_from_error_availability(error.msg) + for id_permutation in ids_permutation_unavailable: + index_category = category_list.get_index_category_from_id_permutation(id_permutation) + category = category_list.categories[index_category] + index_product = category.get_index_product_from_id_permutation(id_permutation) + product = category.products[index_product] + index_permutation = product.get_index_permutation_from_id(id_permutation) + permutation = product.permutations[index_permutation] + permutation.is_available = False + if 'region' in error.msg or 'currency' in error.msg: + permutation.is_unavailable_in_currency_or_region = True + + return category_list, errors # categories, category_index + + def db_cursor_clear(cursor): + while cursor.nextset(): + print(f'new result set: {cursor.fetchall()}') + + def get_ids_permutation_from_error_availability(msg_error_availability): + ids_permutation = [] + index_colon = msg_error_availability.find(':', msg_error_availability.find(':')) + msg_error_availability = msg_error_availability[index_colon + 1:] + index_comma = 0 + while index_comma > -1: + msg_error_availability = msg_error_availability[index_comma:] + index_comma = msg_error_availability.find(',') + ids_permutation.append(msg_error_availability[:index_comma]) + return ids_permutation + + def get_many_user_order(self, id_user, ids_order, n_order_max, id_checkout_session): + _m = 'Model_View_Store.get_many_user_order' + # av.val_str(id_user) + # validation conducted by server + + argument_dict_list = { + 'a_id_user': id_user, + 'a_ids_order': ids_order, + 'a_n_order_max': n_order_max, + 'a_id_checkout_session': id_checkout_session + } + + print('executing p_shop_get_many_user_order') + result = self.db_procedure_execute('p_shop_get_many_user_order', argument_dict_list) + cursor = result.cursor + print('data received') + + + # Discount Delivery Regions + cursor.nextset() + result_set_1 = cursor.fetchall() + orders = [] + for row in result_set_1: + new_order = Order(row[0], row[1], row[2], row[3], row[4], row[5], row[6]) + orders.append(new_order) + print(f'orders: {orders}') + + # Errors + cursor.nextset() + result_set_e = cursor.fetchall() + print(f'raw errors: {result_set_e}') + if len(result_set_e) > 0: + errors = [SQL_Error.make_from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_e] + for error in errors: + print(f"Error [{error.code}]: {error.msg}") + + DataStore_Store.db_cursor_clear(cursor) + + return orders + + def get_many_stripe_product_new(self): + _m = 'Model_View_Store.get_many_stripe_product_new' + _m_db = 'p_shop_get_many_stripe_product_new' + # av.val_str(id_user) + # validation conducted by server + + argument_dict_list = { + 'a_id_user': self.info_user + } + + print(f'executing {_m_db}') + result = self.db_procedure_execute(_m_db, argument_dict_list) + cursor = result.cursor + print('data received') + + + # Products + cursor.nextset() + result_set_1 = cursor.fetchall() + products = [] + for row in result_set_1: + new_product = Product.make_from_DB_Stripe_product(row) # Product(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19]) + products.append(new_product) + print(f'products: {products}') + + # Errors + cursor.nextset() + result_set_e = cursor.fetchall() + print(f'raw errors: {result_set_e}') + if len(result_set_e) > 0: + errors = [SQL_Error.make_from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_e] + for error in errors: + print(f"Error [{error.code}]: {error.msg}") + + DataStore_Store.db_cursor_clear(cursor) + + return products + + def get_many_stripe_price_new(self): + _m = 'Model_View_Store.get_many_stripe_price_new' + _m_db = 'p_shop_get_many_stripe_price_new' + # av.val_str(id_user) + # validation conducted by server + + argument_dict_list = { + 'a_id_user': self.info_user + } + + print(f'executing {_m_db}') + result = self.db_procedure_execute(_m_db, argument_dict_list) + cursor = result.cursor + print('data received') + + + # Products + cursor.nextset() + result_set_1 = cursor.fetchall() + products = [] + for row in result_set_1: + new_product = Product.make_from_DB_Stripe_price(row) # Product(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19]) + products.append(new_product) + print(f'products: {products}') + + # Errors + cursor.nextset() + result_set_e = cursor.fetchall() + print(f'raw errors: {result_set_e}') + if len(result_set_e) > 0: + errors = [SQL_Error.make_from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_e] + for error in errors: + print(f"Error [{error.code}]: {error.msg}") + + DataStore_Store.db_cursor_clear(cursor) + + return products + + def get_many_product_new(self): + _m = 'Model_View_Store.get_many_product_new' + # Stripe + new_products = self.get_many_stripe_product_new() + for product in new_products: + product.id_stripe_product = self.create_stripe_product(product) + return new_products + + def get_many_price_new(self): + _m = 'Model_View_Store.get_many_product_new' + # Stripe + new_products = self.get_many_stripe_price_new() + for product in new_products: + product.id_stripe_price = self.create_stripe_price(product) + return new_products + + # Stripe + def create_stripe_product(self, product): # _name, product_description): + _m = 'Model_View_Store_Checkout.create_stripe_product' + # av.val_str(product_name, 'product_name', _m) + # av.val_str(product_description, 'product_description', _m) + av.val_instance(product, 'product', _m, Product) + + print(f'stripe.api_key = {stripe.api_key}') + new_product = stripe.Product.create( + name = product.name, + description = product.description, + ) + + # Save these identifiers + print(f"Success! Here is your new Stripe product id: {new_product.id}") + + return new_product.id + + def create_stripe_price(self, product, currency): # product_id, product_price, product_currency, product_is_subscription, product_recurring_interval = '', product_interval_count = 0): + _m = 'Model_View_Store_Checkout.create_stripe_price' + """ + av.val_str(p_id, 'p_id', _m) + av.full_val_float(p_price, 'p_price', _m, 0.01) + p_price = round(p_price, 2) + av.val_str(p_currency, 'p_currency', _m) + av.full_val_bool(p_is_subscription, 'p_is_subscription', _m) + p_is_subscription = bool(p_is_subscription) + av.val_str(p_recurring_interval, 'p_recurring_interval', _m) + av.full_val_int(p_interval_count, 'p_interval_count', _m, 1 if p_is_subscription else 0) + p_interval_count = int(p_interval_count) + """ + av.val_instance(product, 'product', _m, Product) + av.val_str(currency, 'currency', _m) + + print(f'stripe.api_key = {stripe.api_key}') + + new_product_price = stripe.Price.create( + unit_amount = product.unit_price, + currency = currency, + recurring = { "interval": product.name_recurring_interval, "interval_count": product.count_recurring_interval } if product.is_subscription else None, + product = product.id_stripe_product + ) + + # Save these identifiers + print(f"Success! Here is your Stripe product price id: {new_product_price.id} for {product.name}") + + return new_product_price.id + + def get_regions_and_currencies(self): + _m = 'Model_View_Store.get_regions_and_currencies' + _m_db_currency = 'p_shop_get_many_currency' + _m_db_region = 'p_shop_get_many_region' + + argument_dict_list_currency = { + 'a_get_inactive_currency': 0 + } + argument_dict_list_region = { + 'a_get_inactive_currency': 0 + } + + print(f'executing {_m_db_currency}') + result = self.db_procedure_execute(_m_db_currency, argument_dict_list_currency) + cursor = result.cursor + print('data received') + + # cursor.nextset() + result_set_1 = cursor.fetchall() + currencies = [] + for row in result_set_1: + currency = Currency.make_from_DB_currency(row) + currencies.append(currency) + print(f'currencies: {currencies}') + DataStore_Store.db_cursor_clear(cursor) + + print(f'executing {_m_db_region}') + result = self.db_procedure_execute(_m_db_region, argument_dict_list_region) + cursor = result.cursor + print('data received') + + # cursor.nextset() + result_set_1 = cursor.fetchall() + regions = [] + for row in result_set_1: + region = Delivery_Region.make_from_DB_region(row) + regions.append(region) + print(f'regions: {regions}') + DataStore_Store.db_cursor_clear(cursor) + + return regions, currencies + + def get_metadata_basket(json_request): + is_included_VAT = json_request[DataStore_Store.KEY_IS_INCLUDED_VAT] + id_currency = json_request[DataStore_Store.KEY_ID_CURRENCY] + id_region_delivery = json_request[DataStore_Store.KEY_ID_REGION_DELIVERY] + return id_currency, id_region_delivery, is_included_VAT \ No newline at end of file diff --git a/forms.py b/forms.py new file mode 100644 index 00000000..7154480c --- /dev/null +++ b/forms.py @@ -0,0 +1,102 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Backend +Feature: Forms - User data input + +Description: +Defines Flask-WTF forms for handling user input. +""" + +# IMPORTS +# internal +# from models.model_view_store import Model_View_Store # circular +# external +from flask_wtf import FlaskForm +from wtforms import StringField, TextAreaField, SubmitField, BooleanField, IntegerField, SelectField +from wtforms.validators import InputRequired, NumberRange, Regexp, DataRequired + + + +class Form_Contact(FlaskForm): + email = StringField('Email address') + CC = BooleanField('Would you like to receive a copy of this email request?') # not in use + name = StringField('Name') + msg = TextAreaField('Message') + submit = SubmitField('Submit') + +class Form_Register(FlaskForm): + email = StringField('Email address') + CC = BooleanField('Would you like to receive a copy of this email request?') # not in use + name = StringField('Name') + msg = TextAreaField('Message') + submit = SubmitField('Submit') + + +""" +class Form_Product(FlaskForm): # for basket, product tiles, product add + # PositiveIntegerField with validation constraints + quantity = IntegerField( + 'Quantity', + validators=[ + # InputRequired(message='Quantity'), + NumberRange(min=1, message='Please enter a positive integer') + ], + default=1 + ) +""" + +class Form_Basket_Add(FlaskForm): # for basket, product tiles, product add + # PositiveIntegerField with validation constraints + quantity = IntegerField( + 'Quantity', + validators=[ + # InputRequired(message='Quantity'), + NumberRange(min=1, message='Please enter a positive integer') + ], + default=1 + # render_kw={'id-product': ''} # {Model_View_Store.attr_id_product: ''} + ) + submit = SubmitField('Add') + form_type = 'Form_Basket_Add' + +class Form_Basket_Edit(FlaskForm): # for basket, product tiles, product add + # PositiveIntegerField with validation constraints + quantity = IntegerField( + 'Quantity', + validators=[ + # InputRequired(message='Quantity'), + NumberRange(min=1, message='Please enter a positive integer') + ], + default=1 + # render_kw={'id-product': ''} # {Model_View_Store.attr_id_product: ''} + ) + submit = SubmitField('Update') + form_type = 'Form_Basket_Edit' + +class Form_Billing(FlaskForm): + identical = BooleanField('Use delivery address') + region = SelectField('Country / region', choices=[('uk', 'UK'), ('international', 'International')], validators=[DataRequired()]) + name_full = StringField('Full name') + phone_number = StringField('Phone number', validators=[Regexp(r'^\+?[0-9\s]{5,20}$', message='Only numbers, plus symbol, and space are allowed.'), DataRequired()]) + postcode = StringField('Post code', validators=[DataRequired()]) + address_1 = StringField('Address line 1', validators=[DataRequired()]) + address_2 = StringField('Address line 2 (optional)') + city = StringField('City', validators=[DataRequired()]) + county = StringField('County', validators=[DataRequired()]) + submit = SubmitField('Submit') + form_type_billing_not_delivery = False + + def output_id(self): + return 'formBilling' if self.form_type_billing_not_delivery else 'formDeliver' + +class Form_Is_Included_VAT(FlaskForm): + is_included = BooleanField('Include VAT') + +class Form_Delivery_Region(FlaskForm): + id_region_delivery = SelectField('Region') + +class Form_Currency(FlaskForm): + id_currency = SelectField('Currency') \ No newline at end of file diff --git a/helpers/__init__.py b/helpers/__init__.py new file mode 100644 index 00000000..54cd3709 --- /dev/null +++ b/helpers/__init__.py @@ -0,0 +1,11 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Module Initialisation +Feature: Helpers + +Description: +Initialises helpers module. +""" diff --git a/lib/__init__.py b/lib/__init__.py new file mode 100644 index 00000000..1b31e3f2 --- /dev/null +++ b/lib/__init__.py @@ -0,0 +1,11 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Module Initialisation +Feature: Library + +Description: +Initialises library module. +""" diff --git a/lib/__pycache__/__init__.cpython-311.pyc b/lib/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 00000000..6733d0f1 Binary files /dev/null and b/lib/__pycache__/__init__.cpython-311.pyc differ diff --git a/lib/__pycache__/argument_validation.cpython-311.pyc b/lib/__pycache__/argument_validation.cpython-311.pyc new file mode 100644 index 00000000..4f6636f0 Binary files /dev/null and b/lib/__pycache__/argument_validation.cpython-311.pyc differ diff --git a/lib/__pycache__/data_types.cpython-311.pyc b/lib/__pycache__/data_types.cpython-311.pyc new file mode 100644 index 00000000..9ac28162 Binary files /dev/null and b/lib/__pycache__/data_types.cpython-311.pyc differ diff --git a/lib/argument_validation.py b/lib/argument_validation.py new file mode 100644 index 00000000..e656c388 --- /dev/null +++ b/lib/argument_validation.py @@ -0,0 +1,1315 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Apr 27 12:33:59 2023 + +@author: Edward Middleton-Smith + +Argument Validation +""" + +# CLASSES +# ATTRIBUTE DECLARATION +# METHODS + # FUNCTION + # ARGUMENTS + # ARGUMENT VALIDATION + # ATTRIBUTE + VARIABLE INSTANTIATION + # METHODS + # RETURNS + +# NORMAL METHODS +# FUNCTION +# ARGUMENTS +# ARGUMENT VALIDATION +# VARIABLE INSTANTIATION +# METHODS +# RETURNS + +from typing import Optional + +def error_msg_str(v, v_name, method, v_type, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # return error message string for output of invalid argument / attribute to user +# ARGUMENTS + # str method - name of parent method which calls this function + # str arg_name - name of argument throwing error + # ? v - erroneous variable + # str v_type - desired / expected variable type + # str arg_type - e.g. argument, attribute + # bool suppress_errors - should outputs not be raised as errors? + # bool suppress_console_outputs +# ARGUMENT VALIDATION + my_f = 'error_msg_str' + # suppress_errors + if not val_bool(suppress_errors, 'suppress_errors', my_f): + error_msg = error_msg_str(suppress_errors, 'suppress_errors', my_f, "") + raise ValueError(error_msg) + # suppress_console_outputs + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + error_msg = error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors) + if suppress_errors: + print(error_msg) + return error_msg + else: + raise ValueError(error_msg) + # method + if not val_str(method, 'method', my_f, suppress_errors=suppress_errors, suppress_console_outputs=suppress_console_outputs): + error_msg = error_msg_str(method, 'method', my_f, "", suppress_errors, suppress_console_outputs) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return error_msg + else: + raise ValueError(error_msg) + my_f = method + '.' + my_f + # v_name + if not val_str(v_name, 'v_name', my_f, -1, -1, suppress_errors, suppress_console_outputs): + error_msg = error_msg_str(v_name, 'v_name', my_f, "", suppress_errors, suppress_console_outputs) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return error_msg + else: + raise ValueError(error_msg) + # v_type + if isinstance(v_type, type): + v_type = str(v_type) + if not val_str(v_type, 'v_type', my_f, -1, -1, suppress_errors, suppress_console_outputs): + error_msg = error_msg_str(v_type, 'v_type', my_f, "", suppress_errors, suppress_console_outputs) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return error_msg + else: + raise ValueError(error_msg) + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, -1, -1, suppress_errors, suppress_console_outputs): + error_msg = error_msg_str(v_arg_type, 'v_arg_type', my_f, "", suppress_errors, suppress_console_outputs) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return error_msg + else: + raise ValueError(error_msg) +# RETURNS + return f"Invalid {method} {v_type} {v_arg_type} {v_name}. Type = {str(type(v))}. Value = {v}" + +def val_bool(v_input, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # validate that myinput is of type bool +# ARGUMENTS + # bool (hopefully) myinput + # str v_name + # str method + # optional bool suppress_errors + # optional bool suppress_console_outputs + # optional str v_arg_type +# ARGUMENT VALIDATION + # validate bool inputs first + v_type = "" + my_f = 'val_bool' + if str(type(suppress_errors)) != v_type: + raise ValueError(error_msg_str(suppress_errors, 'suppress_errors', my_f, v_type)) + if str(type(suppress_console_outputs)) != v_type: + error_msg = error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, v_type, suppress_errors) + if suppress_errors: + print(error_msg) + return False + raise ValueError(error_msg) + v_type = "" + # method + valid = True + if str(type(method)) != v_type: + valid = False + else: + if len(method) < 1: + valid = False + if not valid: + error_msg = error_msg_str(method, 'method', my_f, v_type, suppress_errors, suppress_console_outputs) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + my_f = method + '.' + my_f + # v_name + valid = True + if str(type(v_name)) != v_type: + valid = False + else: + if len(v_name) < 1: + valid = False + if not valid: + error_msg = error_msg_str(v_name, 'v_name', my_f, v_type, suppress_errors, suppress_console_outputs) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + # v_arg_type + valid = True + if str(type(v_arg_type)) != v_type: + valid = False + else: + if len(v_arg_type) < 1: + valid = False + if not valid: + error_msg = error_msg_str(v_arg_type, 'v_arg_type', my_f, v_type, suppress_errors, suppress_console_outputs) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + else: + raise ValueError(error_msg) + # v_input + v_type = "" + if (str(type(v_input)) != v_type): + error_msg = error_msg_str(v_input, v_name, method, v_type, suppress_errors, suppress_console_outputs) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) +# RETURNS + return True + + +def val_str(v_input, v_name, method, min_len = -1, max_len = -1, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # validate that v_input is of type str +# ARGUMENTS + # str (hopefully) v_input + # str v_name + # str method + # optional int min_len + # optional int max_len + # optional bool suppress_errors + # optional bool suppress_console_outputs + # optional str v_arg_type +# ARGUMENT VALIDATION + my_f = 'val_str' + v_type = "" + # suppress_errors + val_bool(suppress_errors, 'suppress_errors', my_f) + # suppress_console_outputs + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors)) + return False + # method + valid = True + if str(type(method)) != v_type: + valid = False + else: + if len(method) < 1: + valid = False + if not valid: + error_msg = error_msg_str(method, 'method', my_f, v_type) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + my_f = method + '.' + my_f + # v_name + valid = True + if str(type(v_name)) != v_type: + valid = False + else: + if len(v_name) < 1: + valid = False + if not valid: + error_msg = error_msg_str(v_name, 'v_name', my_f, v_type) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + # v_arg_type + valid = True + if str(type(v_arg_type)) != v_type: + valid = False + else: + if len(v_arg_type) < 1: + valid = False + if not valid: + error_msg = error_msg_str(v_arg_type, 'v_arg_type', my_f, v_type) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + # min_len + v_type = "" + if str(type(min_len)) != v_type: + error_msg = error_msg_str(min_len, 'min_len', my_f, v_type) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + # max_len + v_type = "" + valid = True + if str(type(max_len)) != v_type: + valid = False + else: + if max_len != -1 and max_len < min_len: + valid = False + if not valid: + error_msg = error_msg_str(max_len, 'max_len', my_f, v_type) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + # v_input +# VARIABLE INSTANTIATION + v_type = "" + valid = True +# METHODS + if str(type(v_input)) != v_type: + valid = False + else: + L = len(v_input) + if min_len != -1 and L < min_len: + valid = False + print(f"Minimum str length {min_len} not met.") + if max_len != -1 and L > max_len: + print(f"Maximum str length {max_len} not met.") + valid = False + if not valid: + error_msg = error_msg_str(v_input, v_name, method, v_type, suppress_errors, suppress_console_outputs, v_arg_type) + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) +# RETURNS + return True + +# def val_none(v_input, v_name, method, v_arg_type = 'argument', suppress_errors = False, suppress_console_outputs = False): +# # FUNCTION +# # evaluate if v_input is None +# # ARGUMENTS +# # ARGUMENT VALIDATION +# # VARIABLE INSTANTIATION +# # METHODS +# # RETURNS + +def val_int(v_input, v_name, method, v_min: Optional[int] = None, v_max: Optional[int] = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # validate that myinput is of type int, and if not None, limited by v_min and v_max +# ARGUMENTS + # int (hopefully) myinput + # str v_name + # str method + # optional int v_min + # optional int v_max + # optional bool suppress_errors + # optional bool suppress_console_outputs + # optional str v_arg_type +# ARGUMENT VALIDATION + my_f = 'val_int' + # suppress_errors + val_bool(suppress_errors, 'suppress_errors', my_f) + # suppress_console_outputs + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors)) + return False + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + my_f = method + '.' + my_f + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_min + if (v_min != None): + if not val_int(v_min, 'v_min', my_f, None, None, suppress_errors, suppress_console_outputs): + return False + # v_max + if (v_max != None): + if not val_int(v_max, 'v_max', my_f, None, None, suppress_errors, suppress_console_outputs): + return False + # v_input +# VARIABLE INSTANTIATION + mytype = "" # str(type(myinput)) + error_msg = error_msg_str(v_input, v_name, method, mytype, suppress_errors, suppress_console_outputs, v_arg_type) +# METHODS + if not mytype == str(type(v_input)): + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + if (v_min != None and v_max != None): + if (v_min > v_max): + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f"\nInverted minimum and maximum values {v_min} and {v_max}.") + return False + raise ValueError(error_msg + f"\nInverted minimum and maximum values {v_min} and {v_max}.") + if (v_min != None): + if (v_input < v_min): + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f"\nValue less than minimum {v_min}.") + return False + raise ValueError(error_msg + f"\nValue less than minimum {v_min}.") + if (v_max != None): + if (v_input > v_max): + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f"\nValue greater than maximum {v_max}.") + return False + raise ValueError(error_msg + f"\nValue greater than maximum {v_max}.") +# RETURNS + return True + + +def val_float(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # validate that v_input is of type float, and if not None, limited by v_min and v_max +# ARGUMENTS + # float (hopefully) v_input + # str v_name + # str method + # optional float v_min + # optional float v_max + # optional bool suppress_errors + # optional bool suppress_console_outputs + # optional str v_arg_type +# ARGUMENT VALIDATION + my_f = 'val_float' + # suppress_errors + val_bool(suppress_errors, 'suppress_errors', my_f) + # suppress_console_outputs + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors)) + return False + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + my_f = method + '.' + my_f + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_min + if (v_min != None): + if not val_float(v_min, 'v_min', my_f, None, None, suppress_errors, suppress_console_outputs): + return False + # v_max + if (v_max != None): + if not val_float(v_max, 'v_max', my_f, None, None, suppress_errors, suppress_console_outputs): + return False + # v_input +# VARIABLE INSTANTIATION + mytype = "" # str(type(myinput)) + error_msg = error_msg_str(v_input, v_name, method, mytype, suppress_errors, suppress_console_outputs, v_arg_type) +# METHODS + if not mytype == str(type(v_input)): + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + if (v_min != None and v_max != None): + if (v_min > v_max): + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f"\nInverted minimum and maximum values {v_min} and {v_max}.") + return False + raise ValueError(error_msg + f"\nInverted minimum and maximum values {v_min} and {v_max}.") + if (v_min != None): + if (v_input < v_min): + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f"\nValue less than minimum {v_min}.") + return False + raise ValueError(error_msg + f"\nValue less than minimum {v_min}.") + if (v_max != None): + if (v_input > v_max): + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f"\nValue greater than maximum {v_max}.") + return False + raise ValueError(error_msg + f"\nValue greater than maximum {v_max}.") +# RETURNS + return True + +def input_bool(v_input, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # input valid str, int, or bool representation of bool, or else None +# ARGUMENTS + # bool (hopefully) v_input + # str v_name + # str method + # optional str v_arg_type + # optional bool suppress_errors + # optional bool suppress_console_outputs +# ARGUMENT VALIDATION + my_f = 'input_bool' + # suppress_errors + val_bool(suppress_errors, 'suppress_errors', my_f) + # suppress_console_outputs + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors)) + return None + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None + my_f = method + '.' + my_f + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None +# METHODS + if not val_bool(v_input, v_name, my_f, True, suppress_console_outputs): + if not val_int(v_input, v_name, my_f, 0, 1, True, suppress_console_outputs): + # if str(type(v_input)) == "": + # return bool(v_input) + v_input = str(v_input) + error_msg = error_msg_str(v_input, v_name, method, "", suppress_errors, suppress_console_outputs, v_arg_type) + if not val_str(v_input, v_name, my_f, suppress_errors=True, suppress_console_outputs=suppress_console_outputs): + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return None + raise ValueError(error_msg) + else: + my_truths = ['1', 'Y', 'YE', 'YES', 'YS', 'YESH', 'YEA', 'YEAH', 'TRUE', 'TRU', 'TRUTH', 'TURE', 'T', "B'\X01'"] + my_falths = ['0', 'N', 'NO', 'FALSE', 'F', 'FAIL', 'FALS', "B'\X00'"] + v_input = v_input.upper() + for i in range(len(my_truths)): + if my_truths[i] == v_input: + return True + for i in range(len(my_falths)): + if my_falths[i] == v_input: + return False + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return None + raise ValueError(error_msg) + else: + return False if v_input == 0 else True +# RETURNS + return v_input + +def full_val_bool(v_input, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # validate that bool input is bool or valid equivalent +# ARGUMENTS + # bool (hopefully) my_input + # str v_name + # str method + # optional bool suppress_errors + # optional bool suppress_console_outputs + # optional str v_arg_type +# ARGUMENT VALIDATION + my_f = 'full_val_bool' + val_bool(suppress_errors, 'suppress_errors', my_f) + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors)) + return False + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + my_f = method + '.' + my_f + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False +# RETURNS + return not (str(type(input_bool(v_input, v_name, method, suppress_errors, suppress_console_outputs, v_arg_type))) == "") + + +def input_int(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # input int or valid equivalent, or else None +# ARGUMENTS + # int or str v_input + # str v_name + # str method + # v_min + # v_min + # bool suppress_errors + # bool suppress_console_outputs + # optional str v_arg_type +# ARGUMENT VALIDATION + my_f = 'input_int' + val_bool(suppress_errors, 'suppress_errors', my_f) + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors)) + return None + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None + my_f = method + '.' + my_f + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None + # v_min + if not str(type(v_min)) == "": + v_min = input_int(v_min, 'v_min', my_f, None, v_max, suppress_errors, suppress_console_outputs) + if str(type(v_min)) == "": return None + # v_max + if not str(type(v_max)) == "": + v_max = input_int(v_max, 'v_min', my_f, v_min, None, suppress_errors, suppress_console_outputs) + if str(type(v_max)) == "": return None +# METHODS + error_msg = error_msg_str(v_input, v_name, method, "", suppress_errors, suppress_console_outputs, v_arg_type) + # v_input + try: + my_int = int(v_input) + except: + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return None + int(v_input) + if not str(type(v_min)) == "": + if my_int < v_min: + if suppress_errors: + if not suppress_console_outputs: + print(f"{error_msg}\nInt input less than minimum value. Value = {v_input}, minimum = {v_min}.") + return None + if not str(type(v_max)) == "": + if my_int > v_max: + if suppress_errors: + if not suppress_console_outputs: + print(f"{error_msg}\nInt input greater than maximum value. Value = {v_input}, maximum = {v_max}.") + return None +# RETURNS + return my_int + + +def full_val_int(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # validate that v_input is int or equivalent, else False, limited by v_min and v_max +# ARGUMENTS + # int (hopefully) v_input + # str v_name + # str method + # optional float v_min + # optional float v_max + # optional bool suppress_errors + # optional bool suppress_console_outputs + # optional str v_arg_type +# ARGUMENT VALIDATION + my_f = 'full_val_int' + val_bool(suppress_errors, 'suppress_errors', my_f) + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors)) + return False + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_min + if not str(type(v_min)) == "": + v_min = input_int(v_min, 'v_min', method, None, v_max, suppress_errors, suppress_console_outputs) + if str(type(v_min)) == "": return False + # v_max + if not str(type(v_max)) == "": + v_max = input_int(v_max, 'v_min', method, v_min, None, suppress_errors, suppress_console_outputs) + if str(type(v_max)) == "": return False +# RETURNS + return not (str(type(input_int(v_input, v_name, method, v_min, v_max, suppress_errors, suppress_console_outputs))) == "") + + +def input_float(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # input float, else return None +# ARGUMENTS + # float/int/str(numeric) v_input + # str v_name + # str method + # optional float v_min + # optional float v_min + # optional bool suppress_errors + # optional bool suppress_console_outputs + # optional str v_arg_type +# ARGUMENT VALIDATION + my_f = 'input_float' + val_bool(suppress_errors, 'suppress_errors', my_f) + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors)) + return None + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None + my_f = method + '.' + my_f + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None + # v_min + if not str(type(v_min)) == "": + v_min = input_float(v_min, 'v_min', my_f, None, v_max, suppress_errors, suppress_console_outputs) + if str(type(v_min)) == "": return None + # v_max + if not str(type(v_max)) == "": + v_max = input_float(v_max, 'v_min', my_f, v_min, None, suppress_errors, suppress_console_outputs) + if str(type(v_max)) == "": return None +# METHODS + error_msg = error_msg_str(v_input, v_name, method, "", suppress_errors, suppress_console_outputs, v_arg_type) + # v_input + try: + my_float = float(v_input) + except: + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return None + float(v_input) + if not str(type(v_min)) == "": + if v_input < v_min: + if suppress_errors: + if not suppress_console_outputs: + print(f"{error_msg}\nInt input less than minimum value. Value = {v_input}, minimum = {v_min}.") + return None + if not str(type(v_max)) == "": + if v_input > v_max: + if suppress_errors: + if not suppress_console_outputs: + print(f"{error_msg}\nInt input greater than maximum value. Value = {v_input}, maximum = {v_max}.") + return None +# RETURNS + return my_float + + +def full_val_float(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # validate that v_input is numeric, and if not False, limited by v_min and v_max +# ARGUMENTS + # float (hopefully) v_input + # str v_name + # str method + # optional float v_min + # optional float v_max + # optional bool suppress_errors + # optional bool suppress_console_outputs +# ARGUMENT VALIDATION + my_f = 'full_val_float' + val_bool(suppress_errors, 'suppress_errors', my_f) + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors)) + return False + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + my_f = method + '.' + my_f + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_min + if not str(type(v_min)) == "": + v_min = input_float(v_min, 'v_min', method, None, v_max, suppress_errors, suppress_console_outputs) + if str(type(v_min)) == "": return False + # v_max + if not str(type(v_max)) == "": + v_max = input_float(v_max, 'v_min', method, v_min, None, suppress_errors, suppress_console_outputs) + if str(type(v_max)) == "": return False +# RETURNS + return not (str(type(input_float(v_input, v_name, method, v_min, v_max, suppress_errors, suppress_console_outputs))) == "") + + +def make_ordinal(n): +# FUNCTION + # Get ordinal representation of number +# ARGUMENTS + # int n +# ARGUMENT VALIDATION + full_val_int(n, 'n', 'make_ordinal', 0) +# VARIABLE INSTANTIATION + n = int(n) +# METHODS + if 11 <= (n % 100): + suffix= 'th' + else: + suffix = ['th', 'st', 'nd', 'rd', 'th'][min(n % 10, 4)] +# RETURNS + return str(n) + suffix + + +def val_type(v_input, v_name, method, v_type, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # validate that v_input is of type v_type +# ARGUMENTS + # v_type (hopefully) v_input + # str v_name + # str method + # str v_type + # optional bool suppress_errors + # optional bool suppress_console_outputs + # str v_arg_type +# ARGUMENT VALIDATION + my_f = 'val_type' + val_bool(suppress_errors, 'suppress_errors', my_f) + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors)) + return False + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + my_f = method + '.' + my_f + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_type + # error_message = error_msg_str(v_type, 'v_type', my_f, v_arg_type) + if not val_str(v_type, 'v_type', my_f, 6, -1, suppress_errors, suppress_console_outputs): return False + # v_input + error_message = error_msg_str(v_input, v_name, method, v_arg_type) + mytype = str(type(v_input)) + # if not (v_type == 'int' or v_type == 'bool' or v_type == 'float' or v_type == 'complex' or v_type == 'str' or v_type == 'NoneType'): + if not mytype == v_type: # f"": + if suppress_errors: + if not suppress_console_outputs: + print(error_message) + return False + raise ValueError(error_message) +# RETURNS + return True + + +def val_instance(v_input, v_name, method, v_type, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # validate that v_input is of type v_type +# ARGUMENTS + # v_type (hopefully) v_input + # str v_name + # str method + # type v_type + # optional bool suppress_errors + # optional bool suppress_console_outputs + # str v_arg_type +# ARGUMENT VALIDATION + my_f = 'val_type' + val_bool(suppress_errors, 'suppress_errors', my_f) + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors)) + return False + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + my_f = method + '.' + my_f + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_type + error_message = error_msg_str(v_type, 'v_type', my_f, v_arg_type) + if not isinstance(v_type, type): # mytype == v_type: # f"": + if suppress_errors: + if not suppress_console_outputs: + print(error_message) + return False + raise ValueError(error_message) # val_str(v_type, 'v_type', my_f, 6, -1, suppress_errors, suppress_console_outputs): return False + # v_input + error_message = error_msg_str(v_input, v_name, method, v_arg_type) + # mytype = str(type(v_input)) + # if not (v_type == 'int' or v_type == 'bool' or v_type == 'float' or v_type == 'complex' or v_type == 'str' or v_type == 'NoneType'): + if not isinstance(v_input, v_type): # mytype == v_type: # f"": + if suppress_errors: + if not suppress_console_outputs: + print(error_message) + return False + raise ValueError(error_message) +# RETURNS + return True + + +def val_list(v_input, v_name, method, v_type = '', min_len = -1, max_len = -1, suppress_errors = False, suppress_console_outputs: bool = False, allow_nuns = False, v_arg_type = 'argument'): +# FUNCTION + # validate that v_input is of type list, and if defined: has v_len elements of type v_type +# ARGUMENTS + # list[v_type] (hopefully) v_input + # str v_name - variable name + # str method - parent method + # str v_type - type of list items + # int min_len - minimum length of list + # int max_len - maximum length of list + # optional bool suppress_errors + # optional bool suppress_console_outputs + # optional bool allow_nuns + # optional str v_arg_type +# ARGUMENT VALIDATION + my_f = 'val_list' + val_bool(suppress_errors, 'suppress_errors', my_f) + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors)) + return False + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + my_f = method + '.' + my_f + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_type + # if not val_type(v_type, 'v_type', my_f, type, suppress_errors, suppress_console_outputs): return False + if not val_str(v_type, 'v_type', my_f, -1, -1, suppress_errors, suppress_console_outputs): return False + # min_len + if not full_val_int(min_len, 'min_len', my_f, None, None if max_len == -1 else max_len, suppress_errors, suppress_console_outputs): return False + # min_len = input_int(min_len, 'min_len', method, None, max_len, suppress_errors, suppress_console_outputs) + # if str(type(min_len)) == "": return False + # max_len + if not full_val_int(max_len, 'max_len', my_f, None if max_len == -1 else (None if min_len == -1 else min_len), None, suppress_errors, suppress_console_outputs): return False + # if not str(type(max_len)) == "": + # max_len = input_int(max_len, 'max_len', method, min_len, None, suppress_errors, suppress_console_outputs) + # if str(type(max_len)) == "": return False + # allow_nuns + if not val_bool(allow_nuns, 'allow_nuns', my_f, suppress_errors, suppress_console_outputs): return False + # v_input + # mytype = str(type(v_input)) + error_msg = error_msg_str(v_input, v_name, method, "") + if not str(type(v_input)) == "": + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + L = len(v_input) + if max_len > -1 and L > max_len: + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f'\nInvalid list length. Maximum = {max_len}, length = {L}') + return False + raise ValueError(error_msg + f'\nInvalid list length. Maximum = {max_len}, length = {L}') + if L < min_len: + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f"Invalid list length. Minimum = {min_len}, length = {L}") + return False + raise ValueError(error_msg + f'\nInvalid list length. Minimum = {min_len}, length = {L}') + if v_type != '' and L > 0: + for i in range(L): + # mytype = str(type(v_input[i])) + if not (val_type(v_input[i], f'{v_name}[{i}]', my_f, v_type, True) or allow_nuns and val_type(v_input[i], f'{v_name}[{i}]', my_f, "", True)): # mytype == v_type: + error_msg = error_msg + '\n' + error_msg_str(v_input[i], f'{v_name}[{i}]', my_f, v_type, False, False, 'list element') + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) +# RETURNS + return True + + +def val_list_instances(v_input, v_name, method, v_type = None, min_len = -1, max_len = -1, suppress_errors = False, suppress_console_outputs: bool = False, allow_nuns = False, v_arg_type = 'argument'): +# FUNCTION + # validate that v_input is of type list, and if defined: has v_len elements of type v_type +# ARGUMENTS + # list[v_type] (hopefully) v_input + # str v_name - variable name + # str method - parent method + # type v_type - type of list items + # int min_len - minimum length of list + # int max_len - maximum length of list + # optional bool suppress_errors + # optional bool suppress_console_outputs + # optional bool allow_nuns + # optional str v_arg_type +# ARGUMENT VALIDATION + my_f = 'val_list' + val_bool(suppress_errors, 'suppress_errors', my_f) + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "", suppress_errors)) + return False + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + my_f = method + '.' + my_f + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_type + if not val_type(v_type, 'v_type', my_f, type, suppress_errors, suppress_console_outputs): return False + # if not val_str(v_type, 'v_type', my_f, 6, -1, suppress_errors, suppress_console_outputs): return False + # min_len + if not full_val_int(min_len, 'min_len', my_f, None, None if max_len == -1 else max_len, suppress_errors, suppress_console_outputs): return False + # min_len = input_int(min_len, 'min_len', method, None, max_len, suppress_errors, suppress_console_outputs) + # if str(type(min_len)) == "": return False + # max_len + if not full_val_int(max_len, 'max_len', my_f, None if max_len == -1 else (None if min_len == -1 else min_len), None, suppress_errors, suppress_console_outputs): return False + # if not str(type(max_len)) == "": + # max_len = input_int(max_len, 'max_len', method, min_len, None, suppress_errors, suppress_console_outputs) + # if str(type(max_len)) == "": return False + # allow_nuns + if not val_bool(allow_nuns, 'allow_nuns', my_f, suppress_errors, suppress_console_outputs): return False + # v_input + # mytype = str(type(v_input)) + error_msg = error_msg_str(v_input, v_name, method, "") + if not str(type(v_input)) == "": + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + L = len(v_input) + if max_len > -1 and L > max_len: + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f'\nInvalid list length. Maximum = {max_len}, length = {L}') + return False + raise ValueError(error_msg + f'\nInvalid list length. Maximum = {max_len}, length = {L}') + if L < min_len: + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f"Invalid list length. Minimum = {min_len}, length = {L}") + return False + raise ValueError(error_msg + f'\nInvalid list length. Minimum = {min_len}, length = {L}') + if v_type != '' and L > 0: + for i in range(L): + # mytype = str(type(v_input[i])) + if not (val_instance(v_input[i], f'{v_name}[{i}]', my_f, v_type, True) or allow_nuns and val_instance(v_input[i], f'{v_name}[{i}]', my_f, type(None), True)): # mytype == v_type: + error_msg = error_msg + '\n' + error_msg_str(v_input[i], f'{v_name}[{i}]', my_f, v_type, False, False, 'list element') + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) +# RETURNS + return True + + +def val_nested_list(v_input, v_name, method, depth_i, depth_max, v_type = '', v_min = -1, v_mins = [], v_max = -1, v_maxs = [], suppress_errors = False, suppress_console_outputs = False, allow_nuns = False, v_arg_type = 'argument'): +# FUNCTION + # validate that v_input is of type list, and if defined: has v_len elements of type v_type + # for nested list of nested-index i +# ARGUMENTS + # list[v_type] (hopefully) v_input + # str v_name + # str method + # int depth_i - current depth of nesting of lists + # int depth_max - maximum depth of nesting of lists - base 0 + # Optional[str] v_type - type of list items + # Optional[int] v_min - minimum sublist size + # Optional[list[int]] v_mins - minimum list sizes + # Optional[int] v_max - maximum sublist size + # Optional[list[int]] v_maxs - maximum list sizes + # optional bool suppress_errors + # optional bool suppress_console_outputs + # optional bool allow_nuns + # optional str v_arg_type +# ARGUMENT VALIDATION + my_f = 'val_nested_list' + val_bool(suppress_errors, 'suppress_errors', my_f) + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "")) + return False + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + my_f = method + '.' + my_f + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_type + if not val_str(v_type, 'v_type', my_f, -1, -1, suppress_errors, suppress_console_outputs): return False + # if not val_type(v_type, 'v_type', my_f, type, suppress_errors, suppress_console_outputs): return False + # v_min + if not val_int(v_min, 'v_min', my_f, -1, None, suppress_errors, suppress_console_outputs): return False + # v_max + if not val_int(v_max, 'v_max', my_f, -1, None, suppress_errors, suppress_console_outputs): return False + # v_mins + if not (val_list(v_mins, 'v_mins', my_f, "", depth_max + 1, depth_max + 1, True, True) or v_mins == []): + error_msg = error_msg_str(v_mins, 'v_mins', my_f, "") + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + # v_maxs + if not (val_list(v_maxs, 'v_maxs', my_f, "", depth_max + 1, depth_max + 1, True, True) or v_maxs == []): + error_msg = error_msg_str(v_maxs, 'v_maxs', my_f, "") + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + # allow_nuns + if not val_bool(allow_nuns, 'allow_nuns', my_f, suppress_errors, suppress_console_outputs): return False + # v_input + mytype = v_type if depth_i == depth_max else "" + error_msg = error_msg_str(v_input, v_name, method, mytype, suppress_errors, suppress_console_outputs, v_arg_type) + if not val_list(v_input, v_name, method, mytype, v_min, v_max, suppress_errors, suppress_console_outputs, allow_nuns, v_arg_type): + if not suppress_console_outputs: + print(error_msg) + return False +# METHODS + L = len(v_input) + if L == 0: + if v_min > -1: + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f'\nMinimum length {v_min} not met.') + return False + raise ValueError(error_msg + f'\nMinimum length {v_min} not met.') + elif depth_i < depth_max: + for i in range(L): + if not (v_mins == [] or v_maxs == []): + if not val_nested_list(v_input[i], v_name, method, depth_i + 1, depth_max, v_type, v_mins[depth_i + 1], v_mins, v_maxs[depth_i + 1], v_maxs, suppress_errors, suppress_console_outputs, v_arg_type): + if not suppress_console_outputs: + print(error_msg) + return False + elif not v_mins == []: + if not val_nested_list(v_input[i], v_name, method, depth_i + 1, depth_max, v_type, v_mins[depth_i + 1], v_mins, -1, v_maxs, suppress_errors, suppress_console_outputs, v_arg_type): + if not suppress_console_outputs: + print(error_msg) + return False + elif not v_maxs == []: + if not val_nested_list(v_input[i], v_name, method, depth_i + 1, depth_max, v_type, -1, v_mins, v_maxs[depth_i + 1], v_maxs, suppress_errors, suppress_console_outputs, v_arg_type): + if not suppress_console_outputs: + print(error_msg) + return False + else: + if not val_nested_list(v_input[i], v_name, method, depth_i + 1, depth_max, v_type, -1, v_mins, -1, v_maxs, suppress_errors, suppress_console_outputs, v_arg_type): + if not suppress_console_outputs: + print(error_msg) + return False +# RETURNS + return True + + +def val_nested_list_instances(v_input, v_name, method, depth_i, depth_max, v_type = '', v_min = -1, v_mins = [], v_max = -1, v_maxs = [], suppress_errors = False, suppress_console_outputs = False, allow_nuns = False, v_arg_type = 'argument'): +# FUNCTION + # validate that v_input is of type list, and if defined: has v_len elements of type v_type + # for nested list of nested-index i +# ARGUMENTS + # list[v_type] (hopefully) v_input + # str v_name + # str method + # int depth_i - current depth of nesting of lists + # int depth_max - maximum depth of nesting of lists - base 0 + # Optional[str] v_type - type of list items + # Optional[int] v_min - minimum sublist size + # Optional[list[int]] v_mins - minimum list sizes + # Optional[int] v_max - maximum sublist size + # Optional[list[int]] v_maxs - maximum list sizes + # optional bool suppress_errors + # optional bool suppress_console_outputs + # optional bool allow_nuns + # optional str v_arg_type +# ARGUMENT VALIDATION + my_f = 'val_nested_list' + val_bool(suppress_errors, 'suppress_errors', my_f) + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "")) + return False + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + my_f = method + '.' + my_f + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_type + # if not val_str(v_type, 'v_type', my_f, -1, -1, suppress_errors, suppress_console_outputs): return False + if not val_type(v_type, 'v_type', my_f, type, suppress_errors, suppress_console_outputs): return False + # v_min + if not val_int(v_min, 'v_min', my_f, -1, None, suppress_errors, suppress_console_outputs): return False + # v_max + if not val_int(v_max, 'v_max', my_f, -1, None, suppress_errors, suppress_console_outputs): return False + # v_mins + if not (val_list(v_mins, 'v_mins', my_f, "", depth_max + 1, depth_max + 1, True, True) or v_mins == []): + error_msg = error_msg_str(v_mins, 'v_mins', my_f, "") + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + # v_maxs + if not (val_list(v_maxs, 'v_maxs', my_f, "", depth_max + 1, depth_max + 1, True, True) or v_maxs == []): + error_msg = error_msg_str(v_maxs, 'v_maxs', my_f, "") + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + # allow_nuns + if not val_bool(allow_nuns, 'allow_nuns', my_f, suppress_errors, suppress_console_outputs): return False + # v_input + mytype = v_type if depth_i == depth_max else list # "" + error_msg = error_msg_str(v_input, v_name, method, mytype, suppress_errors, suppress_console_outputs, v_arg_type) + if not val_list_instances(v_input, v_name, method, mytype, v_min, v_max, suppress_errors, suppress_console_outputs, allow_nuns, v_arg_type): + if not suppress_console_outputs: + print(error_msg) + return False +# METHODS + L = len(v_input) + if L == 0: + if v_min > -1: + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f'\nMinimum length {v_min} not met.') + return False + raise ValueError(error_msg + f'\nMinimum length {v_min} not met.') + elif depth_i < depth_max: + for i in range(L): + if not (v_mins == [] or v_maxs == []): + if not val_nested_list(v_input[i], v_name, method, depth_i + 1, depth_max, v_type, v_mins[depth_i + 1], v_mins, v_maxs[depth_i + 1], v_maxs, suppress_errors, suppress_console_outputs, allow_nuns, v_arg_type): + if not suppress_console_outputs: + print(error_msg) + return False + elif not v_mins == []: + if not val_nested_list(v_input[i], v_name, method, depth_i + 1, depth_max, v_type, v_mins[depth_i + 1], v_mins, -1, v_maxs, suppress_errors, suppress_console_outputs, allow_nuns, v_arg_type): + if not suppress_console_outputs: + print(error_msg) + return False + elif not v_maxs == []: + if not val_nested_list(v_input[i], v_name, method, depth_i + 1, depth_max, v_type, -1, v_mins, v_maxs[depth_i + 1], v_maxs, suppress_errors, suppress_console_outputs, allow_nuns, v_arg_type): + if not suppress_console_outputs: + print(error_msg) + return False + else: + if not val_nested_list(v_input[i], v_name, method, depth_i + 1, depth_max, v_type, -1, v_mins, -1, v_maxs, suppress_errors, suppress_console_outputs, allow_nuns, v_arg_type): + if not suppress_console_outputs: + print(error_msg) + return False +# RETURNS + return True + + +def val_url(v_input, v_name, method, min_len = 12, max_len = -1, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# FUNCTION + # validate that v_input is of type str +# ARGUMENTS + # str (hopefully) v_input + # str v_name + # str method + # optional int min_len + # optional int max_len + # optional bool suppress_errors + # optional bool suppress_console_outputs + # optional str v_arg_type +# ARGUMENT VALIDATION + _m = 'val_url' + v_type = "" + val_bool(suppress_errors, 'suppress_errors', _m) + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', _m, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', _m, "")) + return False + # method + if not val_str(method, 'method', _m, -1, -1, suppress_errors, suppress_console_outputs): return False + _m = method + '.' + _m + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', _m, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_name + if not val_str(v_name, 'v_name', _m, -1, -1, suppress_errors, suppress_console_outputs): return False + # min_len + if not val_int(min_len, 'min_len', _m, 10, None, suppress_errors, suppress_console_outputs): return False + # max_len + if not val_int(max_len, 'max_len', _m, -1, None, suppress_errors, suppress_console_outputs): return False + # v_input + if not val_str(v_input, v_name, method, min_len, -1, suppress_errors, suppress_console_outputs): return False +# METHODS + error_msg = error_msg_str(v_input, 'v_input', _m, "") + if not (v_input[:8] == r'https://' or v_input[:7] == r'http://'): + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) +# RETURNS + return True + +# def val_nparray(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'): +# # FUNCTION +# # validate v_input is numpy ndarray +# # ARGUMENTS +# # numpy.ndarray v_input +# # str v_name +# # str method +# # +# # ARGUMENT VALIDATION +# # METHODS +# # RETURNS + + +def val_DataFrame(v_input, v_name, method, v_types=[], min_col=-1, max_col=-1, cols=[], min_sz=-1, max_sz=-1, suppress_errors=False, suppress_console_outputs=False, v_arg_type='argument'): +# FUNCTION + # validate that v_input is of type list, and if defined: has v_len elements of type v_type + # for nested list of nested-index i +# ARGUMENTS + # pandas.DataFrame (hopefully) v_input + # str v_name + # str method + # optional list[str] v_type - column datatypes + # optional int min_col - minimum number of columns + # optional int max_col - maximum number of columns + # optional list[str] cols - column names + # optional int min_sz - minimum length of columns + # optional int max_sz - maximum length of columns + # optional bool suppress_errors + # optional bool suppress_console_outputs + # optional str v_arg_type +# ARGUMENT VALIDATION + my_f = 'val_DataFrame' + val_bool(suppress_errors, 'suppress_errors', my_f) + if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors): + print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "")) + return False + # method + if not val_str(method, 'method', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + my_f = method + '.' + my_f + # v_name + if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # v_arg_type + if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False + # min_col + if not val_int(min_col, 'min_col', my_f, -1, None, suppress_errors, suppress_console_outputs): return False + # max_col + if not val_int(max_col, 'max_col', my_f, -1, None, suppress_errors, suppress_console_outputs): return False + # min_sz + if not val_int(min_sz, 'min_sz', my_f, -1, None, suppress_errors, suppress_console_outputs): return False + # max_sz + if not val_int(max_sz, 'max_sz', my_f, -1, None, suppress_errors, suppress_console_outputs): return False + # v_types + if not (val_list(v_types, 'v_types', my_f, "", min_col, max_col, True, True, True) or v_types == []): + error_msg = error_msg_str(v_types, 'v_types', my_f, str) + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + # cols + if not (val_list(cols, 'cols', my_f, "", min_col, max_col, True, True) or cols == []): + error_msg = error_msg_str(cols, 'cols', my_f, "") + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + # v_input + if not val_type(v_input, v_name, my_f, "", suppress_errors, suppress_console_outputs, v_arg_type): return False +# METHODS + error_msg = error_msg_str(v_input, v_name, my_f, "", v_arg_type=v_arg_type) + n_c = len(v_input.columns) + if (min_col > 0 and n_c < min_col) or (max_col > 0 and n_c > max_col): + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + my_sz = len(v_input.index) + if (min_sz > 0 and my_sz < min_sz) or (max_sz > 0 and my_sz > max_sz): + if suppress_errors: + if not suppress_console_outputs: + print(error_msg) + return False + raise ValueError(error_msg) + if not v_types == []: + for col_i in range(n_c): + if not (v_types[col_i] == None or str(type(v_types[col_i])) == "" and val_type(v_input.at[0, v_input.columns[col_i]], 'v_input.at[0, v_input.columns[col_i]]', my_f, v_types[col_i], True, False) or val_instance(v_input.at[0, v_input.columns[col_i]], 'v_input.at[0, v_input.columns[col_i]]', my_f, v_types[col_i], True, False)): # str(type(v_input[v_input.columns[col_i]][0])) == v_types[col_i] or v_types[col_i] == '': + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f'\nInvalid data type {str(type(v_input.at[0, v_input.columns[col_i]]))} in column {v_input.columns[col_i]}') + return False + raise ValueError(error_msg + f'\nInvalid data type {str(type(v_input.at[0, v_input.columns[col_i]]))} in column {v_input.columns[col_i]}') + if not cols == []: + for col_i in range(n_c): + if not v_input.columns[col_i] == cols[col_i] or cols[col_i] == '': + if suppress_errors: + if not suppress_console_outputs: + print(error_msg + f'\nInvalid column heading for column {v_input.columns[col_i]}') + return False + raise ValueError(error_msg + f'\nInvalid column heading for column {v_input.columns[col_i]}') +# RETURNS + return True + + + + diff --git a/lib/data_types.py b/lib/data_types.py new file mode 100644 index 00000000..53ddd590 --- /dev/null +++ b/lib/data_types.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Apr 27 12:33:59 2023 + +@author: Edward Middleton-Smith + +Argument Validation +""" + +# CLASSES +# ATTRIBUTE DECLARATION +# METHODS + # FUNCTION + # ARGUMENTS + # ARGUMENT VALIDATION + # ATTRIBUTE + VARIABLE INSTANTIATION + # METHODS + # RETURNS + +# NORMAL METHODS +# FUNCTION +# ARGUMENTS +# ARGUMENT VALIDATION +# VARIABLE INSTANTIATION +# METHODS +# RETURNS + +# IMPORTS + +# CLASSES + +# METHODS +def get_enum_member_by_text(enum_class, text): + for member in enum_class.__members__.values(): + if member.name == text: + return member + raise ValueError(f'{text} is not in {enum_class}') \ No newline at end of file diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 00000000..615f401b --- /dev/null +++ b/models/__init__.py @@ -0,0 +1,11 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Module Initialisation +Feature: Models + +Description: +Initialises view data models module. +""" diff --git a/models/__pycache__/__init__.cpython-311.pyc b/models/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 00000000..53ba36d8 Binary files /dev/null and b/models/__pycache__/__init__.cpython-311.pyc differ diff --git a/models/__pycache__/model_view_base.cpython-311.pyc b/models/__pycache__/model_view_base.cpython-311.pyc new file mode 100644 index 00000000..1e0d7cf7 Binary files /dev/null and b/models/__pycache__/model_view_base.cpython-311.pyc differ diff --git a/models/__pycache__/model_view_contact.cpython-311.pyc b/models/__pycache__/model_view_contact.cpython-311.pyc new file mode 100644 index 00000000..20fb1aef Binary files /dev/null and b/models/__pycache__/model_view_contact.cpython-311.pyc differ diff --git a/models/__pycache__/model_view_home.cpython-311.pyc b/models/__pycache__/model_view_home.cpython-311.pyc new file mode 100644 index 00000000..109a1054 Binary files /dev/null and b/models/__pycache__/model_view_home.cpython-311.pyc differ diff --git a/models/__pycache__/model_view_store.cpython-311.pyc b/models/__pycache__/model_view_store.cpython-311.pyc new file mode 100644 index 00000000..b1396928 Binary files /dev/null and b/models/__pycache__/model_view_store.cpython-311.pyc differ diff --git a/models/__pycache__/model_view_store_basket.cpython-311.pyc b/models/__pycache__/model_view_store_basket.cpython-311.pyc new file mode 100644 index 00000000..86c02f96 Binary files /dev/null and b/models/__pycache__/model_view_store_basket.cpython-311.pyc differ diff --git a/models/__pycache__/model_view_store_checkout.cpython-311.pyc b/models/__pycache__/model_view_store_checkout.cpython-311.pyc new file mode 100644 index 00000000..e3273334 Binary files /dev/null and b/models/__pycache__/model_view_store_checkout.cpython-311.pyc differ diff --git a/models/__pycache__/model_view_store_checkout_success.cpython-311.pyc b/models/__pycache__/model_view_store_checkout_success.cpython-311.pyc new file mode 100644 index 00000000..fff1c74e Binary files /dev/null and b/models/__pycache__/model_view_store_checkout_success.cpython-311.pyc differ diff --git a/models/__pycache__/model_view_store_home.cpython-311.pyc b/models/__pycache__/model_view_store_home.cpython-311.pyc new file mode 100644 index 00000000..c2638ec9 Binary files /dev/null and b/models/__pycache__/model_view_store_home.cpython-311.pyc differ diff --git a/models/__pycache__/model_view_store_product.cpython-311.pyc b/models/__pycache__/model_view_store_product.cpython-311.pyc new file mode 100644 index 00000000..3b140ea4 Binary files /dev/null and b/models/__pycache__/model_view_store_product.cpython-311.pyc differ diff --git a/models/model_view_base.py b/models/model_view_base.py new file mode 100644 index 00000000..0c0a5c81 --- /dev/null +++ b/models/model_view_base.py @@ -0,0 +1,104 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: View Models +Feature: Base View Model + +Description: +Base data model for views +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# METHODS + +# IMPORTS +# internal +# from routes import bp_home +import lib.argument_validation as av +from forms import Form_Is_Included_VAT, Form_Delivery_Region, Form_Currency +# external +from abc import ABC, abstractmethod, abstractproperty +from flask_sqlalchemy import SQLAlchemy +from flask import Flask + +# VARIABLE INSTANTIATION + + +# CLASSES +class Model_View_Base(ABC): + # Attributes + is_user_logged_in: bool + id_user: str + form_is_included_VAT: Form_Is_Included_VAT + form_delivery_region: Form_Delivery_Region + form_currency: Form_Currency + # app: Flask + is_page_store: bool + # Global constants + FLAG_BUTTON_MODAL_CLOSE = 'btn-overlay-close' + FLAG_BUTTON_SUBMIT = 'btn-submit' + FLAG_CARD = 'card' + FLAG_COLLAPSIBLE = 'collapsible' + FLAG_COLUMN = 'column' + FLAG_CONTAINER = 'container' + FLAG_CONTAINER_INPUT = FLAG_CONTAINER + '-input' + FLAG_INITIALISED = 'initialised' + FLAG_ROW = 'column' + FLAG_SCROLLABLE = 'scrollable' + FLAG_SUBMITTED = 'submitted' + # flagIsDatePicker = 'is-date-picker' + HASH_PAGE_CONTACT = '/contact' + HASH_PAGE_ERROR_NO_PERMISSION = '/error' + HASH_PAGE_HOME = '/' + HASH_PAGE_STORE_HOME = '/store' + HASH_PAGE_STORE_PRODUCT = '/store/product' + ID_FORM_CURRENCY = 'formCurrency' + ID_FORM_DELIVERY_REGION = 'formDeliveryRegion' + ID_FORM_IS_INCLUDED_VAT = 'formIsIncludedVAT' + ID_MODAL_SERVICES = 'modalServices' + ID_MODAL_TECHNOLOGIES = 'modalTechnologies' + ID_NAV_CONTACT = 'navContact' + ID_NAV_HOME = 'navHome' + ID_NAV_STORE_HOME = 'navStoreHome' + ID_NAV_STORE_PRODUCT = 'navStoreProduct' + ID_PAGE_BODY = 'pageBody' + URL_HOST = 'http://127.0.0.1:5000' + URL_GITHUB = 'https://github.com/Teddy-1024' + URL_LINKEDIN = 'https://uk.linkedin.com/in/lordteddyms' + + @abstractproperty + def title(self): + pass + + def __new__(cls, db, info_user, app): # , *args, **kwargs + # Initialiser - validation + _m = 'Model_View_Base.__new__' + v_arg_type = 'class attribute' + print(f'{_m}\nstarting') + # return super().__new__(cls, *args, **kwargs) + av.val_instance(db, 'db', _m, SQLAlchemy, v_arg_type=v_arg_type) + return super(Model_View_Base, cls).__new__(cls) + + def __init__(self, db, info_user, app): + # Constructor + _m = 'Model_View_Base.__init__' + v_arg_type = 'class attribute' + print(f'{_m}\nstarting') + av.val_instance(db, 'db', _m, SQLAlchemy, v_arg_type=v_arg_type) + self.db = db + self.info_user = info_user + print(f'info_user: {info_user}\ntype: {str(type(info_user))}') + self.is_user_logged_in = ('sub' in list(info_user.keys()) and not info_user['sub'] == '' and not str(type(info_user['sub'])) == " 0 else None + self.form_delivery_region = Form_Delivery_Region() + self.form_delivery_region.id_region_delivery.choices = [(region.id_region, f'{region.code} - {region.name}') for region in regions] + self.form_delivery_region.id_region_delivery.data = str(self.id_region_delivery) if len(regions) > 0 else None + + def get_many_product_category(self, product_filters): # category_ids = '', product_ids = '', get_all_category = True, get_all_product = True, max_products_per_category = -1): + _m = 'Model_View_Store.get_many_product_category' + av.val_instance(product_filters, 'product_filters', _m, Product_Filters) + """ + av.val_str(category_ids, 'category_ids', _m) + av.val_str(product_ids, 'product_ids', _m) + av.val_bool(get_all_category, 'get_all_category', _m) + av.val_bool(get_all_product, 'get_all_product', _m) + av.val_int(max_products_per_category, 'max_products_per_category', _m) + """ + # get products from database + # call datastore method + # return [Product.template()] + self.category_list, errors = DataStore_Store(self.db, self.info_user, self.app).get_many_product_category(product_filters) # category_ids, product_ids, get_all_category, get_all_product, max_products_per_category) + # self.categories = categories + # self.category_index = category_index + + return + if get_all_category or get_all_product: + prod = Product.template() + prod_list = [ prod, prod ] + return { 'MISCELLANEOUS': prod_list if max_products_per_category < 0 else prod_list[:max_products_per_category] } + if product_ids == 'panties123': + prod = Product.template() + return { 'MISCELLANEOUS': [ prod] } + + # def product_category_getMany(self, category_ids = '', product_ids = '', get_all_category = True, get_all_product = True): + # return Model_View_Store.product_category_getMany(category_ids, product_ids, get_all_category, get_all_product) + + def get_many_product_image_src(self, product_id, image_ids = '', get_primary_only = True, resolution_level = ''): + _m = 'Model_View_Store.get_many_product_image' + # print(f'{_m}\n') + # av.val_instance(filters, 'filters', _m, Product_Image_Filters) + av.val_int(product_id, 'product_id', _m) + # av.full_val_int(product_id, 'product_id', _m) + # product_id = int(product_id) + av.val_str(image_ids, 'image_ids', _m) + av.full_val_bool(get_primary_only, 'get_primary_only', _m) + get_primary_only = bool(get_primary_only) + resolution_level = Resolution_Level_Enum.get_member_by_text(resolution_level) + av.val_instance(resolution_level, 'resolution_level', _m, Resolution_Level_Enum) + # if (filters.product_id < 0 or filters.product_id not in self.valid_product_id_list): + if (product_id not in Model_View_Store.valid_product_id_list): # product_id < 0 or + return '' + path_suffix = 'jpg' # get_suffix_from_product_id(product_id) + path_file = f'/static/images/{product_id}.{path_suffix}' + return path_file + # return send_file(path_file, mimetype=f'image/{path_suffix}') + + """ + def get_product_category_text(self, category): + return Enum_Product_Category.get_member_by_text(category).text() + + def add_2_basket(product_id, quantity, basket_local): + _m = 'Model_View_Store.add_2_basket' + av.full_val_int(product_id, 'product_id', _m) + product_id = str(product_id) + av.full_val_int(quantity, 'quantity', _m) + quantity = int(quantity) + av.val_instance(basket_local, 'basket_local', _m, dict) + # send to database + + # update basket on webpage with new database status + if product_id in basket_local: + basket_local[product_id] += quantity + else: + basket_local[product_id] = quantity + return basket_local // jsonify(basket_local) + """ + + + def basket_item_edit(self, permutation_id, quantity, quantity_sum_not_replace): + _m = 'Model_View_Store.basket_item_edit' + # av.full_val_int(product_id, 'product_id', _m) + # product_id = int(product_id) + # av.val_instance(db, 'db', _m, SQLAlchemy) + print(f'{_m} starting') + # print(f'product_id: {product_id}\npermutation_id: {permutation_id}\nquantity = {quantity}') + # av.full_val_int(product_id, 'product_id', _m) + # print('valid product id') + av.full_val_int(quantity, 'quantity', _m) + quantity = int(quantity) + # item_added = False + print(f'basket: {self.basket}') + ids_permutation, quantities_permutation = self.basket.to_csv() + self.basket = DataStore_Store(self.db, self.info_user, self.app).edit_basket(ids_permutation, quantities_permutation, permutation_id, quantity, quantity_sum_not_replace, self.app.id_currency, self.app.id_region_delivery) + return True + + def get_basket(self, json_data): + self.import_JSON_basket(json_data) + if self.is_user_logged_in: + ids_permutation, quantities_permutation = self.basket.to_csv() + self.basket = DataStore_Store(self.db, self.info_user, self.app).edit_basket(ids_permutation, quantities_permutation, None, None, None, self.app.id_currency, self.app.id_region_delivery) + # return self.basket + + def _get_json_basket_id_CSVs_product_permutation(self, basket): + product_ids = '' + permutation_ids = '' + item_index_dict = {} + if len(basket) > 0: + for index_item in range(len(basket)): + if index_item > 0: + product_ids += ',' + permutation_ids += ',' + basket_item = basket[index_item] + id_product = basket_item[self.key_id_product] + id_permutation = basket_item[self.key_id_permutation] + id_permutation = '' if (id_permutation is None or id_permutation == 'None') else str(id_permutation) + product_ids += str(id_product) # str(basket[b].product.id) + permutation_ids += id_permutation # str(basket[b].product.id) + # item_index_dict[Basket.get_key_product_index_from_ids_product_permutation(id_product, id_permutation)] = index_item + item_index_dict[id_permutation] = index_item + print(f'product_ids = {product_ids}') + print(f'permutation_ids = {permutation_ids}') + return product_ids, permutation_ids, item_index_dict + + def _get_basket_from_json(self, json_data): + basket = json_data[self.key_basket]['items'] + av.val_instance(basket, 'basket', 'Model_View_Store._get_basket_from_json', list) + print(f'basket = {basket}') + return basket + + def import_JSON_basket(self, json_data): + _m = 'Model_View_Store.import_JSON_basket' + # av.val_instance(db, 'db', _m, SQLAlchemy) + items = self._get_basket_from_json(json_data) + print(f'json basket items: {items}') + product_ids, permutation_ids, item_index_dict = self._get_json_basket_id_CSVs_product_permutation(items) + category_list, errors = DataStore_Store(self.db, self.info_user, self.app).get_many_product_category(Product_Filters( + self.id_user, # :a_id_user + True, '', False, # :a_get_all_category, :a_ids_category, :a_get_inactive_category + False, product_ids, False, False, # :a_get_all_product, :a_ids_product, :a_get_inactive_product, :a_get_first_product_only + False, permutation_ids, False, # :a_get_all_permutation, :a_ids_permutation, :a_get_inactive_permutation + False, '', False, True, # :a_get_all_image, :a_ids_image, :a_get_inactive_image, :a_get_first_image_only + False, str(self.app.id_region_delivery), False, # :a_get_all_delivery_region, :a_ids_delivery_region, :a_get_inactive_delivery_region + False, str(self.app.id_currency), False, # :a_get_all_currency, :a_ids_currency, :a_get_inactive_currency + True, '', False # :a_get_all_discount, :a_ids_discount, :a_get_inactive_discount + )) # product_ids=product_ids, get_all_category=False, get_all_product=False) + # print(f'categories = {categories}') + self.basket = Basket() + if len(category_list.categories) > 0: # not (categories is None): + for category in category_list.categories: + for product in category.products: + # product = Product.make_from_json(items[index_item]) + product.form_basket_edit = Form_Basket_Edit() + # key_index_product = Basket.get_key_product_index_from_ids_product_permutation(product.id_product, product.get_id_permutation()) + permutation = product.get_permutation_selected() + self.basket.add_item(Basket_Item.make_from_product_and_quantity_and_VAT_included(product, items[item_index_dict[str(permutation.id_permutation)]][self.key_quantity], self.app.is_included_VAT)) + """ + if len(items) > 0: + for index_item in range(len(items)): + """ + print(f'basket data: {json_data}') + print(f'basket: {self.basket}') + + # ids_permutation_unavailable_region_or_currency = [] + # id_permutation_unavailable_otherwise = [] + if len(errors) > 0: + for error in errors: + if error[1] == 'PRODUCT_AVAILABILITY': + ids_permutation = DataStore_Store.get_ids_permutation_from_error_availability(error[2]) + for id_permutation in ids_permutation: + for item in self.basket.items: + permutation = item.product.get_permutation_selected() + if id_permutation == permutation.id_permutation: + item.is_available = False + if 'region' in error[2] or 'currency' in error[2]: + item.is_unavailable_in_currency_or_region = True + # ids_permutation_unavailable_region_or_currency.append(id_permutation) + # else: + # for id_permutation in ids_permutation: + # id_permutation_unavailable_otherwise.append(id_permutation) + """ + ids_permutation_unavailable = self.basket.get_ids_permutation_unavailable() + if len(ids_permutation_unavailable) > 0: + category_list_unavailable, errors_unavailable = DataStore_Store(self.db, self.info_user, self.app).get_many_product_category(Product_Filters( + self.id_user, # :a_id_user + True, '', False, # :a_get_all_category, :a_ids_category, :a_get_inactive_category + False, '', False, False, # :a_get_all_product, :a_ids_product, :a_get_inactive_product, :a_get_first_product_only + False, ','.join(ids_permutation_unavailable), False, # :a_get_all_permutation, :a_ids_permutation, :a_get_inactive_permutation + False, '', False, True, # :a_get_all_image, :a_ids_image, :a_get_inactive_image, :a_get_first_image_only + True, '', False, # :a_get_all_delivery_region, :a_ids_delivery_region, :a_get_inactive_delivery_region + True, '', False, # :a_get_all_currency, :a_ids_currency, :a_get_inactive_currency + True, '', False # :a_get_all_discount, :a_ids_discount, :a_get_inactive_discount + )) # product_ids=product_ids, get_all_category=False, get_all_product=False) + else: + category_list_unavailable = None + errors_unavailable = [] + """ + + + def import_JSON_basket_item(self, json_data, form_basket = None): + _m = 'Model_View_Store.import_JSON_basket_item' + print(f'starting {_m}') + # print('getting product id') + # product_id = av.input_int(json_data[self.key_id_product], self.key_id_product, _m) + + # print(f'product id: {product_id}, type: {str(type(product_id))}') + try: + permutation_id = json_data[self.key_id_permutation] + av.full_val_int(permutation_id, self.key_id_permutation, _m) + permutation_id = int(permutation_id) + except: + permutation_id = None + if not permutation_id == 'None': + print(f'permutation_id invalid: {permutation_id}') + raise ValueError("Invalid permutation id") + print(f'permutation_id: {permutation_id}') + + try: + print(f'form_basket: {form_basket}') + print('getting quantity') + print(f'form_basket.quantity: {form_basket.quantity}') + print(f'form_basket.quantity.data: {form_basket.quantity.data}') + quantity = int(form_basket.quantity.data) + except: + quantity = 0 + print(f'quantity: {quantity}') + + print(f'permutation_id: {permutation_id}\nquantity: {quantity}') + + return permutation_id, quantity + + def output_basket_total(self): + return self.basket.output_total() + + + def init_forms_basket_add(self): + for cat in self.categories: + c = self.category_index + + def get_many_user_order(self, ids_order, n_order_max, id_checkout_session): + # _m = 'Model_View_Store.get_many_user_order' + # av.val_str(id_user) + # validation conducted by server + return DataStore_Store(self.db, self.info_user, self.app).get_many_user_order(self.info_user['sub'], ids_order, n_order_max, id_checkout_session) + + def get_regions_and_currencies(self): + regions, currencies = DataStore_Store(self.db, self.info_user, self.app).get_regions_and_currencies() + return regions, currencies \ No newline at end of file diff --git a/models/model_view_store_basket.py b/models/model_view_store_basket.py new file mode 100644 index 00000000..cd4819ef --- /dev/null +++ b/models/model_view_store_basket.py @@ -0,0 +1,93 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: View Models +Feature: Store Basket View Model + +Description: +Data model for store basket view +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# METHODS + +# IMPORTS +# internal +from models.model_view_store import Model_View_Store +# from routes import bp_home +from business_objects.product import Product +from forms import Form_Billing # Form_Product +# external + + +# VARIABLE INSTANTIATION + + +# CLASSES +class Model_View_Store_Basket(Model_View_Store): + # Attributes + # product_categories: list # (str) + form_delivery: Form_Billing + form_billing: Form_Billing + forms_delivery_method: list # [] + is_collapsed_info_billing: bool + is_collapsed_info_delivery: bool + # Global constants + # category_products: dict { category_enum_id: List[Product] } + hash_page_store_checkout = '/store/checkout' + hash_page_store_checkout_session = '/store/checkout_session' + hash_store_basket_info = '/store/basket_info' + id_container_info_billing = 'containerInfoBilling' + id_container_info_delivery = 'containerInfoDelivery' + id_overlay_info_delivery = 'overlayInfoDelivery' + id_overlay_info_billing = 'overlayInfoBilling' + key_address1 = 'address_1' + key_address2 = 'address_2' + key_city = 'city' + key_county = 'county' + key_id_checkout = 'checkout-session-id' + key_info_billing = 'billing-info' + key_info_delivery = 'delivery-info' + key_info_identical = 'identical' + key_info_type = 'type-info' + key_is_subscription = 'is-subscription' + key_name_full = 'name_full' + key_phone_number = 'phone_number' + key_postcode = 'postcode' + key_region = 'region' + key_url_checkout = 'checkout-url' + + # Attributes + @property + def title(self): + return 'Store Basket' + + def __new__(cls, db, id_user, app, id_currency, id_region_delivery): + # Initialiser - validation + return super(Model_View_Store_Basket, cls).__new__(cls, db, id_user, app, id_currency, id_region_delivery) + + def __init__(self, db, id_user, app, id_currency, id_region_delivery): + # Constructor + super().__init__(db, id_user, app, id_currency, id_region_delivery) + # self.product_categories = Model_View_Store_Basket.get_many_product_category(get_all_category = True, get_all_product = True) + self.form_billing = Form_Billing() + self.form_billing.form_type_billing_not_delivery = True + self.form_delivery = Form_Billing() + # if logged in: + # else: + self.is_collapsed_info_billing = False + self.is_collapsed_info_delivery = False + """ + self.forms_product = {} + for cat in self.product_categories: + for product in cat: + if len(list(product.variations.keys())) == 0: + new_form = Form_Product() + if new_form.validate_on_submit(): + # Handle form submission + self.add_2_basket(product.id, ) + self.forms[str(product.id)] = new_form + """ \ No newline at end of file diff --git a/models/model_view_store_checkout.py b/models/model_view_store_checkout.py new file mode 100644 index 00000000..6a072fc0 --- /dev/null +++ b/models/model_view_store_checkout.py @@ -0,0 +1,75 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: View Models +Feature: Store Checkout View Model + +Description: +Data model for store checkout view +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# METHODS + +# IMPORTS +# internal +from models.model_view_store import Model_View_Store +from models.model_view_store_basket import Model_View_Store_Basket +# from routes import bp_home +from business_objects.product import Product +from forms import Form_Billing # Form_Product +import lib.argument_validation as av +from datastores.datastore_store import DataStore_Store +# external +import os +import stripe + +# VARIABLE INSTANTIATION + + +# CLASSES +class Model_View_Store_Checkout(Model_View_Store_Basket): + # Attributes + key_secret_stripe: str + key_public_stripe: str + # Global constants + key_id_price = 'price_id' + @property + def title(self): + return 'Store Checkout' + + def __new__(cls, db, id_user, app): + # Initialiser - validation + return super(Model_View_Store_Checkout, cls).__new__(cls, db, id_user, app) + + def __init__(self, db, id_user, app): + # Constructor + super().__init__(db, id_user, app) + self.key_secret_stripe = os.environ.get("KEY_SECRET_STRIPE") + self.key_public_stripe = os.environ.get("KEY_PUBLIC_STRIPE") + + # For sample support and debugging, not required for production: + stripe.set_app_info( + 'stripe-samples/checkout-one-time-payments', + version='0.0.1', + url='https://github.com/stripe-samples/checkout-one-time-payments') + + stripe.api_key = self.key_secret_stripe + + + def create_product(self, product): # _name, product_description): + return DataStore_Store(self.db, self.info_user).create_product(product) # _name, product_description) + + def create_price(self, product, currency): + return DataStore_Store(self.db, self.info_user).create_price(product, currency) + + def get_many_product_new(self): + return DataStore_Store(self.db, self.info_user).get_many_product_new() + + """ + def get_price_id(product_ids): + return DataStore_Store().get_many_id_price(product_ids) + """ diff --git a/models/model_view_store_checkout_success.py b/models/model_view_store_checkout_success.py new file mode 100644 index 00000000..6705ae75 --- /dev/null +++ b/models/model_view_store_checkout_success.py @@ -0,0 +1,55 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: View Models +Feature: Store Checkout Success View Model + +Description: +Data model for store checkout success view +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# METHODS + +# IMPORTS +# internal +from models.model_view_store import Model_View_Store +from models.model_view_store_checkout import Model_View_Store_Checkout +# from routes import bp_home +from business_objects.product import Product +from forms import Form_Billing # Form_Product +import lib.argument_validation as av +from datastores.datastore_store import DataStore_Store +# external +import os + +# VARIABLE INSTANTIATION + + +# CLASSES +class Model_View_Store_Checkout_Success(Model_View_Store_Checkout): + # Attributes + key_secret_stripe: str + key_public_stripe: str + # Global constants + key_id_price = 'price_id' + @property + def title(self): + return 'Store Checkout Success' + + def __new__(cls, db, id_user, app, id_checkout_session, checkout_items = None): + # Initialiser - validation + _m = 'Model_View_Store_Checkout_Success.__new__' + # av.val_list(checkout_items, 'checkout_items', _m) + av.val_str(id_checkout_session, 'id_checkout_session', _m) + return super(Model_View_Store_Checkout_Success, cls).__new__(cls, db, id_user, app) + + def __init__(self, db, id_user, app, id_checkout_session, checkout_items = None): + # Constructor + super().__init__(db, id_user, app) + self.checkout_items = checkout_items + self.id_checkout_session = id_checkout_session + self.order = self.get_many_user_order('', 1, id_checkout_session) \ No newline at end of file diff --git a/models/model_view_store_home.py b/models/model_view_store_home.py new file mode 100644 index 00000000..5cbed4c5 --- /dev/null +++ b/models/model_view_store_home.py @@ -0,0 +1,63 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: View Models +Feature: Store Home View Model + +Description: +Data model for store home view +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# METHODS + +# IMPORTS +# internal +from models.model_view_store import Model_View_Store +# from routes import bp_home +from business_objects.product import Product +from forms import Form_Basket_Add, Form_Basket_Edit # Form_Product +# external + + +# VARIABLE INSTANTIATION + + +# CLASSES +class Model_View_Store_Home(Model_View_Store): + # Attributes + product_categories: list # (str) + forms_product: dict + forms_basket: dict + # Global constants + # category_products: dict { category_enum_id: List[Product] } + # Attributes + @property + def title(self): + return 'Store Home' + max_products_per_category = -1 + + def __new__(cls, db, id_user, app, id_currency, id_region_delivery): + # Initialiser - validation + return super(Model_View_Store_Home, cls).__new__(cls, db, id_user, app, id_currency, id_region_delivery) + + def __init__(self, db, id_user, app, id_currency, id_region_delivery): + # Constructor + super().__init__(db, id_user, app, id_currency, id_region_delivery) + # self.categories = Model_View_Store_Home.get_many_product_category(self.db, get_all_category = True, get_all_product = True) + # self.get_many_product_category(get_all_category = True, get_all_product = True) + """ + self.forms_product = {} + for cat in self.product_categories: + for product in cat: + if len(list(product.variations.keys())) == 0: + new_form = Form_Product() + if new_form.validate_on_submit(): + # Handle form submission + self.add_2_basket(product.id, ) + self.forms[str(product.id)] = new_form + """ + diff --git a/models/model_view_store_product.py b/models/model_view_store_product.py new file mode 100644 index 00000000..23bc705a --- /dev/null +++ b/models/model_view_store_product.py @@ -0,0 +1,82 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: View Models +Feature: Store Product View Model + +Description: +Data model for store product view +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# METHODS + +# IMPORTS +# internal +from models.model_view_store import Model_View_Store +from datastores.datastore_store import DataStore_Store +# from routes import bp_home +from business_objects.product import Product, Product_Filters +import lib.argument_validation as av +# external + + +# VARIABLE INSTANTIATION + + +# CLASSES +class Model_View_Store_Product(Model_View_Store): + # categories: list # (str) + # category_products: dict { category_enum_id: List[Product] } + + # Attributes + @property + def title(self): + return 'Store Home' + + def __new__(cls, db, id_user, app, id_permutation, id_currency, id_region_delivery): # *args, **kwargs + # Initialiser - validation + _m = 'Model_View_Store_Product.__new__' + print(f'{_m}\nstarting...') + v_arg_type = 'class attribute' + + # av.val_instance(product, 'product', _m, Product, v_arg_type=v_arg_type) + # av.val_int(id_product, 'id_product', _m, v_arg_type=v_arg_type) + # av.val_int(id_permutation, 'id_permutation', _m, v_arg_type=v_arg_type) + + print(f'user id: {id_user.get("sub")}') + print(f'ending') + + # return super().__new__(cls, *args, **kwargs) # Model_View_Store_Product, cls # , db, id_user, id_product) # , db, id_user) + return super(Model_View_Store_Product, cls).__new__(cls, db, id_user, app, id_currency, id_region_delivery) + + def __init__(self, db, id_user, app, id_permutation, id_currency, id_region_delivery): + # Constructor + _m = 'Model_View_Store_Product.__init__' + print(f'{_m}\nstarting...') + super().__init__(db, id_user, app, id_currency, id_region_delivery) + print('supered') + print(f'user info: {self.info_user}') + # print(f'user id: {self.info_user.get("sub")}') + + category_list = DataStore_Store(self.db, self.info_user).get_many_product_category(Product_Filters( + self.info_user['sub'], + True, '', False, + True, '', False, False, + False, str(id_permutation), False, + True, '', False, False, + False, str(id_region_delivery), False, + False, str(id_currency), False, + True, '', False + )) # product_ids=str(id_product), permutation_ids=str(id_permutation)) + print('connection to db successful') + # self.categories = categories + # self.category_index = category_index + if (category_list.get_count_categories() > 0): + self.product = category_list.get_permutation_first() + else: + self.product = None + print('selected permutation selected') diff --git a/pay_stripe.py b/pay_stripe.py new file mode 100644 index 00000000..bda7620a --- /dev/null +++ b/pay_stripe.py @@ -0,0 +1,182 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: App General +Feature: App + +Description: +Initializes the Flask application, sets the configuration based on the environment, and defines two routes (/ and /about) that render templates with the specified titles. +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# METHODS + +# IMPORTS +import os +import stripe +import json +from flask import Flask, render_template, render_template_string, jsonify, request, send_from_directory, redirect +from dotenv import load_dotenv, find_dotenv + +from config import app_config + +# VARIABLE INSTANTIATION +key_secret = os.environ.get("KEY_SECRET_STRIPE") +key_public = os.environ.get("KEY_PUBLIC_STRIPE") # 'pk_test_51OGrxlL7BuLKjoMpfpfw7bSmZZK1MhqMoQ5VhW2jUj7YtoEejO4vqnxKPiqTHHuh9U4qqkywbPCSI9TpFKtr4SYH007KHMWs68' + +# METHODS +def create_product_price(): + print(f'stripe.api_key = {stripe.api_key}') + starter_subscription = stripe.Product.create( + name="Starter Subscription", + description="$12/Month subscription", + ) + + starter_subscription_price = stripe.Price.create( + unit_amount=1200, + currency="usd", + recurring={"interval": "month"}, + product=starter_subscription['id'], + ) + + # Save these identifiers + print(f"Success! Here is your starter subscription product id: {starter_subscription.id}") + print(f"Success! Here is your starter subscription price id: {starter_subscription_price.id}") + + return starter_subscription_price.id + +def get_file_str(f_address): + f = open(f_address) + return f.read() + +# Ensure environment variables are set. +price = os.getenv('PRICE') +if price is None or price == 'price_12345' or price == '': + print('You must set a Price ID in .env. Please see the README.') + exit(0) + +# For sample support and debugging, not required for production: +stripe.set_app_info( + 'stripe-samples/checkout-one-time-payments', + version='0.0.1', + url='https://github.com/stripe-samples/checkout-one-time-payments') + +# stripe.api_version = '2020-08-27' +stripe.api_key = key_secret # os.getenv('KEY_SECRET_STRIPE') + +# app_dir = str(os.path.abspath(os.path.join( +# __file__, "..", ".."))) +# static_dir = str(os.path.abspath(os.path.join( +# app_dir, os.getenv("STATIC_DIR")))) +# template_dir = str(os.path.abspath(os.path.join( +# app_dir, os.getenv("TEMPLATE_DIR")))) +app = Flask(__name__) # , static_folder=static_dir, + # static_url_path="", template_folder=template_dir) +app.config.from_object(app_config) + +@app.route('/', methods=['GET']) +def home(): + # return render_template(f'{app_dir}\\templates\\_home.html') # f'{app_dir}\\templates\\layout.html') + # return render_template_string(get_file_str(f'{app_dir}\\templates\\_home.html')) # f'{app_dir}\\templates\\layout.html') + return render_template('_home.html', title='Home') + +@app.route('/store', methods=['GET']) +def store_home(): + return render_template('_store_home.html', title='Store Home') + +@app.route('/contact') +def contact(): + return render_template('_contact.html', title='Contact Us') + + +@app.route('/config', methods=['GET']) +def get_publishable_key(): + price = stripe.Price.retrieve(os.getenv('PRICE')) + return jsonify({ + 'publicKey': key_public, # os.getenv('KEY_PUBLIC_STRIPE'), + 'unitAmount': price['unit_amount'], + 'currency': price['currency'] + }) + +# Fetch the Checkout Session to display the JSON result on the success page +@app.route('/checkout-session', methods=['GET']) +def get_checkout_session(): + id = request.args.get('sessionId') + print(f'checkout session id: {id}') + checkout_session = stripe.checkout.Session.retrieve(id) + return jsonify(checkout_session) + + +@app.route('/create-checkout-session', methods=['POST']) +def create_checkout_session(): + quantity = request.form.get('quantity', 1) + domain_url = os.getenv('DOMAIN') + + try: + # Create new Checkout Session for the order + # Other optional params include: + # [billing_address_collection] - to display billing address details on the page + # [customer] - if you have an existing Stripe Customer ID + # [payment_intent_data] - lets capture the payment later + # [customer_email] - lets you prefill the email input in the form + # [automatic_tax] - to automatically calculate sales tax, VAT and GST in the checkout page + # For full details see https://stripe.com/docs/api/checkout/sessions/create + + # ?session_id={CHECKOUT_SESSION_ID} means the redirect will have the session ID set as a query param + checkout_session = stripe.checkout.Session.create( + success_url=domain_url + '/success.html?session_id={CHECKOUT_SESSION_ID}', + cancel_url=domain_url + '/canceled.html', + mode='subscription', # 'payment', + # automatic_tax={'enabled': True}, + line_items=[{ + 'price': os.getenv('PRICE'), + 'quantity': quantity, + }] + ) + return redirect(checkout_session.url, code=303) + except Exception as e: + return jsonify(error=str(e)), 403 + + +@app.route('/webhook', methods=['POST']) +def webhook_received(): + # You can use webhooks to receive information about asynchronous payment events. + # For more about our webhook events check out https://stripe.com/docs/webhooks. + webhook_secret = os.getenv('STRIPE_WEBHOOK_SECRET') + request_data = json.loads(request.data) + + if webhook_secret: + # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured. + signature = request.headers.get('stripe-signature') + try: + event = stripe.Webhook.construct_event( + payload=request.data, sig_header=signature, secret=webhook_secret) + data = event['data'] + except Exception as e: + return e + # Get the type of webhook event sent - used to check the status of PaymentIntents. + event_type = event['type'] + else: + data = request_data['data'] + event_type = request_data['type'] + data_object = data['object'] + + print('event ' + event_type) + + if event_type == 'checkout.session.completed': + print('🔔 Payment succeeded!') + + return jsonify({'status': 'success'}) + + +if __name__ == '__main__': + # stripe.api_key = key_secret + + # create_product_price() + + # Setup Stripe python client library. + load_dotenv(find_dotenv()) + app.run(port=4242, debug=True) \ No newline at end of file diff --git a/payments/__pycache__/pay_stripe.cpython-311.pyc b/payments/__pycache__/pay_stripe.cpython-311.pyc new file mode 100644 index 00000000..eab0ae29 Binary files /dev/null and b/payments/__pycache__/pay_stripe.cpython-311.pyc differ diff --git a/payments/pay_stripe.py b/payments/pay_stripe.py new file mode 100644 index 00000000..944bfecd --- /dev/null +++ b/payments/pay_stripe.py @@ -0,0 +1,170 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: App General +Feature: App + +Description: +Initializes the Flask application, sets the configuration based on the environment, and defines two routes (/ and /about) that render templates with the specified titles. +""" + +# IMPORTS +# VARIABLE INSTANTIATION +# METHODS + +# IMPORTS +import os +import stripe +import json +from flask import Flask, render_template, render_template_string, jsonify, request, send_from_directory, redirect +from dotenv import load_dotenv, find_dotenv + + +# VARIABLE INSTANTIATION +key_secret = os.environ.get("KEY_SECRET_STRIPE") +key_public = os.environ.get("KEY_PUBLIC_STRIPE") # 'pk_test_51OGrxlL7BuLKjoMpfpfw7bSmZZK1MhqMoQ5VhW2jUj7YtoEejO4vqnxKPiqTHHuh9U4qqkywbPCSI9TpFKtr4SYH007KHMWs68' + +# METHODS +def create_product_price(): + print(f'stripe.api_key = {stripe.api_key}') + starter_subscription = stripe.Product.create( + name="Starter Subscription", + description="$12/Month subscription", + ) + + starter_subscription_price = stripe.Price.create( + unit_amount=1200, + currency="usd", + recurring={"interval": "month"}, + product=starter_subscription['id'], + ) + + # Save these identifiers + print(f"Success! Here is your starter subscription product id: {starter_subscription.id}") + print(f"Success! Here is your starter subscription price id: {starter_subscription_price.id}") + + return starter_subscription_price.id + +def get_file_str(f_address): + f = open(f_address) + return f.read() + +# Ensure environment variables are set. +price = os.getenv('PRICE') +if price is None or price == 'price_12345' or price == '': + print('You must set a Price ID in .env. Please see the README.') + exit(0) + +# For sample support and debugging, not required for production: +stripe.set_app_info( + 'stripe-samples/checkout-one-time-payments', + version='0.0.1', + url='https://github.com/stripe-samples/checkout-one-time-payments') + +# stripe.api_version = '2020-08-27' +stripe.api_key = key_secret # os.getenv('KEY_SECRET_STRIPE') + +app_dir = str(os.path.abspath(os.path.join( + __file__, "..", ".."))) +static_dir = str(os.path.abspath(os.path.join( + app_dir, os.getenv("STATIC_DIR")))) +app = Flask(__name__, static_folder=static_dir, + static_url_path="", template_folder=static_dir) + + +@app.route('/', methods=['GET']) +def get_example(): + # return render_template(f'{app_dir}\\templates\\_home.html') # f'{app_dir}\\templates\\layout.html') + # return render_template_string(get_file_str(f'{app_dir}\\templates\\_home.html')) # f'{app_dir}\\templates\\layout.html') + return render_template('../templates/_home.html') + + +@app.route('/config', methods=['GET']) +def get_publishable_key(): + price = stripe.Price.retrieve(os.getenv('PRICE')) + return jsonify({ + 'publicKey': key_public, # os.getenv('KEY_PUBLIC_STRIPE'), + 'unitAmount': price['unit_amount'], + 'currency': price['currency'] + }) + +# Fetch the Checkout Session to display the JSON result on the success page +@app.route('/checkout-session', methods=['GET']) +def get_checkout_session(): + id = request.args.get('sessionId') + checkout_session = stripe.checkout.Session.retrieve(id) + return jsonify(checkout_session) + + +@app.route('/create-checkout-session', methods=['POST']) +def create_checkout_session(): + quantity = request.form.get('quantity', 1) + domain_url = os.getenv('DOMAIN') + + try: + # Create new Checkout Session for the order + # Other optional params include: + # [billing_address_collection] - to display billing address details on the page + # [customer] - if you have an existing Stripe Customer ID + # [payment_intent_data] - lets capture the payment later + # [customer_email] - lets you prefill the email input in the form + # [automatic_tax] - to automatically calculate sales tax, VAT and GST in the checkout page + # For full details see https://stripe.com/docs/api/checkout/sessions/create + + # ?session_id={CHECKOUT_SESSION_ID} means the redirect will have the session ID set as a query param + checkout_session = stripe.checkout.Session.create( + success_url=domain_url + '/success.html?session_id={CHECKOUT_SESSION_ID}', + cancel_url=domain_url + '/canceled.html', + mode='payment', + # automatic_tax={'enabled': True}, + line_items=[{ + 'price': os.getenv('PRICE'), + 'quantity': quantity, + }] + ) + return redirect(checkout_session.url, code=303) + except Exception as e: + return jsonify(error=str(e)), 403 + + +@app.route('/webhook', methods=['POST']) +def webhook_received(): + # You can use webhooks to receive information about asynchronous payment events. + # For more about our webhook events check out https://stripe.com/docs/webhooks. + webhook_secret = os.getenv('STRIPE_WEBHOOK_SECRET') + request_data = json.loads(request.data) + + if webhook_secret: + # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured. + signature = request.headers.get('stripe-signature') + try: + event = stripe.Webhook.construct_event( + payload=request.data, sig_header=signature, secret=webhook_secret) + data = event['data'] + except Exception as e: + return e + # Get the type of webhook event sent - used to check the status of PaymentIntents. + event_type = event['type'] + else: + data = request_data['data'] + event_type = request_data['type'] + data_object = data['object'] + + print('event ' + event_type) + + if event_type == 'checkout.session.completed': + print('🔔 Payment succeeded!') + + return jsonify({'status': 'success'}) + + +if __name__ == '__main__': + # stripe.api_key = key_secret + + # create_product_price() + + # Setup Stripe python client library. + load_dotenv(find_dotenv()) + app.run(port=4242, debug=True) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..1a531f8e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,24 @@ + +flask +flask_wtf +flask_sqlalchemy +flask_cors +authlib +jwt +mysqlclient + + +# environment variables +# KEY_SECRET_FLASK = 'random secret key' +# # KEY_PUBLIC_FLASK = '' +# ID_AUTH0_CLIENT = '' +# ID_AUTH0_CLIENT_SECRET = '' +# DOMAIN_AUTH0=dev-nwak2066ef6h8ixn.us.auth0.com +# SQLALCHEMY_DATABASE_URI = 'mysql://username:password@localhost/dbname' + # Replace 'username', 'password', 'localhost', and 'dbname' with your actual database credentials + +# run with: +# python -m flask run + +# not env var: +# auth0 recovery key: S92HY59VU5J9YDVYWCRHSKJ8 \ No newline at end of file diff --git a/routes.py b/routes.py new file mode 100644 index 00000000..d93a97ad --- /dev/null +++ b/routes.py @@ -0,0 +1,54 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Backend +Feature: Controller - Webpage routing + +Description: +Defines the routes and view functions for each page. +Manages the interaction between the frontend and backend. +""" + +from flask import render_template, url_for, Blueprint +from app import app +from app.forms import Form_Contact +# from forms import MyForm +# from app import MyForm +from model_view_contact import Model_View_Contact + +""" +@app.route('/', methods=['GET']) +def home(): + return render_template('_home.html', title='Home') + +@app.route('/store', methods=['GET']) +def store_home(): + return render_template('_store_home.html', title='Store Home') + +@app.route('/contact', methods=['GET', 'POST']) +def contact(): + form = Form_Contact() + if form.validate_on_submit(): + # Handle form submission + email = form.sender_email.data + CC = form.sender_CC.data + name = form.sender_name.data + msg = form.sender_message.data + # return render_template('contact.html', form=form) + # return render_template('_contact.html', title='Contact Us') + return render_template('contact.html', model=Model_View_Contact(form)) + +@app.route('/about') +def about(): + return render_template('about.html') + +@app.route('/contact', methods=['GET', 'POST']) +def contact(): + form = MyForm() + if form.validate_on_submit(): + # Handle form submission + pass + return render_template('contact.html', form=form) +""" \ No newline at end of file diff --git a/run.py b/run.py new file mode 100644 index 00000000..1dc4c20d --- /dev/null +++ b/run.py @@ -0,0 +1,16 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Backend +Feature: Launcher + +Description: +Runs project. +""" + +from app import app + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file diff --git a/static/batch/sql_combine.bat b/static/batch/sql_combine.bat new file mode 100644 index 00000000..8c673a25 --- /dev/null +++ b/static/batch/sql_combine.bat @@ -0,0 +1,96 @@ +@echo off +setlocal enabledelayedexpansion + +:: set "test=C:\C:\ \" +set dir_parent=C:\Users\edwar\OneDrive\Documents\Programming\Visual Studio 2022\PARTS_Web\app\static\sql +set "f_list=file_list.txt" +set dir_current=%cd% +set "f_tmp=temp.txt" +set "f_combine=000_combine.sql" +set verbose=0 +set "strs_delete_0=920_edit_permissions.sql" +set "strs_delete_1=910_anal.sql" +set "strs_delete_2=deprecated" +set "strs_delete_3=%f_list%" +set "strs_delete_4=%f_tmp%" +set "strs_delete_5=701_p_shop_get_many_role_permission.sql" +set "strs_delete_6=600_p_shop_save_product.sql" +set "strs_delete_7=170_ish_tbl_ERP_Order.sql" +set strs_n_max=7 +set strs_list =%strs_delete_0% %strs_delete_1% %strs_delete_2% %strs_delete_3% %strs_delete_4% +set "str_true=true" +set "str_replace=" + +set "str_list=" + + +:: report constants +echo temp = %f_tmp% +echo dir_parent = !%dir_parent%! +echo dir_current = !%dir_current%! +echo file_list = %f_list% +echo file = %f_combine% +echo n strings = !strs_n_max! + +:: begin +cd %dir_parent% +::echo current directory: %cd% +del %f_tmp% +del %f_list% +del %f_combine% + +:: colate dir files +dir /b > %f_list% + +::type %f_list% + +echo loopy +:: Remove blacklist files +:: grep -v '920_edit_permissions.sql' %f_list% > %f_list% +:: grep -v '910_anal.sql' %f_list% > %f_list% + + +(for /f "delims=" %%a in (%f_list%) do ( + ::if %verbose% gtr 0 ( echo new line ) + set "line=%%a" + ::if %verbose% gtr 0 ( echo new line = !line! ) + ::if !line! neq %strs_delete_0% if !line! neq %strs_delete_1% if !line! neq %strs_delete_2% if !line! neq %strs_delete_3% if !line! neq %strs_delete_4% if !line! neq %strs_delete_5% if !line! neq %strs_delete_6% ( + :: echo !line! + :: set "str_list=!str_list! !line!" + ::) + set include_line=1 + for /L %%i in (0, 1, %strs_n_max%) do ( + ::set "str_delete=!strs_delete_%%i!" + if !line! equ !strs_delete_%%i! ( + set include_line=0 + ) + ::set "include_line=!include_line!" + set "line=!line!" + ) + if !include_line! gtr 0 ( + echo !line! + set "str_list=!str_list! !line!" + ) + set "line=!line!" +)) > %f_tmp% + +:: Combine files +echo output list: +type %f_tmp% + +del %f_list% +echo file_tmp: %f_tmp% +echo file_list: %f_list% +echo combining files +::type %f_tmp% | type > %f_list% +:: +::type %f_list% +echo cmd: +echo "type !str_list! > %f_combine%" +type !str_list! > %f_combine% + +cd %dir_current% + +echo Current Time: %TIME% + +endlocal \ No newline at end of file diff --git a/static/css/contact.css b/static/css/contact.css new file mode 100644 index 00000000..3f35c8b4 --- /dev/null +++ b/static/css/contact.css @@ -0,0 +1,15 @@ +/* +.content > a { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + text-align: center; +} + +.content > a > img, .content > a > h4 { + flex: content; + margin: 0px; +} +*/ + diff --git a/static/css/home.css b/static/css/home.css new file mode 100644 index 00000000..36bdc651 --- /dev/null +++ b/static/css/home.css @@ -0,0 +1,14 @@ +.img-demo { + max-width: 50%; + min-width: 500px; +} + +.img-featured { + width: 100%; +} + +/* +img { + background-image: url("/static/images/Tag_Molly1.png"); +} +*/ \ No newline at end of file diff --git a/static/css/shared.css b/static/css/shared.css new file mode 100644 index 00000000..1f64ed2b --- /dev/null +++ b/static/css/shared.css @@ -0,0 +1,302 @@ +:root { + /* Declare global variables */ + --c_purple: #5B29FF; + --c_purple_pastel: #D1D1FF; + --c_purple_light: #C6BDFF; + --c_purple_dark: #4700B3; + --c_blue: #0044FF; + --c_blue_pastel: #B8E0FF; + --c_blue_light: #73E8FF; + --c_blue_dark: #003ADB; +} + +*{ + box-sizing: border-box; +} + +body { + font-family: Arial; + padding: 10px; + background: var(--c_purple_pastel); +} + +h1 { + font-size: 4vh; +} + +h2 { + font-size: 2.4vh; +} + +h3 { + font-size: 2vh; + margin: 1vh; +} + +h4 { + font-size: 1.5vh; + margin: 1vh; +} + +h5 { + font-size: 1.25vh; + margin: 1vh; +} + +/* Header/Blog Title */ +.header { + padding: 1vh; + text-align: center; + background-color: var(--c_purple_light); +} + +/* Style the top navigation bar */ +.topnav { + overflow: hidden; + background-color: var(--c_purple); + border-bottom-left-radius: 2.5vh; + border-bottom-right-radius: 2.5vh; + flex-wrap: wrap; +} + +/* Style the topnav links */ +.topnav a, .topnav label { + float: left; + display: block; + color: white; + text-align: center; + /* padding: 14px 16px; */ + text-decoration: none; +} +.topnav a { + padding: 3vh 2vw; +} +/* Change color on hover */ +.topnav a:hover { + background-color: var(--c_purple_light); + color: var(--c_purple_dark); +} + +.topnav .container { + max-width: 20%; + height: 100%; +} + +/* Create two unequal columns that floats next to each other */ +/* Left column */ +.leftcolumn { + float: left; + width: 70%; + display: flex; + flex-wrap: wrap; + /* min-width: fit-content; */ + align-items: center; + justify-content: center; +} + +/* Right column */ +.rightcolumn { + float: left; + width: 30%; + display: flex; + flex-wrap: wrap; + /* min-width: fit-content; only on store?? */ + /* background-color: #f1f1f1; */ + padding-left: 20px; + height: fit-content; + align-items: center; + justify-content: center; +} + +/* Fake image */ +.fakeimg { + background-color: var(--c_purple_light); + width: 100%; + padding: 20px; +} + +img, video { + border-radius: 3vh; +} + +/* header image */ +img.header-logo { + max-height: 15vh; +} + +/* icon images */ +.img-icon { + max-width: 5vh; + max-height: 5vh; + border-radius: 1vh; +} + +.container-icon-label { + padding: 0; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + text-align: center; +} + +.container-icon-label > * { + display: inline-flex; + margin-left: 1vh; + margin-right: 1vh; +} + +.header > .container:first-of-type { + max-width: 25%; + justify-self: left; +} +.header > .container:last-of-type { + max-width: 75%; + justify-self: left; +} + +/* Add a card effect for articles */ +.card { + background-color: white; + padding: 1vh; + margin-top: 3vh; + display: flex !important; + flex-wrap: wrap; + align-items: center; + justify-content: center; + text-align: center; + border-radius: 4vh; + min-width: fit-content; +} + +.card.subcard { + margin-top: 0; +} + +.header.card { + border-radius: 2.5vh; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +.container { + flex: 1; + margin: 0px; + align-items: center; + justify-content: center; + text-align: center; + max-width: 100%; + min-width: fit-content; +} + +.column { + display: flex; + flex-direction: column; +} + +.row { + display: flex; + flex-direction: row; + width: 100%; + min-width: fit-content; +} + +.container > .card:first-of-type { + margin-top: none; +} + +/* Clear floats after the columns +.row:after { + content: ""; + display: table; + clear: both; +} +*/ +/* Footer */ +.footer { + padding: 1vh; + text-align: center; + background: var(--c_purple_light); + margin-top: 20px; + border-radius: 2.5vh; +} + +.footer > h4, h5 { + padding: 0; + margin: 1vh; +} + +/* Responsive layout - when the screen is less than 800px wide, make the two columns stack on top of each other instead of next to each other */ +@media screen and (max-width: 800px) { + .leftcolumn, .rightcolumn { + width: 100%; + /* padding: 0; */ + } +} + +/* Responsive layout - when the screen is less than 400px wide, make the navigation links stack on top of each other instead of next to each other */ +@media screen and (max-width: 400px) { + .topnav a { + float: none; + width: 100%; + } +} + +/* input container + margin-top: 3vh; + */ +.container-input { + padding: 1vh; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + text-align: center; +} + +.container-input > label { + width: 100%; + margin-bottom: 1vh; + margin-top: 0; +} + +.container-input:not(:nth-child(3)) > label { + margin-top: 1vh; +} + +.container-input > input, .container-input > textarea { + border: 2px solid var(--c_purple); + max-width: 50%; + min-width: 40%; + padding: 1vh; +} + +.label-title { + width: 100%; +} + +button, .btn-submit, input[type="submit"] { + font-size: 20px; + font-weight: bold; + border: 4px solid; + border-radius: 2vh; + padding: 1vh 2vh 1vh 2vh; + margin: 0.5vh; + background-color: var(--c_blue_pastel); + color: var(--c_blue_dark); + border-color: var(--c_blue_dark); +} + +/* Overlay modal */ +.overlay { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + justify-content: center; + align-items: center; + z-index: 999; +} \ No newline at end of file diff --git a/static/css/store_home.css b/static/css/store_home.css new file mode 100644 index 00000000..e69de29b diff --git a/static/css/store_product.css b/static/css/store_product.css new file mode 100644 index 00000000..e69de29b diff --git a/static/css/store_shared.css b/static/css/store_shared.css new file mode 100644 index 00000000..7864b531 --- /dev/null +++ b/static/css/store_shared.css @@ -0,0 +1,55 @@ +.img-product { + max-width: 20vh; + max-height: 20vh; + border-radius: 3vh; + justify-self: left; +} + +.img-thumbnail { + max-width: 10vh; + max-height: 10vh; + border-radius: 3vh; + justify-self: left; +} + +.btnAdd2Basket { + background-color: var(--c_blue_pastel); + color: var(--c_blue_dark); + border-color: var(--c_blue_dark); +} + +#btnCheckout, .btnBuyNow { + background-color: var(--c_purple_pastel); + color: var(--c_purple_dark); + border-color: var(--c_purple_dark); +} + +.btn-increment, .btn-decrement { + border: 2px solid darkgrey; + background-color: lightgray; + margin: 1vh 1vh; + width: 2.5vh; + height: 2.5vh; + border-radius: 1.25vh; + font-size: 2vh; +} + +.container-input > input { + padding: 0vh 1vh; + border-radius: 0.5vh; + max-width: 7vh; +} + +#basket { + max-width: 100%; +} + +.basket-item-delete { + text-decoration: underline; +} + + +/* Right column */ +.rightcolumn { + min-width: fit-content; +} \ No newline at end of file diff --git a/static/css/stylesheet.css b/static/css/stylesheet.css new file mode 100644 index 00000000..5818ec66 --- /dev/null +++ b/static/css/stylesheet.css @@ -0,0 +1,86 @@ +* { + box-sizing: border-box; +} + +body { + padding: 10px; + display: block; + background-color: grey; +} + +.banner { + background-color: black; + color: white; + width: 100%; + position: fixed; + padding-top: 5vh; + padding-bottom: 10vh; +} + +.banner.top { + background-color: black; + color: white; +} + +.banner.bottom { + background-color: black; + color: white; + bottom: 0; +} + +.row:after { + content: ""; + display: table; + clear: both; +} + +.column { + float: left; + padding: 5vw; +} + +.column.side { + width: 25%; +} + +.column.middle { + width: 50%; +} + +.midbod { + background-color: white; + color: black; +} + +.panel { + float: left; +} + +img { + height: 100px; + width: 100px; +} + +.panel.labelcontainer { + background-color: black; + color: white; + text-align: center; +} + +.label { + font-family: Arial, Helvetica, sans-serif; + text-decoration: none; +} + +.label.bodytext { + background-color: black; + color: white; + text-decoration: none; + font-style: normal; + font-size: 12; +} + +.label.title { + font-style: bold; + font-size: 18; +} \ No newline at end of file diff --git a/static/docs/Logo.png b/static/docs/Logo.png new file mode 100644 index 00000000..d49d2284 Binary files /dev/null and b/static/docs/Logo.png differ diff --git a/static/docs/__pycache__/server.cpython-311.pyc b/static/docs/__pycache__/server.cpython-311.pyc new file mode 100644 index 00000000..9456c281 Binary files /dev/null and b/static/docs/__pycache__/server.cpython-311.pyc differ diff --git a/static/docs/server.py b/static/docs/server.py new file mode 100644 index 00000000..13733752 --- /dev/null +++ b/static/docs/server.py @@ -0,0 +1,124 @@ +#! /usr/bin/env python3.6 + +""" +server.py +Stripe Sample. +Python 3.6 or newer required. +""" + +import stripe +import json +import os + +from flask import Flask, render_template, jsonify, request, send_from_directory, redirect +from dotenv import load_dotenv, find_dotenv + +# Setup Stripe python client library. +load_dotenv(find_dotenv()) + +# Ensure environment variables are set. +price = os.getenv('PRICE') +if price is None or price == 'price_12345' or price == '': + print('You must set a Price ID in .env. Please see the README.') + exit(0) + +# For sample support and debugging, not required for production: +stripe.set_app_info( + 'stripe-samples/checkout-one-time-payments', + version='0.0.1', + url='https://github.com/stripe-samples/checkout-one-time-payments') + +stripe.api_version = '2020-08-27' +stripe.api_key = os.getenv('STRIPE_KEY_SECRET') + +static_dir = str(os.path.abspath(os.path.join( + __file__, "..", os.getenv("STATIC_DIR")))) +app = Flask(__name__, static_folder=static_dir, + static_url_path="", template_folder=static_dir) + + +@app.route('/', methods=['GET']) +def get_example(): + return render_template('index.html') + + +@app.route('/config', methods=['GET']) +def get_publishable_key(): + price = stripe.Price.retrieve(os.getenv('PRICE')) + return jsonify({ + 'publicKey': os.getenv('STRIPE_PUBLISHABLE_KEY'), + 'unitAmount': price['unit_amount'], + 'currency': price['currency'] + }) + +# Fetch the Checkout Session to display the JSON result on the success page +@app.route('/checkout-session', methods=['GET']) +def get_checkout_session(): + id = request.args.get('sessionId') + checkout_session = stripe.checkout.Session.retrieve(id) + return jsonify(checkout_session) + + +@app.route('/create-checkout-session', methods=['POST']) +def create_checkout_session(): + quantity = request.form.get('quantity', 1) + domain_url = os.getenv('DOMAIN') + + try: + # Create new Checkout Session for the order + # Other optional params include: + # [billing_address_collection] - to display billing address details on the page + # [customer] - if you have an existing Stripe Customer ID + # [payment_intent_data] - lets capture the payment later + # [customer_email] - lets you prefill the email input in the form + # [automatic_tax] - to automatically calculate sales tax, VAT and GST in the checkout page + # For full details see https://stripe.com/docs/api/checkout/sessions/create + + # ?session_id={CHECKOUT_SESSION_ID} means the redirect will have the session ID set as a query param + checkout_session = stripe.checkout.Session.create( + success_url=domain_url + '/success.html?session_id={CHECKOUT_SESSION_ID}', + cancel_url=domain_url + '/canceled.html', + mode='payment', + # automatic_tax={'enabled': True}, + line_items=[{ + 'price': os.getenv('PRICE'), + 'quantity': quantity, + }] + ) + return redirect(checkout_session.url, code=303) + except Exception as e: + return jsonify(error=str(e)), 403 + + +@app.route('/webhook', methods=['POST']) +def webhook_received(): + # You can use webhooks to receive information about asynchronous payment events. + # For more about our webhook events check out https://stripe.com/docs/webhooks. + webhook_secret = os.getenv('STRIPE_WEBHOOK_SECRET') + request_data = json.loads(request.data) + + if webhook_secret: + # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured. + signature = request.headers.get('stripe-signature') + try: + event = stripe.Webhook.construct_event( + payload=request.data, sig_header=signature, secret=webhook_secret) + data = event['data'] + except Exception as e: + return e + # Get the type of webhook event sent - used to check the status of PaymentIntents. + event_type = event['type'] + else: + data = request_data['data'] + event_type = request_data['type'] + data_object = data['object'] + + print('event ' + event_type) + + if event_type == 'checkout.session.completed': + print('🔔 Payment succeeded!') + + return jsonify({'status': 'success'}) + +if __name__ == '__main__': + app.run(port=4242, debug=True) \ No newline at end of file diff --git a/static/docs/template webpage.html b/static/docs/template webpage.html new file mode 100644 index 00000000..600d3329 --- /dev/null +++ b/static/docs/template webpage.html @@ -0,0 +1,63 @@ + + + + + + + +
+

My Website

+

Resize the browser window to see the effect.

+
+ +
+ Link + Link + Link + Link +
+ +
+
+
+

TITLE HEADING

+
Title description, Dec 7, 2017
+
Image
+

Some text..

+

Sunt in culpa qui officia deserunt mollit anim id est laborum consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.

+
+
+

TITLE HEADING

+
Title description, Sep 2, 2017
+
Image
+

Some text..

+

Sunt in culpa qui officia deserunt mollit anim id est laborum consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.

+
+
+
+
+

About Me

+
Image
+

Some text about me in culpa qui officia deserunt mollit anim..

+
+
+

Popular Post

+

Image

+

Image

+

Image

+
+
+

Follow Me

+

Some text..

+
+
+
+ + + + + + + diff --git a/static/docs/test.py b/static/docs/test.py new file mode 100644 index 00000000..729ffc95 --- /dev/null +++ b/static/docs/test.py @@ -0,0 +1 @@ +print(not None) \ No newline at end of file diff --git a/static/images/Braille_Translator_Demo.png b/static/images/Braille_Translator_Demo.png new file mode 100644 index 00000000..17c7a695 Binary files /dev/null and b/static/images/Braille_Translator_Demo.png differ diff --git a/static/images/CAD.gif b/static/images/CAD.gif new file mode 100644 index 00000000..5e532877 Binary files /dev/null and b/static/images/CAD.gif differ diff --git a/static/images/Fractal Fortune Teller.mp4 b/static/images/Fractal Fortune Teller.mp4 new file mode 100644 index 00000000..08ebcff2 Binary files /dev/null and b/static/images/Fractal Fortune Teller.mp4 differ diff --git a/static/images/Invoice Generator.mp4 b/static/images/Invoice Generator.mp4 new file mode 100644 index 00000000..06490e93 Binary files /dev/null and b/static/images/Invoice Generator.mp4 differ diff --git a/static/images/Logo.png b/static/images/Logo.png new file mode 100644 index 00000000..d49d2284 Binary files /dev/null and b/static/images/Logo.png differ diff --git a/static/images/Logo_GitHub.png b/static/images/Logo_GitHub.png new file mode 100644 index 00000000..04999f33 Binary files /dev/null and b/static/images/Logo_GitHub.png differ diff --git a/static/images/Logo_LinkedIn.png b/static/images/Logo_LinkedIn.png new file mode 100644 index 00000000..67a756fd Binary files /dev/null and b/static/images/Logo_LinkedIn.png differ diff --git a/static/images/Prosthetics_Demo.gif b/static/images/Prosthetics_Demo.gif new file mode 100644 index 00000000..2fadccaf Binary files /dev/null and b/static/images/Prosthetics_Demo.gif differ diff --git a/static/images/Tag_Molly1.jpg b/static/images/Tag_Molly1.jpg new file mode 100644 index 00000000..8ca5c74d Binary files /dev/null and b/static/images/Tag_Molly1.jpg differ diff --git a/static/images/Warhammer Jiggler.gif b/static/images/Warhammer Jiggler.gif new file mode 100644 index 00000000..fbb53637 Binary files /dev/null and b/static/images/Warhammer Jiggler.gif differ diff --git a/static/images/icon_basket.png b/static/images/icon_basket.png new file mode 100644 index 00000000..6d6161d9 Binary files /dev/null and b/static/images/icon_basket.png differ diff --git a/static/images/mechatronics_design.gif b/static/images/mechatronics_design.gif new file mode 100644 index 00000000..fbb53637 Binary files /dev/null and b/static/images/mechatronics_design.gif differ diff --git a/static/images/ms_automation.mp4 b/static/images/ms_automation.mp4 new file mode 100644 index 00000000..a7850ffb Binary files /dev/null and b/static/images/ms_automation.mp4 differ diff --git a/static/images/prod_.jpg b/static/images/prod_.jpg new file mode 100644 index 00000000..9ad384d7 Binary files /dev/null and b/static/images/prod_.jpg differ diff --git a/static/images/prod_1.jpg b/static/images/prod_1.jpg new file mode 100644 index 00000000..475f011d Binary files /dev/null and b/static/images/prod_1.jpg differ diff --git a/static/images/prod_2.jpg b/static/images/prod_2.jpg new file mode 100644 index 00000000..552d0f84 Binary files /dev/null and b/static/images/prod_2.jpg differ diff --git a/static/images/prod_PB0NUOSEs06ymG.jpg b/static/images/prod_PB0NUOSEs06ymG.jpg new file mode 100644 index 00000000..892c8128 Binary files /dev/null and b/static/images/prod_PB0NUOSEs06ymG.jpg differ diff --git a/static/images/programming_services.mp4 b/static/images/programming_services.mp4 new file mode 100644 index 00000000..978c4685 Binary files /dev/null and b/static/images/programming_services.mp4 differ diff --git a/static/images/webapp_db_design.mp4 b/static/images/webapp_db_design.mp4 new file mode 100644 index 00000000..2daccdda Binary files /dev/null and b/static/images/webapp_db_design.mp4 differ diff --git a/static/js/contact.js b/static/js/contact.js new file mode 100644 index 00000000..f0cff237 --- /dev/null +++ b/static/js/contact.js @@ -0,0 +1,5 @@ +var _loading = true; + +function hookupPageContact() { + _loading = false; +} diff --git a/static/js/home.js b/static/js/home.js new file mode 100644 index 00000000..ef0c9352 --- /dev/null +++ b/static/js/home.js @@ -0,0 +1,6 @@ +var _loading = true; + +function hookupPageHome() { + hookupVideos(); + _loading = false; +} diff --git a/static/js/shared.js b/static/js/shared.js new file mode 100644 index 00000000..70073b3f --- /dev/null +++ b/static/js/shared.js @@ -0,0 +1,870 @@ +// Shared JS file names: routing, main, shared, localStorage, appDialogs +const _dataLoadingFlag = 'data-loading' +var _verbose = true; +var hashPageCurrent; + +function hookupShared() { + hookupVideos(); + hookupNavigation(); +} + +function hookupVideos() { + let videos = document.querySelectorAll('video'); + videos.forEach(function(video) { + video.addEventListener('mouseover', videoPlay(video)); + video.addEventListener('mouseout', videoPause(video)); + }); +} + +function videoPlay(elemVideo) { + if (!_loading) { // elemVideo.paused && + elemVideo.play(); + if (_verbose) { console.log("Playing video element: " + elemVideo.name)}; + } +} + +function videoPause(elemVideo) { + elemVideo.pause(); + if (_verbose) { console.log("Pausing video element: " + elemVideo.name)}; +} + +function hookupNavigation() { + console.log("hooking up navigation"); + + let btnNavHome = $(idNavHome); + initialiseEventHandler(btnNavHome, flagInitialised, function() { + btnNavHome.on("click", function(event) { + event.stopPropagation(); + // setupPageLocalStorageNext(hashPageStoreHome); + goToPage(hashPageHome); + }); + }); + + let btnNavContact = $(idNavContact); + initialiseEventHandler(btnNavContact, flagInitialised, function() { + btnNavContact.on("click", function(event) { + event.stopPropagation(); + // setupPageLocalStorageNext(hashPageStoreHome); + goToPage(hashPageContact); + }); + }); + + let btnNavStoreHome = $(idNavStoreHome); + console.log("hooking up store home"); + console.log("btn: ", btnNavStoreHome, "\nHash: ", hashPageStoreHome, "\nflag: ", flagInitialised); + initialiseEventHandler(btnNavStoreHome, flagInitialised, function() { + console.log("hooking up store home"); + console.log("btn: ", btnNavStoreHome, "\nHash: ", hashPageStoreHome); + btnNavStoreHome.on("click", function(event) { + event.stopPropagation(); + // setupPageLocalStorageNext(hashPageStoreHome); + goToPage(hashPageStoreHome); + }); + }); + + hookupSelectorCurrency(); + hookupSelectorDeliveryRegion(); + hookupCheckboxIsIncludedVAT(); +} + +function hookupOverlay(idOverlay) { + + initialiseEventHandler(idOverlay, flagInitialised, function() { + + let overlay = $(idOverlay) + + // close button + overlay.find('button.' + flagBtnOverlayClose).on("click", function(event) { + overlay.css('display', 'none'); + }); + }); +} + +function hookupSelectorCurrency() { + let elForm = $(idFormCurrency); + let elSelector = $(elForm.find('select')[0]); + initialiseEventHandler(elSelector, flagInitialised, function(){ + elForm = $(idFormCurrency); + elSelector.on("change", function(event) { + ajaxData = {}; + ajaxData[keyForm] = convertForm2JSON(elForm); + console.log('sending data to currency selector controller: '); console.log(ajaxData); + ajaxJSONData('select currency', mapHashToController(hashStoreSelectCurrency), ajaxData, function() { window.location.reload() }, false); + + let optionSelected = elSelector.options[elSelector.selectedIndex] + let textSelected = optionSelected.attr(attrDataShort) + + }); + }); + console.log("form currency initialised") +} +function hookupSelectorDeliveryRegion() { + let elForm = $(idFormDeliveryRegion); + let elSelector = $(elForm.find('select')[0]); + initialiseEventHandler(elSelector, flagInitialised, function(){ + elForm = $(idFormDeliveryRegion); + elSelector.on("change", function(event) { + ajaxData = {}; + ajaxData[keyForm] = convertForm2JSON(elForm); + console.log('sending data to delivery region selector controller: '); console.log(ajaxData); + ajaxJSONData('select delivery region', mapHashToController(hashStoreSelectDeliveryRegion), ajaxData, function() { window.location.reload() }, false); + }); + console.log("form delivery region initialised") + }); +} +function hookupCheckboxIsIncludedVAT() { + let elForm = $(idFormIsIncludedVAT); + let elSelector = $(elForm.find('input[type="checkbox"]')[0]); + initialiseEventHandler(elSelector, flagInitialised, function(){ + elForm = $(idFormIsIncludedVAT); + elSelector.on("change", function(event) { + ajaxData = {}; + ajaxData[keyForm] = convertForm2JSON(elForm); + console.log('sending data to include VAT controller: '); console.log(ajaxData); + ajaxJSONData('set include VAT', mapHashToController(hashStoreSetIsIncludedVAT), ajaxData, function() { window.location.reload() }, false); + }); + console.log("form is included VAT initialised") + }); +} + +// Argument validation +/* +function isNullOrWhitespace(v) { + let txt = JSON.stringify(v).replace('/\s\g', ''); + return (txt == '' || 'null'); +} +*/ + +function isEmpty(object) { + + let isEmpty = true; + + if (object !== null && object !== "null" && object !== undefined && object !== "undefined") { + + if (object.length == undefined) { + isEmpty = false; // object exists but isn't a collection + } + else if (typeof object === "function") { + isEmpty = false; // object is function reference + } + else { // string or collection + + let isString = (typeof object == "string"); + + if (isString) object = object.trim(); + + if (object.length > 0) { + + if (isString) { + isEmpty = false; // String greater than length 0 + } + else { + + if (typeof object[0] != "string") { + isEmpty = false; + } + else { + for(let i = 0; i < object.length; i++) { + if (object[i] != "") { + isEmpty = false; + break + } + } + } + } + } + } + } + + return isEmpty; +} + +function isValidNumber(value, positiveOnly) { + return !isEmpty(value) && !isNaN(value) && (!positiveOnly || parseFloat(value) > 0); +} + +function getDataContentType(params) { + + var data = null; + var contentType = ''; + + if (!isEmpty(params)) { + + if (typeof params === "string") { + data = params; + contentType = "application/x-www-form-urlencoded; charset=UTF-8"; + } + else { + data = JSON.stringify(params); + contentType = "application/json; charset=UTF-8"; + } + } + + return { Data: data, ContentType: contentType }; +} + +function arrayContainsItem(array, itemValue) { + + var hasItem = false; + + if (!isEmpty(array) && !isEmpty(itemValue)) { + + var isJQueryElementArray = array[0] instanceof jQuery; + + if (isJQueryElementArray) { + + for (let i = 0; i < array.length; i++) { + + if ($(array[i]).is(itemValue)) { + hasItem = true; + break; + } + } + } + else { + + var isDate = array[0] instanceof Date; + + if (isDate) { + + for (let i = 0; i < array.length; i++) { + + if (array[i].getTime() === itemValue.getTime()) { + hasItem = true; + break; + } + } + } + else { + + for (let i = 0; i < array.length; i++) { + + if (array[i] == itemValue) { + hasItem = true; + break; + } + } + } + } + } + + return hasItem; +} + +function dictHasKey(d, k) { + return (k in d); +} + +/* System Interation +AJAX + */ +function xmlJSONData(methodName, objJSON) { + + var xhr = new XMLHttpRequest(); + + // Specify post-request actions + xhr.onreadystatechange = function() { + if (xhr.readyState === 4 && xhr.status === 200) { + // Parse the JSON response + return JSON.parse(xhr.responseText); + } + }; + + // Specify request path + xhr.open('GET', '/' + methodName, true); + + // send request + xhr.send(); +} + +function ajaxJSONData(dataName, url, postData, successCallback, async) { + + if (isEmpty(async)) async = true; + let formattedParams = getDataContentType(postData); + + $.ajax({ + async: async, + type: 'POST', + cache: false, + url: url, + data: formattedParams.Data, + dataType: 'json', + contentType: formattedParams.ContentType, + success: function(result) { + if (result.Success) { + successCallback(result); + } + else { + alertError("Error", result.Message); + } + }, + error: function(xhr, ajaxOptions, thrownError) { + var errorMessage = "There was an error while getting the " + dataName + " data"; + alertError("Error", errorMessage); + } + }) +} + +function mapHashToController(hash) { + if (hash == null) return mapHashToController(hashPageHome); + + url = _pathHost; // + '/'; + console.log("url: " + url + "\nhash: " + hash); + return url + hash; + + switch (hash) { + case hashPageErrorNoPermission: + url += 'error'; + break; + case hashPageStoreHome: + url += 'store/home'; + break; + case hashPageStoreProduct: + url += 'store/product'; + break; + case hashStoreBasketLoad: + url += 'store/basket_load'; + break; + case hashStoreBasketAdd: + url += 'store/product'; + break; + default: + url += ''; + } + + return url; +} + +/* +function goToPage(pageHash, parameters) { + window.location.href = "{{ url_for(" + pageHash + (parameters == '' ? '' : ',' + parameters) + ") }}"; // getPageRoute(pageHash, parameters); +} +*/ +function goToPage(pageHash, parametersJSON) { + // window.location.href = "{{ url_for(" + pageHash + (parameters == '' ? '' : ',' + parameters) + ") }}"; // getPageRoute(pageHash, parameters); + // ajaxJSONData(pageHash, mapHashToController(pageHash), parameters, null, false); + url = mapHashToController(pageHash); + + + if (!isEmpty(parametersJSON)) { + url += '%3F'; // '?'; + let firstParameter = true; + for (var p in parametersJSON) { + // url += p + '=' + parametersJSON[p]; + if (!firstParameter) { + url += '&'; + } else { + firstParameter = false; + } + url += parametersJSON[p]; + } + } + + + window.location.href = url; + // ajaxJSONData(pageHash, url, parametersJSON, loadPageBody, false); +} + +function htmlEncode(value) { + return $('
').text(value).html(); +} + +var _domParser = null; +function htmlDecode(value) { + if (_domParser == null) _domParser = DOMParser(); // https://www.w3docs.com/snippets/javascript/how-to-html-encode-a-string.html + return _domParser.parseFromString(value, 'text/html').documentElement.textContent; +} + +function convertForm2JSON(elemForm) { + + formData = {} + + formDataTmp = elemForm.serializeArray(); + + $.each(formDataTmp, function(index, field) { + formData[field.name] = field.value; + /* + console.log('field name: ' + field.name); + console.log('field value: ' + field.value); + console.log('field currentval: ' + getElementCurrentValue(field)); + */ + }); + + return formData; +} + +function loadPageBody(response) { + + let pageBody = $(idPageBody); + + console.log('ajax:'); + console.log(response.data); + + pageBody.html(response.data['html_block']); +} + +/* Page elements */ +function initialiseEventHandler(elSelector, initialisedClass, eventHandler) { + + // only add once + var elObject = $(elSelector); + if (elObject.hasClass(initialisedClass)) return; + + // add event handler + eventHandler(); + + // flag as initialised + elObject.addClass(initialisedClass); +} + +function alertError(errorType, errorText) { + alert(errorType + '\n' + errorText); +} + +function setPageToLoading(isLoading) { + + if (isLoading) { + $(document.body).addClass(_dataLoadingFlag); + } + else { + $(document.body).removeClass(_dataLoadingFlag); + } +} + +function displayOverlay(message, show, force) { + + if (show) { + _overlayLoadingCount += 1; + } + else if (force) { + _overlayLoadingCount = 0; + } + else { + _overlayLoadingCount -= 1; + if (_overlayLoadingCount < 0) _overlayLoadingCount = 0; + } + + var loadingImg = $(idImageLoading); + var overlay = $(loadingImg.closest("div.overlay")); + + if (_overlayLoadingCount == 0) { + + // Prevent short glimpse of prev. content before switch to new content + // caused by data load but not fully rendered + setTimeout(function() { + overlay.fadeOut(); + }, 100); + } + else if (show && _overlayLoadingCount == 1) { + // only show once + loadingImg.html(message); + overlay.show(); + } +} + +function setBackgroundToLoading(elId, isLoading) { + + if (isEmpty(el)) { + + var elObj = $(elId); + + if (isLoading) { + + setTimeout(function() { + elObj.html(""); + elObj.css({ + "background-image": "url(" + urlImgLoading + ")", + "background-position": "center", + "background-repeat": "no-repeat" + }); + }, 0); + } + else { + elObj.css("background-image", ""); + } + } +} + +function allowClick() { + return !$("body").hasClass(_dataLoadingFlag); +} + +function imageExists(url, callback) { + + var img = new Image(); + + img.onload = function() { callback(true); }; + img.onerror = function() { callback(false); }; + img.src = url; +} + +function validateImageUrl(id, img) { + imageExists(img, function(exists) { + if (exists) { + $("#" + id).css({ "background-image": "url(" + url + ")", "background-size": "35px 35px"}) + } + }) +} + +function getElementCurrentValue(el) { + let returnVal = ''; + let element = $(el); + + if (!isEmpty(el)) { + + if (element.is("input:checkbox")) { + returnVal = (element.is(":checked")); + } + /* + else if (element.hasClass(flagIsDatePicker)) { + returnVal = getDatePickerDate(element, adjust4DayLightSavings); + } + */ + else if (element.is("input") || element.is("textarea") || element.is("select")) { + returnVal = element.val(); + } + else { + returnVal = element.text(); + } + } + + if (isEmpty(returnVal)) returnVal = ''; + + return returnVal; +} + +function parseCSSPropertyToFloat(element, propertyName) { + var propertyText = element.css(propertyName); + + if (!isEmpty(propertyText)) { + + propertyText = propertyText.replace('px', ''); + + if (!isValidNumber(propertyText, true)) return parseFloat(propertyText); + } + + return 0.00; +} + +function scrollToElement(parent, element) { + // REQUIRED: parent has scroll-bar + parent.scrollTop(parent.scrollTop() + (element.offset().top - parent.offset().top)); +} + +function isElementInContainer(container, element) { + + if (typeof jQuery === 'function') { + if (container instanceof jQuery) container = container[0]; + if (element instanceof jQuery) element = element[0]; + } + + var containerBounds = container.getBoundingClientRect(); + var elementBounds = element.getBoundingClientRect(); + + return ( + containerBounds.top <= elementBounds.top && + containerBounds.left <= elementBounds.left && + ((elementBounds.top + elementBounds.height) <= (containerBounds.top + containerBounds.height)) && + ((elementBounds.left + elementBounds.width) <= (containerBounds.left + containerBounds.width)) + ); +} + +// Date picker inputs +/* +function hookupInputDatePickers(dateInputs, notFuture, notPast, parent, addClearOption) { + + if (!isEmpty(dateInputs)) { + + let currentInput, currentDateString, currentDate, exceptionsArray; + + for (let i = 0; i < dateInputs.length; i++) { + + currentInput = $(dateInputs[i]); + currentDateString = currentInput.val(); + currentDate = (!isEmpty(currentDateString)) ? convertDDMMYYYYString2Date(currentDateString, false) : null; + exceptionsArray = (currentDate != null) ? [currentDate] : null; + + turnInputIntoDatePicker(currentInput, notFuture, notPast, exceptionsArray); + } + + if (!isEmpty(parent)) { + // stop user from manually typing date except backspace and delete + // which will clear the whole value to ensure we either have a whole + // date string or none + + parent.on("keydown", isDatePickerSelector, function(event) { + if (event.keyCode == 46 | event.keyCode == 8) { // delete or backspace + $(this).val(''); + } + else { + event.preventDefault(); + event.stopPropagation(); + } + + return false + }); + + if (addClearOption) { + + // if user right-clicks in date input, give option to clear the date + parent.contextMenu({ + selector: isDatePickerSelector, + delay: 100, + autoHide: true, + position: function(opt, x, y) { + var event = opt.$trigger[0]?.ownerDocument?.defaultView?.event || event; + opt.$menu.position({ my: 'center top', at: 'center top', of: event }); + }, + items: { + "clears": { + name: "Clear Date", + icon: "delete", + disabled: function(key, opt) { return isEmpty($(opt.$trigger)); }, // if it's already empty, don't do anything + callback: function(itemKey, opt, rootMenu, originalEvent) { var input = $(opt.$trigger); input.val(''); input.trigger('change'); } + } + } + }); + } + } + } +} + +function turnInputIntoDatePicker(input, notFuture, notPast, exceptionValueArray) { + + var beforeShowDayCallBack = null; + + if (notFuture || notPast) { + + var today = new Date(); + today.setHours(0, 0, 0, 0); + + var tomorrow = new Date(); + tomorrow.setDate(today.getDate() + 1); + tomorrow.setHours(0, 0, 0, 0); + + var hasExceptions = !isEmpty(exceptionValueArray); + + beforeShowDayCallBack = function(date) { + + var selectedDate = date.getTime(); + var fieldHasException = hasExceptions && arrayContainsItem(exceptionValueArray, date); + + if (notFuture && (tomorrow < selectedDate) && fieldHasException) return [false, 'redday', 'You cannot choose a future date']; + if (notPast && (selectedDate < today) && fieldHasException) return [false, 'redday', 'You cannot choose a past date']; + + return [true, '', '']; + }; + } + + input.datepicker({ + dateFormat: 'dd-mm-yy', + navigationAsDateFormat: true, + beforeShowDay: beforeShowDayCallBack + }); + + // prevent datepicker from appearing on right click + input.on('contextmenu', function() { $(this).datepicker('hide'); }); + + // Disable autocomplete suggestions appearing when clicking on input + input.attr('autocomplete', 'off'); +} + +function setDatePickerDate(input, objDate) { + if (!isEmpty(objDate)) { + input.val(''); + } + else { + input.datepicker('setDate', objDate); + } +} + +function getDatePickerDate(input, adjust4DayLightSavings) { + + var date = null; + + if (!isEmpty(input)) { + date = input.datepicker('getDate'); + + if (adjust4DayLightSavings) { + formatDateDayLightSavingsTime(date); + } + } + + return date; +} + +function formatDateDayLightSavingsTime(date) { + // JSON.stringify removes hour delta for daylight savings + // e.g. 13/11/2023 01:00:00 goes to 13/11/2023 00:00:00 + // this adds an hour so it becomes the correct time when stringified + if (!isEmpty(date)) { + date.setTime(date.getTime() - date.getTimezoneOffset() * 60 * 1000) + } +} +*/ +function convertJSONDateString2Date(dateStr) { + if (isEmpty(dateStr)) return null; + if (dateStr instanceof Date) return dateStr; + return new Date(parseInt(dateStr.substr(6))); +} + +function convertDDMMYYYYString2Date(dateStr, adjust4DayLightSavings) { + var date = null; + + if (!isEmpty(dateStr)) { + if (dateStr instanceof Date) { + date = dateStr; + } + else { + var dateParts = dateStr.split('-'); + + if (dateParts.length == 3) { + date = new Date(dateParts[2], dateParts[1] - 1, dateParts[0]); + } + } + + if (adjust4DayLightSavings && !isEmpty(date)) { + formatDateDayLightSavingsTime(date); + } + } + + return date; +} + +function convertDate2DDMMYYYYString(date) { + if (isEmpty(date)) return ''; + + try { + var dd = date.getDate(); + var mm = date.getMonth() + 1; + var yyyy = date.getFullYear(); + + if (dd < 10) dd = '0' + dd; + if (dd < 10) mm = '0' + mm; + + return dd + '-' + mm + '-' + yyyy; + } + catch (err) { + return 'Formatting error'; + } +} + +// Textareas +function removeBlankTextAreaLines(textarea) { + textarea.val(textarea.val.replace(/(?:(?:\r\n|\r|\n)\s*){2}/gm, '')); +} + +function fitTextAreasToContent(parent) { + var textareas = parent.find('textarea'); + + if (!isEmpty(textareas)) { + for (var t = 0; t < textareas.length; t++) { + fitTextAreaToContent($(textareas[t])); + } + } +} + +function fitTextAreaToContent(textarea) { + // Trim new text + var txtNew = textarea.val().trim(); + textarea.val(txtNew); + + var elTextarea = textarea[0]; + + // Clear style height and set rows = 1 + elTextarea.style.removeProperty('height'); + textarea.attr('rows', 1); + + const paddingTop = parseCSSPropertyToFloat(textarea, 'padding-top'); + const paddingBottom= parseCSSPropertyToFloat(textarea, 'padding-bottom'); + const borderTop = parseCSSPropertyToFloat(textarea, 'border-top'); + const borderBottom = parseCSSPropertyToFloat(textarea, 'border-bottom'); + let heightDelta = paddingTop + paddingBottom + borderTop + borderBottom; + let heightNew = elTextarea.scrollHeight + heightDelta; + + // If new height is less than 1 linem default to single line height + const heightSingleLine = parseCSSPropertyToFloat(textarea, 'line-height') + heightDelta; + if (heightNew < heightSingleLine) heightNew = heightSingleLine; + + elTextarea.style.height = heightNew + 'px'; +} + + +// Data tables +function getDataTableCellByNode(table, elRow, indexColumn) { + // normal jQuery selector won't pick up hidden columns + return $(table.DataTable().cells(elRow, indexColumn, null).nodes()); +} + +function outputTableElementDateInput(table, elRow, indexColumn, value) { + + let currentCell = getDataTableCellByNode(table, elRow, indexColumn); + + let dateTxt = ''; + + if (!isEmpty(value)) { + if (typeof value === 'string') value = convertJSONDateString2Date(value); + } +} + + +// Local storage +/* +function getPageLocalStorage(pageHash) { + + let ls; + try { + ls = JSON.parse(localStorage.getItem(pageHash)); + } catch { + + } + + if (isEmpty(ls)) return {} + + return ls; +} +function getPageLocalStorageCurrent() { + + return JSON.parse(localStorage.getItem(hashPageCurrent)); +} + +function setPageLocalStorage(pageHash, newLS) { + + localStorage.setItem(pageHash, JSON.stringify(newLS)); +} + +function clearPageLocalStorage(pageHash) { + localStorage.removeItem(pageHash); +} + +function setupPageLocalStorage(pageHash) { + + let ls = getPageLocalStorage(pageHash); + + if (isEmpty(ls)) ls = {}; + + setPageLocalStorage(pageHash, ls); +} +*/ + +function getLocalStorage(key) { + + return JSON.parse(localStorage.getItem(key)); +} + +function setLocalStorage(key, newLS) { + + localStorage.setItem(key, JSON.stringify(newLS)); +} + +/* +function setupPageLocalStorageNext(pageHashNext) { + let lsOld = getPageLocalStorage(hashPageCurrent); + hashPageCurrent = pageHashNext; + clearPageLocalStorage(hashPageCurrent); + setupPageLocalStorage(hashPageCurrent); + let lsNew = getPageLocalStorage(hashPageCurrent); + lsNew[keyBasket] = (keyBasket in lsOld) ? lsOld[keyBasket] : {'items': []}; + setPageLocalStorage(hashPageCurrent, lsNew); +} +*/ \ No newline at end of file diff --git a/static/js/store_admin.js b/static/js/store_admin.js new file mode 100644 index 00000000..d418eb39 --- /dev/null +++ b/static/js/store_admin.js @@ -0,0 +1,28 @@ +var _loading = true; + +function hookupPageStorePageAdmin() { + _loading = false; + + hookupBtnProductNew(); + hookupBtnPriceNew(); +} + +function hookupBtnProductNew() { + let btnProductNew = $(idBtnProductNew); + btnProductNew.removeClass(flagInitialised); + initialiseEventHandler(idBtnProductNew, flagInitialised, function() { + btnProductNew.on("click", function(event) { + goToPage(hashPageStoreProductNew); + }); + }); +} + +function hookupBtnPriceNew() { + let btnPriceNew = $(idBtnPriceNew); + btnPriceNew.removeClass(flagInitialised); + initialiseEventHandler(idBtnPriceNew, flagInitialised, function() { + btnPriceNew.on("click", function(event) { + goToPage(hashPageStorePriceNew); + }); + }); +} \ No newline at end of file diff --git a/static/js/store_home.js b/static/js/store_home.js new file mode 100644 index 00000000..f9c7a473 --- /dev/null +++ b/static/js/store_home.js @@ -0,0 +1,35 @@ +var _loading = true; + +function hookupStorePageHome() { + _loading = false; + + hookupStoreCardsProduct(); +} + +function hookupStoreCardsProduct() { + + let d; // , lsShared; + // let selectorCardProduct = '.card.subcard'; + $('div.card.subcard[' + attrIdProduct +']').each(function() { + + var product = $(this); + initialiseEventHandler(product, flagInitialised, function() { + product = $(product); + console.log("initialising product: ", product); + product.on("click", function(event) { + // d = { keyIdProduct: product.attr(attrIdProduct) } + var elemClicked = event.target; + if (elemClicked.id != 'submit') { // disable for submit buttons + console.log("product click: " + product.attr(attrIdProduct)); + console.log("permutation click: " + product.attr(attrIdPermutation)); + var d = {} + d[keyIdProduct] = product.attr(attrIdProduct) + d[keyIdPermutation] = product.attr(attrIdPermutation) + // send quantity requested + goToPage(hashPageStoreProduct, d); + } + }); + console.log("click method added for product ID: " + product.attr(attrIdProduct) + ', permutation ID: ', product.attr(attrIdPermutation)); + }); + }); +} diff --git a/static/js/store_page_basket.js b/static/js/store_page_basket.js new file mode 100644 index 00000000..1004f6cd --- /dev/null +++ b/static/js/store_page_basket.js @@ -0,0 +1,178 @@ +var _loading = true; + +function hookupStorePageBasket() { + _loading = false; + + hookupStoreCardsInfo(); + hookupOverlaysStoreBasketInfo(); + hookupBtnCheckoutSession(); +} + +function hookupStoreCardsInfo() { + + $(idContainerInfoDelivery).on("click", function(event) { + console.log("delivery modal display method"); + $(idOverlayInfoDelivery).css('display', 'block'); + }); + + $(idContainerInfoBilling).on("click", function(event) { + console.log("billing modal display method"); + $(idOverlayInfoBilling).css('display', 'block'); + }); +} + +function hookupOverlaysStoreBasketInfo() { + + let elOverlay, elForm; + + // Delivery + elOverlay = $(idOverlayInfoDelivery); + elForm = elOverlay.find('form'); + + hookupOverlay(elOverlay); + initialiseEventHandler(elForm, flagInitialised, function() { + elForm.submit(function(event) { + elForm = $(elForm); + event.preventDefault(); + console.log("delivery submit method"); + + ajaxData = {}; + ajaxData[keyInfoType] = keyInfoDelivery; + ajaxData = convertFormBilling2JSON(ajaxData, idOverlayInfoDelivery); + + ajaxJSONData('info delivery', mapHashToController(hashStoreBasketInfo), ajaxData, loadInfoAddress, false); + // $(idOverlayInfoDelivery).css('display', 'none'); + }); + }); + + // Billing + elOverlay = $(idOverlayInfoBilling); + elForm = elOverlay.find('form'); + + hookupOverlay(elOverlay); + initialiseEventHandler(elForm, flagInitialised, function() { + elForm.submit(function(event) { + event.preventDefault(); + console.log("billing submit method"); + + ajaxData = {}; + ajaxData[keyInfoType] = keyInfoBilling; + ajaxData = convertFormBilling2JSON(ajaxData, idOverlayInfoBilling); // formData; // form.serialize(); + + ajaxJSONData('info billing', mapHashToController(hashStoreBasketInfo), ajaxData, loadInfoAddress, false); + // $(idOverlayInfoBilling).css('display', 'none'); + }); + }); + let keys = [keyNameFull, keyPhoneNumber, keyPostcode, keyAddress1, keyCity, keyCounty]; + for (var k in keys) { + elForm.find('#' + keys[k]).removeAttr('required'); + } +} + +function loadInfoAddress(response) { + + console.log('ajax:'); console.log(response.data); + let infoType = response.data[keyInfoType]; + let infoAddress = response.data[infoType]; + setLocalStorage(infoType, infoAddress); + + // update webpage elements in background + if (infoType == keyInfoBilling) { + + let container = $(idContainerInfoBilling); + if (infoAddress[keyInfoIdentical]) { + container.find('div').html("Same as delivery address"); + } else { + container.find('div').html("" + infoAddress[keyNameFull] + ' at ' + infoAddress[keyPostcode] + ""); + } + + $(idOverlayInfoBilling).css('display', 'none'); + + $(idOverlayInfoBilling).find('form').addClass(flagSubmitted); + } else { + + let container = $(idContainerInfoDelivery); + container.find('div').html("" + infoAddress[keyNameFull] + ' at ' + infoAddress[keyPostcode] + ""); + + $(idOverlayInfoDelivery).css('display', 'none'); + + $(idOverlayInfoDelivery).find('form').addClass(flagSubmitted); + } +} + +function convertFormBilling2JSON(ajaxData, idOverlayInfo) { + + let elOverlay, elForm, elOverlayDelivery, elFormDelivery; + + elOverlay = $(idOverlayInfo); + elForm = elOverlay.find('form'); + elOverlay = $(idOverlayInfoDelivery); + elForm = elOverlay.find('form'); + + console.log('converting billing form to json\nform ID: ' + elForm.id); + ajaxData[keyForm] = convertForm2JSON(elForm); // formData; // form.serialize(); + let keys = [keyNameFull, keyPhoneNumber, keyPostcode, keyAddress1, keyAddress2, keyCity, keyCounty]; + console.log('ajaxData:'); + console.log(ajaxData); + ajaxData[keyForm][keyInfoIdentical] = getElementCurrentValue(elForm.find('#' + keyInfoIdentical)); + for (var k in keys) { + if (idOverlayInfo == idOverlayInfoBilling && ajaxData[keyForm][keyInfoIdentical]) { + ajaxData[keyForm][keys[k]] = getElementCurrentValue(elFormDelivery.find('#' + keys[k])); + } else { + ajaxData[keyForm][keys[k]] = getElementCurrentValue(elForm.find('#' + keys[k])); + } + } + console.log('ajaxData:'); + console.log(ajaxData); + return ajaxData; +} + +function hookupBtnCheckoutSession() { + let btnCheckout = $(idBtnCheckout); + btnCheckout.removeClass(flagInitialised); + initialiseEventHandler(idBtnCheckout, flagInitialised, function() { + + btnCheckout.off("click"); + btnCheckout.on("click", function(event) { + + + //setupPageLocalStorageNext(hashPageStoreBasket); + let basket = getLocalStorage(keyBasket); + // goToPage(hashPageStoreBasket); + let ajaxData = {}; + ajaxData[keyBasket] = basket; + ajaxData = convertFormBilling2JSON(ajaxData, idOverlayInfoDelivery); + ajaxData = convertFormBilling2JSON(ajaxData, idOverlayInfoBilling); + ajaxData[key_code_currency] = getCurrencySelected(); + // ajaxData[keyIsSubscription] = false; // only checkout one-time payment items for now + + ajaxJSONData('checkout session', mapHashToController(hashPageStoreCheckout), ajaxData, handleResponseCheckout, false); + }); + }); +} + +function handleResponseCheckout(response) { + // let tmpData = {}; + // tmpData[keyIdCheckout] = response.data[keyIdCheckout] + // goToPage(hashPageStoreCheckoutSession, tmpData); + window.location.href = response.data[keyUrlCheckout] +} + +function hookupBtnFormBillingCopy() { + + // let elBtn = $(idBtnFormBillingCopy); + + initialiseEventHandler(idBtnFormBillingCopy, flagInitialised, function() { + $(idBtnFormBillingCopy).on("click", function (event) { + + let keys = [keyNameFull, keyPhoneNumber, keyPostcode, keyAddress1, keyAddress2, keyCity, keyCounty]; + + let elFormBilling = $(idOverlayInfoBilling).find('form'); + let elFormDelivery = $(idOverlayInfoDelivery).find('form'); + + for (var k in keys) { + elFormBilling.find('#' + keys[k]).val(getElementCurrentValue(elFormDelivery.find('#' + keys[k]))); + } + }); + }); +} diff --git a/static/js/store_product.js b/static/js/store_product.js new file mode 100644 index 00000000..d0a6796b --- /dev/null +++ b/static/js/store_product.js @@ -0,0 +1,5 @@ +var _loading = true; + +function hookupStorePageProduct() { + _loading = false; +} diff --git a/static/js/store_shared.js b/static/js/store_shared.js new file mode 100644 index 00000000..693b0c47 --- /dev/null +++ b/static/js/store_shared.js @@ -0,0 +1,363 @@ + + +function hookupStore() { + console.log('hookup store start'); + console.log(_pathHost); + hookupLocalStorageStore(); + hookupBasket(); + hookupBtnsAdd2Basket(); +} + +function hookupBasket() { + + // const containerBasket = $(idContainerBasket); + + toggleShowBtnCheckout(); // containerBasket + hookupBtnCheckout(); + hookupBtnsPlusMinus(); + hookupBasketAddInputs(); + hookupBasketEditInputs(); + hookupBtnsDelete(); +} + +function hookupLocalStorageStore() { + + // setupPageLocalStorage(hashPageCurrent); + // let lsPage = getPageLocalStorage(hashPageCurrent); + // let d = {} + // d[keyBasket] = getLocalStorage(keyBasket); // (keyBasket in lsPage) ? lsPage[keyBasket] : {'items': []}; + // console.log('d:'); console.log(d); + let basket; + let createNewBasket = true; + if (true) { // !isUserLoggedIn) { + try { + basket = getLocalStorage(keyBasket); + console.log('basket found: '); console.log(basket); + createNewBasket = isEmpty(basket); + } + catch { + + } + // lsPage[keyBasket] = ajaxJSONData(keyBasket, hashStoreBasketLoad, d, loadBasket, false); + } + else { + // store basket from server in localStorage + + } + if (createNewBasket) { + basket = {'items': []}; + setLocalStorage(keyBasket, basket); + console.log("new local basket created"); + } + let ajaxData = {} + ajaxData[keyBasket] = basket; + // console.log('ajax:' + ajaxData); + ajaxJSONData(keyBasket, mapHashToController(hashStoreBasketLoad), ajaxData, loadBasket, false); +} + +/* +function setupPageLocalStorageNextStore(pageHashNext) { + let lsOld = getPageLocalStorage(hashPageCurrent); + hashPageCurrent = pageHashNext; + clearPageLocalStorage(hashPageCurrent); + setupPageLocalStorage(hashPageCurrent); + let lsNew = getPageLocalStorage(hashPageCurrent); + lsNew[keyBasket] = (keyBasket in lsOld) ? lsOld[keyBasket] : {'items': []}; + setPageLocalStorage(hashPageCurrent, lsNew); +} + +function goToPageStore(pageHash, parameters_dict) { + + let lsOld = getPageLocalStorage(pageHashCurrent); + pageHashCurrent = pageHash; + clearPageLocalStorage(pageHashCurrent); + setupPageLocalStorage(pageHashCurrent); + let lsNew = getPageLocalStorage(pageHashCurrent); + lsNew[keyBasket] = (keyBasket in lsOld) ? lsOld[keyBasket] : {'items': []}; + setPageLocalStorage(pageHashCurrent, lsNew); + + goToPage(pageHash, parameters_dict); +} +*/ + +function toggleShowBtnCheckout() { // containerBasket + + console.log("toggling checkout button"); + + const btnCheckout = $(idBtnCheckout); + const labelBasketEmpty = $(idLabelBasketEmpty); + + // let lsPage = getPageLocalStorage(hashPageCurrent); + // let basket = lsPage[keyBasket]['items']; + // let products = containerBasket.filter(''); + let basket = getLocalStorage(keyBasket); + + if (basket['items'].length == 0) { + btnCheckout.hide(); + labelBasketEmpty.show(); + } else { + btnCheckout.show(); + labelBasketEmpty.hide(); + } +} + +/* +function getBasket() { + + lsShared = getPageLocalStorage(keyShared); + + return lsShared[keyBasket]; +} +*/ + +function hookupBtnsAdd2Basket() { + + // let product, btn, lsPage; + // [' + attrIdProduct + '=' + elBtn.attr(attrIdProduct) + '] + $('form[' + attrFormType + '="' + typeFormBasketAdd +'"]').each(function() { + + var form = $(this); + + initialiseEventHandler(form, flagInitialised, function() { + // form = $(form); + form.submit(function(event) { + event.preventDefault(); + + // lsShared = getPageLocalStorage(keyShared); + console.log("adding to basket for product ID: ", form.attr(attrIdProduct)); + + ajaxData = {}; + ajaxData[keyIdProduct] = form.attr(attrIdProduct); + ajaxData[keyIdPermutation] = form.attr(attrIdPermutation); + basket = getLocalStorage(keyBasket); + ajaxData[keyBasket] = basket; // lsShared[keyBasket]; + console.log("basket before add: ", basket); + ajaxData[keyForm] = convertForm2JSON(form); // formData; // form.serialize(); + console.log("ajax data:"); console.log(ajaxData); + ajaxJSONData('add2Basket', mapHashToController(hashStoreBasketAdd), ajaxData, loadBasket, false); // { product_id: form.attr(attrIdProduct), basket_local: lsPage[keyBasket] , } + }); + console.log("basket add method added for product ID: ", form.attr(attrIdProduct)); + }); + }); +} + +function hookupBtnCheckout() { + + console.log("hooking up checkout button"); + + const btnCheckout = $(idBtnCheckout); + // let lsPage = getPageLocalStorage(hashPageCurrent); + initialiseEventHandler(btnCheckout, flagInitialised, function() { + btnCheckout.on("click", function() { + /* + //setupPageLocalStorageNext(hashPageStoreBasket); + let basket = getLocalStorage(keyBasket); + // goToPage(hashPageStoreBasket); + let ajaxData = {}; + ajaxData[keyBasket] = basket; + + ajaxJSONData('checkout', mapHashToController(hashPageStoreBasket), ajaxData, null, false); + */ + goToPage(hashPageStoreBasket); + }); + }); +} + +function loadBasket(response) { + + let basketContainer = $(idBasketContainer); + // let lsPage = getPageLocalStorage(hashPageCurrent); + // let lsShared = getPageLocalStorage(keyShared); + + console.log('ajax:'); console.log(response.data); + + let basket = response.data[keyBasket]; // JSON.parse(response.data[keyBasket]); + // setPageLocalStorage(keyShared, lsShared); + setLocalStorage(keyBasket, basket); + items = basket['items']; + // console.log('old basket:'); console.log(basketContainer.html()); + // console.log('setting basket:'); console.log(response.data['html_block']); + basketContainer.html(response.data['html_block']); + + /* + if (items.length > 0) { + let basketItem; + for (let indexItemBasket = 0; indexItemBasket < items.length; indexItemBasket++) { + basketItem = items[indexItemBasket]; + if (basketItem[keyQuantity] > 1) { + elInput = basketContainer.find('form[' + attrFormType + '=' + typeFormBasketEdit + ']').find('input[type="number"]'); + // todo : what is missing? + elInput.val(basketItem[keyQuantity]); + } + } + } + */ + + hookupBasket(); +} + +function getFormProductSelector(typeForm, elementInForm) { + idPermutation = elementInForm.attr(attrIdPermutation); + console.log('idPermutation: ', idPermutation); + hasPermutation = !isEmpty(idPermutation); + console.log('has permutation: ', hasPermutation); + selectorIdPermutation = hasPermutation ? '[' + attrIdPermutation + '=' + idPermutation + ']' : ''; + return 'form[' + attrFormType + '="' + typeForm + '"][' + attrIdProduct + '=' + elementInForm.attr(attrIdProduct) + ']' + selectorIdPermutation; +} + +function hookupBtnsPlusMinus() { + + // let elBtn, elInput, newVal, product; + const minVal = 1; + // Basket Add + // Increment + $('div.btn-increment[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() { + let elBtn = $(this); + initialiseEventHandler(elBtn, flagInitialised, function(){ + elBtn.on("click", function(event) { + event.preventDefault(); + event.stopPropagation(); + let elInput = $(getFormProductSelector(typeFormBasketAdd, elBtn)).find('input[type="number"]'); + // console.log('input selector ='); console.log('form[' + attrFormType + '=' + elBtn.attr(attrFormType) + '][' + attrIdProduct + '=' + elBtn.attr(attrIdProduct) + ']'); + let newVal = parseInt(getElementCurrentValue(elInput)); + if (isNaN(newVal)) newVal = minVal; + newVal += 1; + elInput.val(newVal); + }); + }); + }); + // Decrement + $('div.btn-decrement[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() { + let elBtn = $(this); + initialiseEventHandler(elBtn, flagInitialised, function(){ + elBtn.on("click", function(event) { + event.preventDefault(); + event.stopPropagation(); + // let product = $('.card.subcard[' + attrIdProduct +'=' + elBtn.attr(attrIdProduct) + ']'); + let elInput= $(getFormProductSelector(typeFormBasketAdd, elBtn)).find('input[type="number"]'); + let newVal = parseInt(getElementCurrentValue(elInput)); + if (isNaN(newVal)) newVal = minVal; + newVal = Math.max(minVal, newVal - 1); + elInput.val(newVal); + }); + }); + }); + + // Basket Edit + // Increment + $('div.btn-increment[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() { + let elBtn = $(this); + initialiseEventHandler(elBtn, flagInitialised, function(){ + elBtn.on("click", function(event) { + event.stopPropagation(); + // basketItem = $('.card.subcard[' + attrIdProduct +'=' + elBtn.attr(attrIdProduct) + ']'); + let elInput = $(getFormProductSelector(typeFormBasketEdit, elBtn)).find('input[type="number"]'); + // console.log('input selector ='); console.log('form[' + attrFormType + '=' + elBtn.attr(attrFormType) + '][' + attrIdProduct + '=' + elBtn.attr(attrIdProduct) + ']'); + let newVal = parseInt(getElementCurrentValue(elInput)); + if (isNaN(newVal)) newVal = minVal; + newVal += 1; + elInput.val(newVal); + elInput.trigger("change"); + }); + }); + }); + // Decrement + $('div.btn-decrement[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() { + let elBtn = $(this); + initialiseEventHandler(elBtn, flagInitialised, function(){ + elBtn.on("click", function(event) { + event.stopPropagation(); + let elInput= $(getFormProductSelector(typeFormBasketEdit, elBtn)).find('input[type="number"]'); + let newVal = parseInt(getElementCurrentValue(elInput)); + if (isNaN(newVal)) newVal = minVal; + newVal = Math.max(minVal, newVal - 1); + elInput.val(newVal); + elInput.trigger("change"); + }); + }); + }); +} + +function hookupBasketAddInputs() { + + $('form[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() { + let elForm = $(this); + let elInput = elForm.find('input[type="number"]'); + initialiseEventHandler(elInput, flagInitialised, function(){ + elInput.on("change", function(event) { + event.preventDefault(); + event.stopPropagation(); + }); + elInput.on("click", function(event) { + event.preventDefault(); + event.stopPropagation(); + }); + }); + }); +} + +function hookupBasketEditInputs() { + + // let elBtn, elInput, newVal, product; + const minVal = 1; + // Basket Edit + // Increment + $('form[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() { + let elForm = $(this); + let elInput = elForm.find('input[type="number"]'); + initialiseEventHandler(elInput, flagInitialised, function(){ + elInput.on("change", function(event) { + event.preventDefault(); + event.stopPropagation(); + // let lsPage = getPageLocalStorageCurrent(); + d = {}; + d[keyBasket]= getLocalStorage(keyBasket); // lsPage[keyBasket]; // JSON.parse(lsPage[keyBasket]); + d[keyIdProduct] = elForm.attr(attrIdProduct); // lsPage[keyIdProduct]; + d[keyIdPermutation] = elForm.attr(attrIdPermutation); + // d[keyQuantity] = lsPage[keyQuantity]; + d[keyForm] = convertForm2JSON(elForm); + d[keyForm][keyQuantity] = elInput.val(); + console.log('sending data to basket edit controller: '); console.log(d); + ajaxJSONData('basket update', mapHashToController(hashStoreBasketEdit), d, loadBasket, false); + }); + }); + }); +} + +function hookupBtnsDelete() { + + console.log('hooking up basket item delete buttons'); + // let elForm, elDelete; + // const minVal = 1; + // Basket Add + // Increment + $('form[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() { + let elForm = $(this); + let elDelete = elForm.find('a.' + flagBasketItemDelete); + initialiseEventHandler(elDelete, flagInitialised, function(){ + elDelete.on("click", function(event) { + event.stopPropagation(); + ajaxData = {}; + ajaxData[keyBasket]= getLocalStorage(keyBasket); + ajaxData[keyIdProduct] = elForm.attr(attrIdProduct); + ajaxData[keyIdPermutation] = elForm.attr(attrIdPermutation); + console.log('sending data to basket delete controller: '); console.log(ajaxData); + ajaxJSONData('basket update', mapHashToController(hashStoreBasketDelete), ajaxData, loadBasket, false); + }); + }); + }); +} + +function getCurrencySelected() { + let elementSelectorCurrency = $(idSelectorCurrency); + let selectedCurrency = elementSelectorCurrency.val(); + console.log("selected currency: ", selectedCurrency); + return selectedCurrency; +} + +function addMetadataBasketToJSON(jsonData) { + jsonData[keyIdCurrency] = getLocalStorage(keyIdCurrency); + jsonData[keyIdRegionDelivery] = getLocalStorage(keyIdRegionDelivery); + jsonData[keyIsIncludedVAT] = getLocalStorage(keyIsIncludedVAT); + return jsonData; +} \ No newline at end of file diff --git a/static/js/stripe.js b/static/js/stripe.js new file mode 100644 index 00000000..118f776b --- /dev/null +++ b/static/js/stripe.js @@ -0,0 +1 @@ +var key_pub = 'pk_test_51OGrxlL7BuLKjoMpfpfw7bSmZZK1MhqMoQ5VhW2jUj7YtoEejO4vqnxKPiqTHHuh9U4qqkywbPCSI9TpFKtr4SYH007KHMWs68'; diff --git a/static/python/rename_files.py b/static/python/rename_files.py new file mode 100644 index 00000000..0a9202d2 --- /dev/null +++ b/static/python/rename_files.py @@ -0,0 +1,21 @@ +import os + +dir_parent = os.path.abspath(__file__ + '/../..') +dir_sql = os.path.abspath(dir_parent + '/sql') + + +# METHODS +for entry in os.scandir(dir_sql): + if entry.is_file(): + if '_tbl_' in entry.name: + + new_name = entry.name + i_underscore = 6 + while i_underscore > 0: + i_underscore = new_name.find('_', i_underscore + 1) + new_name = new_name[:i_underscore + 1] + new_name[i_underscore + 1].upper() + new_name[i_underscore + 2:] + os.rename(entry.path, dir_sql + '/' + new_name) + if entry.is_dir(): + pass + +# SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Msg_Error_Type'; \ No newline at end of file diff --git a/static/sql/000_combine.sql b/static/sql/000_combine.sql new file mode 100644 index 00000000..9a6d6753 --- /dev/null +++ b/static/sql/000_combine.sql @@ -0,0 +1,8395 @@ + +/* Clear Store DataBase */ +USE PARTS; + + +# Drop dependencies +DROP TABLE IF EXISTS Shop_User_Eval_Temp; +DROP TABLE IF EXISTS tmp_Msg_Error; +DROP TABLE IF EXISTS tmp_Currency; +DROP TABLE IF EXISTS tmp_Delivery_Region; +DROP TABLE IF EXISTS tmp_Region; +DROP TABLE IF EXISTS tmp_Shop_User; +DROP TABLE IF EXISTS tmp_Shop_Order; +DROP TABLE IF EXISTS tmp_Shop_Product; +DROP TABLE IF EXISTS tmp_Shop_Product_p_Shop_User_Eval; +DROP TABLE IF EXISTS tmp_Shop_Image; +DROP TABLE IF EXISTS tmp_Shop_Variation; +DROP TABLE IF EXISTS tmp_Shop_Discount; +DROP TABLE IF EXISTS tmp_Discount; +DROP TABLE IF EXISTS tmp_Shop_Category; +DROP TABLE IF EXISTS tmp_Shop_Product_Currency_Region_Link; +DROP TABLE IF EXISTS tmp_Shop_Product_Currency_Link; +DROP TABLE IF EXISTS tmp_User_Role_Link; +DROP TABLE IF EXISTS tmp_Shop_Basket; + + +# Delete old tables +DROP TABLE IF EXISTS Shop_User_Order_Product_Link_Audit; +DROP TABLE IF EXISTS Shop_User_Order_Product_Link; + +DROP TABLE IF EXISTS Shop_User_Order_Audit; +DROP TABLE IF EXISTS Shop_User_Order; + +DROP TABLE IF EXISTS Shop_User_Order_Status_Audit; +DROP TABLE IF EXISTS Shop_User_Order_Status; + +DROP TABLE IF EXISTS Shop_User_Basket_Audit; +DROP TABLE IF EXISTS Shop_User_Basket; + +DROP TABLE IF EXISTS Shop_Address_Audit; +DROP TABLE IF EXISTS Shop_Address; + +DROP TABLE IF EXISTS Shop_User_Role_Link_Audit; +DROP TABLE IF EXISTS Shop_User_Role_Link; + +DROP TABLE IF EXISTS Shop_User_Audit; +DROP TABLE IF EXISTS Shop_User; + +DROP TABLE IF EXISTS Shop_Role_Permission_Link_Audit; +DROP TABLE IF EXISTS Shop_Role_Permission_Link; + +DROP TABLE IF EXISTS Shop_Role_Audit; +DROP TABLE IF EXISTS Shop_Role; + +DROP TABLE IF EXISTS Shop_Permission_Audit; +DROP TABLE IF EXISTS Shop_Permission; + +DROP TABLE IF EXISTS Shop_Permission_Group_Audit; +DROP TABLE IF EXISTS Shop_Permission_Group; + + +DROP TABLE IF EXISTS Shop_Discount_Region_Currency_Link_Audit; +DROP TABLE IF EXISTS Shop_Discount_Region_Currency_Link; + +DROP TABLE IF EXISTS Shop_Discount_Audit; +DROP TABLE IF EXISTS Shop_Discount; + +DROP TABLE IF EXISTS Shop_Product_Delivery_Option_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Delivery_Option_Link; + +DROP TABLE IF EXISTS Shop_Delivery_Option_Audit; +DROP TABLE IF EXISTS Shop_Delivery_Option; + +DROP TABLE IF EXISTS Shop_Image_Audit; +DROP TABLE IF EXISTS Shop_Image; + +DROP TABLE IF EXISTS Shop_Image_Type_Audit; +DROP TABLE IF EXISTS Shop_Image_Type; + +DROP TABLE IF EXISTS Shop_Product_Currency_Region_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Currency_Region_Link; +DROP TABLE IF EXISTS Shop_Product_Currency_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Currency_Link; + +DROP TABLE IF EXISTS Shop_Product_Variation_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Variation_Link; +DROP TABLE IF EXISTS Shop_Product_Permutation_Variation_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Permutation_Variation_Link; + +DROP TABLE IF EXISTS Shop_Product_Permutation_Audit; +DROP TABLE IF EXISTS Shop_Product_Permutation; + +DROP TABLE IF EXISTS Shop_Variation_Audit; +DROP TABLE IF EXISTS Shop_Variation; +DROP TABLE IF EXISTS Shop_Product_Variation_Type_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Variation_Type_Link; + +DROP TABLE IF EXISTS Shop_Variation_Type_Audit; +DROP TABLE IF EXISTS Shop_Variation_Type; + +DROP TABLE IF EXISTS Shop_Product_Audit; +DROP TABLE IF EXISTS Shop_Product; + +DROP TABLE IF EXISTS Shop_Tax_Or_Surcharge_Audit; +DROP TABLE IF EXISTS Shop_Tax_Or_Surcharge; + +DROP TABLE IF EXISTS Shop_Currency_Audit; +DROP TABLE IF EXISTS Shop_Currency; + +DROP TABLE IF EXISTS Shop_Delivery_Region_Branch_Audit; +DROP TABLE IF EXISTS Shop_Delivery_Region_Branch; +DROP TABLE IF EXISTS Shop_Region_Branch_Audit; +DROP TABLE IF EXISTS Shop_Region_Branch; + +DROP TABLE IF EXISTS Shop_Delivery_Region_Audit; +DROP TABLE IF EXISTS Shop_Delivery_Region; +DROP TABLE IF EXISTS Shop_Region_Audit; +DROP TABLE IF EXISTS Shop_Region; + +DROP TABLE IF EXISTS Shop_Recurrence_Interval_Audit; +DROP TABLE IF EXISTS Shop_Recurrence_Interval; + +DROP TABLE IF EXISTS Shop_Category_Audit; +DROP TABLE IF EXISTS Shop_Category; + +DROP TABLE IF EXISTS Shop_General_Audit; +DROP TABLE IF EXISTS Shop_General; + +DROP TABLE IF EXISTS File_Type_Audit; +DROP TABLE IF EXISTS File_Type; + +DROP TABLE IF EXISTS Msg_Error_Type; + +DROP TABLE IF EXISTS Shop_Access_Level_Audit; +DROP TABLE IF EXISTS Shop_Access_Level; + +DROP TABLE IF EXISTS Shop_User_Change_Set; + +DROP TABLE IF EXISTS Shop_Msg_Error_Type; + +DROP TABLE IF EXISTS Shop_Product_Change_Set; + +# Product Change Sets + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Change_Set'; + +CREATE TABLE Shop_Product_Change_Set ( + id_change_set INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + comment VARCHAR(500), + updated_last_on DATETIME, + updated_last_by VARCHAR(100) +); +# User Change Sets + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Change_Set'; + +CREATE TABLE IF NOT EXISTS Shop_User_Change_Set ( + id_change_set INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + comment VARCHAR(500), + updated_last_on DATETIME, + updated_last_by VARCHAR(100) +); +# Access Levels + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Access_Level'; + +CREATE TABLE IF NOT EXISTS Shop_Access_Level ( + id_access_level INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + priority INT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Access_Level_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); +# Access Level Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Access_Level_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Access_Level_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_access_level INT NOT NULL, + CONSTRAINT FK_Shop_Access_Level_Audit_id_access_level + FOREIGN KEY (id_access_level) + REFERENCES Shop_Access_Level(id_access_level) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Access_Level_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); +# Error Message Type + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Msg_Error_Type'; + +CREATE TABLE IF NOT EXISTS Shop_Msg_Error_Type ( + id_type INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(500) NOT NULL, + description VARCHAR(1000) +); + +# File Types + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'File_Type'; + +CREATE TABLE IF NOT EXISTS File_Type ( + id_type INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(100), + extension VARCHAR(50), + created_on DATETIME, + created_by VARCHAR(100), + updated_last_on DATETIME, + updated_last_by VARCHAR(100) +); + +# File Type Audit + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'File_Type_Audit'; + +CREATE TABLE IF NOT EXISTS File_Type_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_File_Type_Audit_id_type + FOREIGN KEY (id_type) + REFERENCES File_Type(id_type) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + created_on DATETIME, + created_by VARCHAR(100), + updated_last_on DATETIME, + updated_last_by VARCHAR(100) +); +# Generic / shared properties + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_General'; + +CREATE TABLE IF NOT EXISTS Shop_General ( + id_general INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + quantity_max FLOAT, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT CHK_Shop_General_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Shop General Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_General_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_General_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_general INT NOT NULL, + CONSTRAINT FK_Shop_General_Audit_id_general + FOREIGN KEY (id_general) + REFERENCES Shop_General(id_general) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_General_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Categories + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Category'; + +CREATE TABLE IF NOT EXISTS Shop_Category ( + id_category INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + description VARCHAR(4000), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Category_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Category Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Category_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Category_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_category INT NOT NULL, + CONSTRAINT FK_Shop_Category_Audit_id_category + FOREIGN KEY (id_category) + REFERENCES Shop_Category(id_category) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Category_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Recurrence Interval + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Recurrence_Interval'; + +CREATE TABLE IF NOT EXISTS Shop_Recurrence_Interval ( + id_interval INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + name_plural VARCHAR(256), + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Recurrence_Interval_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Recurrence Interval Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Recurrence_Interval_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Recurrence_Interval_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_interval INT NOT NULL, + CONSTRAINT FK_Shop_Recurrence_Interval_Audit_id_interval + FOREIGN KEY (id_interval) + REFERENCES Shop_Recurrence_Interval(id_interval) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(256), + value_new VARCHAR(256), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Recurrence_Interval_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Regions + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Region'; + +CREATE TABLE IF NOT EXISTS Shop_Region ( + id_region INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(200) NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Region_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Region Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Region_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Region_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_region INT NOT NULL, + CONSTRAINT FK_Shop_Region_Audit_id_region + FOREIGN KEY (id_region) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + name_field VARCHAR(64) NOT NULL, + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Region_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Region Branchs + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Region_Branch'; + +CREATE TABLE IF NOT EXISTS Shop_Region_Branch ( + id_branch INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_region_parent INT NOT NULL, + CONSTRAINT FK_Shop_Region_Branch_id_region_parent + FOREIGN KEY (id_region_parent) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + id_region_child INT NOT NULL, + CONSTRAINT FK_Shop_Region_Branch_id_region_child + FOREIGN KEY (id_region_child) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + -- depth INT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Region_Branch_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Region Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Region_Branch_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Region_Branch_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_branch INT NOT NULL, + CONSTRAINT FK_Shop_Region_Branch_Audit_id_branch + FOREIGN KEY (id_branch) + REFERENCES Shop_Region_Branch(id_branch) + ON UPDATE RESTRICT, + name_field VARCHAR(64) NOT NULL, + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Region_Branch_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Currencies + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Currency'; + +CREATE TABLE IF NOT EXISTS Shop_Currency ( + id_currency INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(255) NOT NULL, + symbol VARCHAR(1) NOT NULL, + factor_from_GBP FLOAT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Currency_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); +# Currency Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Currency_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Currency_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_currency INT NOT NULL, + CONSTRAINT FK_Shop_Currency_Audit_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Currency_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); +# Taxes and Surcharges + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Tax_Or_Surcharge'; + +CREATE TABLE Shop_Tax_Or_Surcharge ( + id_tax INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(200) NOT NULL, + id_region_buyer INT NOT NULL, + CONSTRAINT FK_Shop_Tax_Or_Surcharge_id_region_buyer + FOREIGN KEY (id_region_buyer) + REFERENCES Shop_Region(id_region), + id_region_seller INT NOT NULL, + CONSTRAINT FK_Shop_Tax_Or_Surcharge_id_region_seller + FOREIGN KEY (id_region_seller) + REFERENCES Shop_Region(id_region), + id_currency INT, + CONSTRAINT FK_Shop_Tax_Or_Surcharge_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + fixed_fee FLOAT NOT NULL DEFAULT 0, + multiplier FLOAT NOT NULL DEFAULT 1 CHECK (multiplier > 0), + apply_fixed_fee_before_multiplier BIT DEFAULT 1, + quantity_min FLOAT NOT NULL DEFAULT 0, + quantity_max FLOAT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Tax_Or_Surcharge_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Tax Or Surcharge Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Tax_Or_Surcharge_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Tax_Or_Surcharge_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_tax INT NOT NULL, + CONSTRAINT FK_Shop_Tax_Or_Surcharge_Audit_id_discount + FOREIGN KEY (id_tax) + REFERENCES Shop_Tax_Or_Surcharge(id_tax) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Tax_Or_Surcharge_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); +# Products + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product'; + +CREATE TABLE IF NOT EXISTS Shop_Product ( + id_product INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL, + -- description VARCHAR(4000), + id_category INT NOT NULL, + has_variations BIT NOT NULL, + /* + price_GBP_full FLOAT, + price_GBP_min FLOAT, + # ratio_discount_overall FLOAT NOT NULL DEFAULT 0, + CONSTRAINT FK_Shop_Product_id_category + FOREIGN KEY (id_category) + REFERENCES Shop_Category(id_category) + ON UPDATE RESTRICT, + latency_manuf INT, + quantity_min FLOAT, + quantity_max FLOAT, + quantity_step FLOAT, + quantity_stock FLOAT, + is_subscription BIT, + id_recurrence_interval INT, + CONSTRAINT FK_Shop_Product_id_recurrence_interval + FOREIGN KEY (id_recurrence_interval) + REFERENCES Shop_Recurrence_Interval(id_interval), + count_recurrence_interval INT, + */ + id_access_level_required INT NOT NULL, + CONSTRAINT FK_Shop_Product_id_access_level_required + FOREIGN KEY (id_access_level_required) + REFERENCES Shop_Access_Level(id_access_level), + # id_stripe_product VARCHAR(100), + # id_stripe_price VARCHAR(100) NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Products + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Audit_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Variation Types + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Variation_Type'; + +CREATE TABLE IF NOT EXISTS Shop_Variation_Type ( + id_type INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + name_plural VARCHAR(256), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Variation_Type_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Variation Type Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Variation_Type_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Variation_Type_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_Shop_Variation_Type_Audit_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Variation_Type(id_type) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Variation_Type_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Variations + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Variation'; + +CREATE TABLE Shop_Variation ( + id_variation INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_Shop_Variation_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Variation_Type(id_type) + ON UPDATE RESTRICT, + code VARCHAR(50), + name VARCHAR(255), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Variation_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Variation Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Variation_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Variation_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_variation INT NOT NULL, + CONSTRAINT FK_Shop_Variation_Audit_id_variation + FOREIGN KEY (id_variation) + REFERENCES Shop_Variation(id_variation) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Variation_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Product Permutation + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Permutation'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Permutation ( + id_permutation INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Variation_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + -- name VARCHAR(255) NOT NULL, + description VARCHAR(4000) NOT NULL, + cost_local_manufacturing FLOAT NOT NULL, + id_currency_cost_manufacturing INT NOT NULL, + profit_local_min FLOAT NOT NULL, + id_currency_profit_min INT NOT NULL, + latency_manufacture INT NOT NULL, + quantity_min FLOAT NOT NULL, + quantity_max FLOAT NOT NULL, + quantity_step FLOAT NOT NULL, + quantity_stock FLOAT NOT NULL, + is_subscription BIT NOT NULL, + id_recurrence_interval INT, + CONSTRAINT FK_Shop_Product_Permutation_id_recurrence_interval + FOREIGN KEY (id_recurrence_interval) + REFERENCES Shop_Recurrence_Interval(id_interval), + count_recurrence_interval INT, + id_access_level_required INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_id_access_level_required + FOREIGN KEY (id_access_level_required) + REFERENCES Shop_Access_Level(id_access_level), + id_stripe_product VARCHAR(100) NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Variation_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Product Permutation Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Permutation_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Permutation_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_permutation INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_Audit_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); + +# Product Permutation Variation Link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Permutation_Variation_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Permutation_Variation_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_permutation INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + id_variation INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_id_variation + FOREIGN KEY (id_variation) + REFERENCES Shop_Variation(id_variation) + ON UPDATE RESTRICT, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Product Permutation Variation Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Permutation_Variation_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Permutation_Variation_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Permutation_Variation_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); +# Product Currency link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Currency_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Currency_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_permutation INT NULL, + CONSTRAINT FK_Shop_Product_Currency_Link_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + id_currency INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Link_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + id_region_purchase INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Link_id_region_purchase + FOREIGN KEY (id_region_purchase) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + price_local_VAT_incl FLOAT NULL, + price_local_VAT_excl FLOAT NULL, + id_stripe_price VARCHAR(200), + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Currency_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Product Currency Region link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Currency_Region_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Currency_Region_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_permutation INT NULL, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + id_currency INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + id_region_purchase INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_region_purchase + FOREIGN KEY (id_region_purchase) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + price_local_VAT_incl FLOAT NULL, + price_local_VAT_excl FLOAT NULL, + id_stripe_price VARCHAR(200), + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Product Currency Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Currency_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Currency_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Currency_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Product Currency Region Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Currency_Region_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Currency_Region_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Currency_Region_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Image Types + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Image_Type'; + +CREATE TABLE IF NOT EXISTS Shop_Image_Type ( + id_type INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + name_plural VARCHAR(256), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Image_Type_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Image Type Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Image_Type_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Image_Type_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_Shop_Image_Type_Audit_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Image_Type(id_type) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Image_Type_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Images + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Image'; + +CREATE TABLE IF NOT EXISTS Shop_Image ( + id_image INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type_image INT NOT NULL, + CONSTRAINT FK_Shop_Image_id_type_image + FOREIGN KEY (id_type_image) + REFERENCES Shop_Image_Type(id_type), + id_type_file INT NOT NULL, + CONSTRAINT FK_Shop_Image_id_type_file + FOREIGN KEY (id_type_file) + REFERENCES File_Type(id_type), + id_product INT NULL, + CONSTRAINT FK_Shop_Image_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NULL, + CONSTRAINT FK_Shop_Image_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + url VARCHAR(255), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Image_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Image Type Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Image_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Image_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_image INT NOT NULL, + CONSTRAINT FK_Shop_Image_Audit_id_image + FOREIGN KEY (id_image) + REFERENCES Shop_Image(id_image), + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Image_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Delivery Options + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Delivery_Option'; + +CREATE TABLE IF NOT EXISTS Shop_Delivery_Option ( + id_option INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(100) NOT NULL, + description VARCHAR(4000), + latency_delivery_min INT NOT NULL, + latency_delivery_max INT NOT NULL, + quantity_min INT NOT NULL, + quantity_max INT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Delivery_Option_Type_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Delivery Option Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Delivery_Option_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Delivery_Option_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_option INT NOT NULL, + CONSTRAINT FK_Shop_Delivery_Option_Audit_id_option + FOREIGN KEY (id_option) + REFERENCES Shop_Delivery_Option(id_option) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Delivery_Option_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Delivery Option + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Delivery_Option_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Delivery_Option_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_permutation INT, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + id_delivery_option INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_id_delivery_option + FOREIGN KEY (id_delivery_option) + REFERENCES Shop_Delivery_Option(id_option) + ON UPDATE RESTRICT, + id_region INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_id_region + FOREIGN KEY (id_region) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + id_currency INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + price_local FLOAT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Delivery Option Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Delivery_Option_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Delivery_Option_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Delivery_Option_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(64) NOT NULL, + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Discounts + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Discount'; + +CREATE TABLE Shop_Discount ( + id_discount INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(200) NOT NULL, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Discount_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT, + CONSTRAINT FK_Shop_Discount_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + /* + id_delivery_region INT, + CONSTRAINT FK_Shop_Discount_id_delivery_region + FOREIGN KEY (id_delivery_region) + REFERENCES Shop_Delivery_Region(id_region) + ON UPDATE RESTRICT, + id_currency INT, + CONSTRAINT FK_Shop_Discount_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + */ + multiplier FLOAT NOT NULL DEFAULT 1 CHECK (multiplier > 0), + subtractor FLOAT NOT NULL DEFAULT 0, + apply_multiplier_first BIT DEFAULT 1, + quantity_min FLOAT NOT NULL DEFAULT 0, + quantity_max FLOAT NOT NULL, + date_start DATETIME NOT NULL, + date_end DATETIME NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Discount_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +# Discount Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Discount_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Discount_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_discount INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Audit_id_discount + FOREIGN KEY (id_discount) + REFERENCES Shop_Discount(id_discount) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); +# Discount Region Currency Link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Discount_Region_Currency_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Discount_Region_Currency_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_discount INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Region_Currency_Link_id_discount + FOREIGN KEY (id_discount) + REFERENCES Shop_Discount(id_discount) + ON UPDATE RESTRICT, + id_region INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Region_Currency_Link_id_region + FOREIGN KEY (id_region) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + id_currency INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Region_Currency_Link_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Discount_Region_Currency_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# Discount Region Currency Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Discount_Region_Currency_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Discount_Region_Currency_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Region_Currency_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Discount_Region_Currency_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Region_Currency_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); +# Permission Groups + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Permission_Group'; + +CREATE TABLE IF NOT EXISTS Shop_Permission_Group ( + id_group INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Permission_Group_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); +# Permission Group Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Permission_Group_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Permission_Group_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_group INT NOT NULL, + CONSTRAINT FK_Shop_Permission_Group_Audit_id_group + FOREIGN KEY (id_group) + REFERENCES Shop_Permission_Group(id_group) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Permission_Group_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); +# Permissions + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Permission'; + +CREATE TABLE IF NOT EXISTS Shop_Permission ( + id_permission INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + id_permission_group INT NOT NULL, + CONSTRAINT FK_Shop_Permission_id_permission_group + FOREIGN KEY (id_permission_group) + REFERENCES Shop_Permission_Group(id_group) + ON UPDATE RESTRICT, + id_access_level_required INT NOT NULL, + CONSTRAINT FK_Shop_Permission_id_access_level_required + FOREIGN KEY (id_access_level_required) + REFERENCES Shop_Access_Level(id_access_level), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Permission_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); +# Permission Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Permission_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Permission_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_permission INT NOT NULL, + CONSTRAINT FK_Shop_Permission_Audit_id_permission + FOREIGN KEY (id_permission) + REFERENCES Shop_Permission(id_permission) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Permission_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); +# Roles + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Role'; + +CREATE TABLE IF NOT EXISTS Shop_Role ( + id_role INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Role_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); +# Role Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Role_Audit'; + +CREATE TABLE Shop_Role_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_role INT NOT NULL, + CONSTRAINT FK_Shop_Role_Audit_id_role + FOREIGN KEY (id_role) + REFERENCES Shop_Role(id_role) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Role_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); +# Role Permission link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Role_Permission_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Role_Permission_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_role INT, + CONSTRAINT FK_Shop_Role_Permission_Link_id_role + FOREIGN KEY (id_role) + REFERENCES Shop_Role(id_role) + ON UPDATE RESTRICT, + id_permission INT, + CONSTRAINT FK_Shop_Role_Permission_Link_id_permission + FOREIGN KEY (id_permission) + REFERENCES Shop_Permission(id_permission) + ON UPDATE RESTRICT, + id_access_level INT, + CONSTRAINT FK_Shop_Role_Permission_Link_id_access_level + FOREIGN KEY (id_access_level) + REFERENCES Shop_Access_Level(id_access_level), + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Role_Permission_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); +# Role Permission link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Role_Permission_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Role_Permission_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Role_Permission_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Role_Permission_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Role_Permission_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); +# Users + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User'; + +CREATE TABLE IF NOT EXISTS Shop_User ( + id_user VARCHAR(200) NOT NULL PRIMARY KEY, + name VARCHAR(255) NOT NULL, + email VARCHAR(254) NOT NULL, + email_verified BIT NOT NULL DEFAULT 0, + is_super_user BIT NOT NULL DEFAULT 0, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_User_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); + +# User Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_User_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_Shop_User_Audit_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_User_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); +# User Role link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Role_Link'; + +CREATE TABLE IF NOT EXISTS Shop_User_Role_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_Shop_User_Role_Link_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user) + ON UPDATE RESTRICT, + id_role INT NOT NULL, + CONSTRAINT FK_Shop_User_Role_Link_id_role + FOREIGN KEY (id_role) + REFERENCES Shop_Role(id_role), + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_User_Role_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); +# User Role Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Role_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_User_Role_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_User_Role_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_User_Role_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_User_Role_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); + +# Addresses + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Address'; + +CREATE TABLE Shop_Address ( + id_address INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_Shop_Address_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user) + ON UPDATE RESTRICT, + -- region VARCHAR(100) NOT NULL, + id_region INT NOT NULL, + name_full VARCHAR(255) NOT NULL, + phone_number VARCHAR(20) NOT NULL, + postcode VARCHAR(20) NOT NULL, + address_line_1 VARCHAR(100) NOT NULL, + address_line_2 VARCHAR(100) NOT NULL, + city VARCHAR(50) NOT NULL, + county VARCHAR(100) NOT NULL, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Address_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); +# Address Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Address_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Address_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_address INT NOT NULL, + CONSTRAINT FK_Shop_Address_Audit_id_address + FOREIGN KEY (id_address) + REFERENCES Shop_Address(id_address) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Address_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); +# User Basket (Product Link) + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Basket'; + +CREATE TABLE IF NOT EXISTS Shop_User_Basket ( + id_item INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_Shop_User_Basket_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user) + ON UPDATE RESTRICT, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_User_Basket_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_permutation INT, + CONSTRAINT FK_Shop_User_Basket_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + quantity INT NOT NULL, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set_user INT, + CONSTRAINT FK_Shop_User_Basket_id_change_set_user + FOREIGN KEY (id_change_set_user) + REFERENCES Shop_User_Change_Set(id_change_set) + /* + id_change_set_product INT, + CONSTRAINT FK_Shop_User_Basket_id_change_set_product + FOREIGN KEY (id_change_set_product) + REFERENCES Shop_Product_Change_Set(id_change_set) + */ +); + +# Product Basket Audits +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Basket_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_User_Basket_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_item INT NOT NULL, + CONSTRAINT FK_Shop_User_Basket_Audit_id_link + FOREIGN KEY (id_item) + REFERENCES Shop_User_Basket(id_item) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set_user INT, + CONSTRAINT FK_Shop_User_Basket_Audit_id_change_set_user + FOREIGN KEY (id_change_set_user) + REFERENCES Shop_User_Change_Set(id_change_set) + /* + id_change_set_product INT, + CONSTRAINT FK_Shop_User_Basket_Audit_id_change_set_product + FOREIGN KEY (id_change_set_product) + REFERENCES Shop_Product_Change_Set(id_change_set) + */ +); + +# User Order Types + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Order_Status'; + +CREATE TABLE IF NOT EXISTS Shop_User_Order_Status ( + id_status INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + name_plural VARCHAR(256), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_User_Order_Status_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); + +# Order Type Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Order_Status_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_User_Order_Status_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_status INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Status_Audit_id_status + FOREIGN KEY (id_status) + REFERENCES Shop_User_Order_Status(id_status) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Status_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); +# User Order + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Order'; + +CREATE TABLE IF NOT EXISTS Shop_User_Order ( + id_order INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_Shop_User_Order_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user) + ON UPDATE RESTRICT, + value_total FLOAT, + id_order_status INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_id_order_status + FOREIGN KEY (id_order_status) + REFERENCES Shop_User_Order_Status(id_status), + id_checkout_session VARCHAR(200) NOT NULL, + id_currency INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set_user INT, + CONSTRAINT FK_Shop_User_Order_id_change_set_user + FOREIGN KEY (id_change_set_user) + REFERENCES Shop_User_Change_Set(id_change_set) + /* + id_change_set_product INT, + CONSTRAINT FK_Shop_User_Basket_id_change_set_product + FOREIGN KEY (id_change_set_product) + REFERENCES Shop_Product_Change_Set(id_change_set) + */ +); + +# User Order Audits +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Order_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_User_Order_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_order INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Audit_id_order + FOREIGN KEY (id_order) + REFERENCES Shop_User_Order(id_order) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set_user INT, + CONSTRAINT FK_Shop_User_Order_Audit_id_change_set_user + FOREIGN KEY (id_change_set_user) + REFERENCES Shop_User_Change_Set(id_change_set) + /* + id_change_set_product INT, + CONSTRAINT FK_Shop_User_Basket_Audit_id_change_set_product + FOREIGN KEY (id_change_set_product) + REFERENCES Shop_Product_Change_Set(id_change_set) + */ +); + +# User Order Product link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Order_Product_Link'; + +CREATE TABLE IF NOT EXISTS Shop_User_Order_Product_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_order INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Product_Link_id_order + FOREIGN KEY (id_order) + REFERENCES Shop_User_Order(id_order) + ON UPDATE RESTRICT, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Product_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_permutation INT NULL, + CONSTRAINT FK_Shop_User_Order_Product_Link_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + quantity FLOAT NOT NULL, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_User_Order_Product_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); +# User Order Product Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Order_Product_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_User_Order_Product_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Product_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_User_Order_Product_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Product_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); + +# Shop User Change Set + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User_Change_Set; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Change_Set +BEFORE INSERT ON Shop_User_Change_Set +FOR EACH ROW +BEGIN + IF NEW.updated_last_on <=> NULL THEN + SET NEW.updated_last_on = NOW(); + END IF; + IF NEW.updated_last_by <=> NULL THEN + SET NEW.updated_last_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; +# Shop Access Level + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Access_Level; +DROP TRIGGER IF EXISTS before_update_Shop_Access_Level; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Access_Level +BEFORE INSERT ON Shop_Access_Level +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Access_Level +BEFORE UPDATE ON Shop_Access_Level +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Access_Level_Audit ( + id_access_level, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_access_level, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT (OLD.code <=> NEW.code) + UNION + # Changed name + SELECT NEW.id_access_level, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT (OLD.name <=> NEW.name) + UNION + # Changed priority + SELECT NEW.id_access_level, 'priority', CONVERT(OLD.priority, CHAR), CONVERT(NEW.priority, CHAR), NEW.id_change_set + WHERE NOT (OLD.priority <=> NEW.priority) + UNION + # Changed active + SELECT NEW.id_access_level, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_access_level, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; + +# Product Change Set + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Change_Set; + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Change_Set +BEFORE INSERT ON Shop_Product_Change_Set +FOR EACH ROW +BEGIN + IF NEW.updated_last_on <=> NULL THEN + SET NEW.updated_last_on = NOW(); + END IF; + IF NEW.updated_last_by <=> NULL THEN + SET NEW.updated_last_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +# File Type + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_File_Type; +DROP TRIGGER IF EXISTS before_update_File_Type; + +DELIMITER // +CREATE TRIGGER before_insert_File_Type +BEFORE INSERT ON File_Type +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_File_Type +BEFORE UPDATE ON File_Type +FOR EACH ROW +BEGIN + INSERT INTO File_Type_Audit ( + id_type, + name_field, + value_prev, + value_new + ) + # Changed code + SELECT NEW.id_type, 'code', OLD.code, NEW.code + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_type, 'name', OLD.name, NEW.name + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed extension + SELECT NEW.id_type, 'extension', CONVERT(OLD.extension, CHAR), CONVERT(NEW.extension, CHAR) + WHERE NOT OLD.extension <=> NEW.extension + ; +END // +DELIMITER ; + +# File Type Audits + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_File_Type_Audit; +DROP TRIGGER IF EXISTS before_update_File_Type_Audit; + + +DELIMITER // +CREATE TRIGGER before_insert_File_Type_Audit +BEFORE INSERT ON File_Type_Audit +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_File_Type_Audit +BEFORE UPDATE ON File_Type_Audit +FOR EACH ROW +BEGIN + SET NEW.updated_last_on = NOW(); + SET NEW.updated_last_by = CURRENT_USER(); +END // +DELIMITER ; +# Shop General + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_General; +DROP TRIGGER IF EXISTS before_update_Shop_General; + +DELIMITER // +CREATE TRIGGER before_insert_Shop_General +BEFORE INSERT ON Shop_General +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_Shop_General +BEFORE UPDATE ON Shop_General +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_General_Audit ( + id_general, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed quantity max + SELECT NEW.id_general, 'quantity_max', CONVERT(OLD.quantity_max, CHAR), CONVERT(NEW.quantity_max, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + ; +END // +DELIMITER ; +# Shop Category + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Category; +DROP TRIGGER IF EXISTS before_update_Shop_Category; + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Category +BEFORE INSERT ON Shop_Category +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_Shop_Category +BEFORE UPDATE ON Shop_Category +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Category_Audit ( + id_category, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_category, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_category, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed description + SELECT NEW.id_category, 'description', OLD.description, NEW.description, NEW.id_change_set + WHERE NOT OLD.description <=> NEW.description + UNION + # Changed active + SELECT NEW.id_category, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_category, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; + +# Shop Recurrence Interval + +USE PARTS; + + +DROP TRIGGER IF EXISTS before_insert_Shop_Recurrence_Interval; +DROP TRIGGER IF EXISTS before_update_Shop_Recurrence_Interval; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Recurrence_Interval +BEFORE INSERT ON Shop_Recurrence_Interval +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Recurrence_Interval +BEFORE UPDATE ON Shop_Recurrence_Interval +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Recurrence_Interval_Audit ( + id_interval, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_interval, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_interval, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed name_plural + SELECT NEW.id_interval, 'name_plural', OLD.name_plural, NEW.name_plural, NEW.id_change_set + WHERE NOT OLD.name_plural <=> NEW.name_plural + UNION + # Changed name + SELECT NEW.id_interval, 'active', OLD.active, NEW.active, NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + ; +END // +DELIMITER ; +# Shop Delivery Region + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Region; +DROP TRIGGER IF EXISTS before_update_Shop_Region; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Region +BEFORE INSERT ON Shop_Region +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Region +BEFORE UPDATE ON Shop_Region +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Region_Audit ( + id_region, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_region, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_region, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed active + SELECT NEW.id_region, 'active', CONVERT(OLD.active, CHAR), CONVERT(NEW.active, CHAR), NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + UNION + # Changed display_order + SELECT NEW.id_region, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; + +# Shop Region Branch + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Region_Branch; +DROP TRIGGER IF EXISTS before_update_Shop_Region_Branch; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Region_Branch +BEFORE INSERT ON Shop_Region_Branch +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Region_Branch +BEFORE UPDATE ON Shop_Region_Branch +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Region_Branch_Audit ( + id_branch, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed depth + SELECT NEW.id_branch, 'depth', CONVERT(OLD.depth, CHAR), CONVERT(NEW.depth, CHAR), NEW.id_change_set + WHERE NOT OLD.depth <=> NEW.depth + UNION + */ + # Changed active + SELECT NEW.id_branch, 'active', CONVERT(OLD.active, CHAR), CONVERT(NEW.active, CHAR), NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + UNION + # Changed display_order + SELECT NEW.id_branch, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; + +# Shop Currency + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Currency; +DROP TRIGGER IF EXISTS before_update_Shop_Currency; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Currency +BEFORE INSERT ON Shop_Currency +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Currency +BEFORE UPDATE ON Shop_Currency +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Currency_Audit ( + id_currency, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_currency, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_currency, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed symbol + SELECT NEW.id_currency, 'symbol', OLD.symbol, NEW.symbol, NEW.id_change_set + WHERE NOT OLD.symbol <=> NEW.symbol + UNION + # Changed ratio_2_GBP + SELECT NEW.id_currency, 'factor_from_GBP', OLD.factor_from_GBP, NEW.factor_from_GBP, NEW.id_change_set + WHERE NOT OLD.factor_from_GBP <=> NEW.factor_from_GBP + UNION + # Changed active + SELECT NEW.id_currency, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_currency, 'display_order', CONVERT(display_order, CHAR), CONVERT(display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; +# Shop Tax_Or_Surcharge + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Tax_Or_Surcharge; +DROP TRIGGER IF EXISTS before_update_Shop_Tax_Or_Surcharge; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Tax_Or_Surcharge +BEFORE INSERT ON Shop_Tax_Or_Surcharge +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_Shop_Tax_Or_Surcharge +BEFORE UPDATE ON Shop_Tax_Or_Surcharge +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Tax_Or_Surcharge_Audit ( + id_tax, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_tax, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_tax, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed fixed_fee + SELECT NEW.id_tax, 'fixed_fee', OLD.fixed_fee, NEW.fixed_fee, NEW.id_change_set + WHERE NOT OLD.fixed_fee <=> NEW.fixed_fee + UNION + # Changed multiplier + SELECT NEW.id_tax, 'multiplier', OLD.multiplier, NEW.multiplier, NEW.id_change_set + WHERE NOT OLD.multiplier <=> NEW.multiplier + UNION + # Changed apply_fixed_fee_before_multiplier + SELECT NEW.id_tax, 'apply_fixed_fee_before_multiplier', CONVERT(CONVERT(OLD.apply_fixed_fee_before_multiplier, SIGNED), CHAR), CONVERT(CONVERT(NEW.apply_fixed_fee_before_multiplier, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.apply_fixed_fee_before_multiplier <=> NEW.apply_fixed_fee_before_multiplier + UNION + # Changed quantity_min + SELECT NEW.id_tax, 'quantity_min', OLD.quantity_min, NEW.quantity_min, NEW.id_change_set + WHERE NOT OLD.quantity_min <=> NEW.quantity_min + UNION + # Changed quantity_max + SELECT NEW.id_tax, 'quantity_max', OLD.quantity_max, NEW.quantity_max, NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + UNION + # Changed display_order + SELECT NEW.id_tax, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + UNION + # Changed active + SELECT NEW.id_tax, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + ; +END // +DELIMITER ; + + +# Shop Product + +USE PARTS; + + +DROP TRIGGER IF EXISTS before_insert_Shop_Product; +DROP TRIGGER IF EXISTS before_update_Shop_Product; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product +BEFORE INSERT ON Shop_Product +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product +BEFORE UPDATE ON Shop_Product +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + /* + IF NOT NEW.has_variations THEN + IF ISNULL(NEW.price_GBP_full) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have price or variations (with prices).'; + END IF; + IF ISNULL(NEW.price_GBP_min) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have minimum price or variations (with prices).'; + END IF; + IF ISNULL(NEW.latency_manuf) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have manufacturing latency or variations (with manufacturing latencies).'; + END IF; + IF ISNULL(NEW.quantity_min) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have minimum quantity or variations (with minimum quantities).'; + END IF; + IF ISNULL(NEW.quantity_max) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have maximum quantity or variations (with maximum quantities).'; + END IF; + IF ISNULL(NEW.quantity_step) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have increment of quantity or variations (with increments of quantities).'; + END IF; + IF ISNULL(NEW.quantity_stock) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have stock quantity or variations (with stock quantities).'; + END IF; + IF ISNULL(NEW.is_subscription) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have subscription status or variations (with subscription statuses).'; + END IF; + IF ISNULL(NEW.id_recurrence_interval) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have recurrence interval or variations (with recurrence intervals).'; + END IF; + IF ISNULL(NEW.count_recurrence_interval) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have recurrence interval count or variations (with recurrence interval counts).'; + END IF; + END IF; + */ + + INSERT INTO Shop_Product_Audit ( + id_product, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed name + SELECT NEW.id_product, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + /* + UNION + # Changed description + SELECT NEW.id_product, 'description', OLD.description, NEW.description, NEW.id_change_set + WHERE NOT OLD.description <=> NEW.description + UNION + # Changed price_GBP_full + SELECT NEW.id_product, 'price_GBP_full', CONVERT(OLD.price_GBP_full, CHAR), CONVERT(NEW.price_GBP_full, CHAR), NEW.id_change_set + WHERE NOT OLD.price_GBP_full <=> NEW.price_GBP_full + UNION + # Changed price_GBP_min + SELECT NEW.id_product, 'price_GBP_min', CONVERT(OLD.price_GBP_min, CHAR), CONVERT(NEW.price_GBP_min, CHAR), NEW.id_change_set + WHERE NOT OLD.price_GBP_min <=> NEW.price_GBP_min + UNION + # Changed has_variations + SELECT NEW.id_product, 'has_variations', CONVERT(CONVERT(NEW.has_variations, SIGNED), CHAR), CONVERT(CONVERT(NEW.has_variations, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.has_variations <=> NEW.has_variations + UNION + /* + # Changed discount + SELECT NEW.id_product, 'discount', CONVERT(OLD.discount, CHAR), CONVERT(NEW.discount, CHAR), NEW.id_change_set + WHERE NOT OLD.discount <=> NEW.discount + */ + UNION + # Changed id_category + SELECT NEW.id_product, 'id_category', CONVERT(OLD.id_category, CHAR), CONVERT(NEW.id_category, CHAR), NEW.id_change_set + WHERE NOT OLD.id_category <=> NEW.id_category + /* + UNION + # Changed latency_manuf + SELECT NEW.id_product, 'latency_manuf', CONVERT(OLD.latency_manuf, CHAR), CONVERT(NEW.latency_manuf, CHAR), NEW.id_change_set + WHERE NOT OLD.latency_manuf <=> NEW.latency_manuf + UNION + # Changed quantity_min + SELECT NEW.id_product, 'quantity_min', CONVERT(OLD.quantity_min, CHAR), CONVERT(NEW.quantity_min, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_min <=> NEW.quantity_min + UNION + # Changed quantity_max + SELECT NEW.id_product, 'quantity_max', CONVERT(OLD.quantity_max, CHAR), CONVERT(NEW.quantity_max, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + UNION + # Changed quantity_step + SELECT NEW.id_product, 'quantity_step', CONVERT(OLD.quantity_step, CHAR), CONVERT(NEW.quantity_step, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_step <=> NEW.quantity_step + UNION + # Changed quantity_stock + SELECT NEW.id_product, 'quantity_stock', CONVERT(OLD.quantity_stock, CHAR), CONVERT(NEW.quantity_stock, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_stock <=> NEW.quantity_stock + UNION + # Changed is_subscription + SELECT NEW.id_product, 'is_subscription', CONVERT(CONVERT(OLD.is_subscription, SIGNED), CHAR), CONVERT(CONVERT(NEW.is_subscription, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.is_subscription <=> NEW.is_subscription + UNION + # Changed id_recurrence_interval + SELECT NEW.id_product, 'id_recurrence_interval', CONVERT(OLD.id_recurrence_interval, CHAR), CONVERT(NEW.id_recurrence_interval, CHAR), NEW.id_change_set + WHERE NOT OLD.id_recurrence_interval <=> NEW.id_recurrence_interval + UNION + # Changed count_recurrence_interval + SELECT NEW.id_product, 'count_recurrence_interval', CONVERT(OLD.count_recurrence_interval, CHAR), CONVERT(NEW.count_recurrence_interval, CHAR), NEW.id_change_set + WHERE NOT OLD.count_recurrence_interval <=> NEW.count_recurrence_interval + UNION + # Changed id_access_level_required + SELECT NEW.id_product, 'id_access_level_required', CONVERT(OLD.id_access_level_required, CHAR), CONVERT(NEW.id_access_level_required, CHAR), NEW.id_change_set + WHERE NOT OLD.id_access_level_required <=> NEW.id_access_level_required + UNION + # Changed id_stripe_product + SELECT NEW.id_product, 'id_stripe_product', OLD.id_stripe_product, NEW.id_stripe_product, NEW.id_change_set + WHERE NOT OLD.id_stripe_product <=> NEW.id_stripe_product + /* + UNION + # Changed id_stripe_price + SELECT NEW.id_product, 'id_stripe_price', OLD.id_stripe_price, NEW.id_stripe_price, NEW.id_change_set + WHERE NOT OLD.id_stripe_price <=> NEW.id_stripe_price + */ + UNION + # Changed active + SELECT NEW.id_product, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_product, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; + +# Shop Variation Type + +USE PARTS; + + +DROP TRIGGER IF EXISTS before_insert_Shop_Variation_Type; +DROP TRIGGER IF EXISTS before_update_Shop_Variation_Type; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Variation_Type +BEFORE INSERT ON Shop_Variation_Type +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Variation_Type +BEFORE UPDATE ON Shop_Variation_Type +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Variation_Type_Audit ( + id_type, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_type, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_type, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed name_plural + SELECT NEW.id_type, 'name_plural', OLD.name_plural, NEW.name_plural, NEW.id_change_set + WHERE NOT OLD.name_plural <=> NEW.name_plural + UNION + # Changed active + SELECT NEW.id_type, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_type, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; + +# Shop Variation + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Variation; +DROP TRIGGER IF EXISTS before_update_Shop_Variation; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Variation +BEFORE INSERT ON Shop_Variation +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Variation +BEFORE UPDATE ON Shop_Variation +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Variation_Audit ( + id_variation, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_variation, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_variation, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed active + SELECT NEW.id_variation, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_variation, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; + +# Shop Product Permutation + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Permutation; +DROP TRIGGER IF EXISTS before_update_Shop_Product_Permutation; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Permutation +BEFORE INSERT ON Shop_Product_Permutation +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Permutation +BEFORE UPDATE ON Shop_Product_Permutation +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Product_Permutation_Audit ( + id_permutation, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_product + SELECT NEW.id_permutation, 'id_product', OLD.id_product, NEW.id_product, NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_variation + SELECT NEW.id_permutation, 'id_variation', OLD.id_variation, NEW.id_variation, NEW.id_change_set + WHERE NOT OLD.id_variation <=> NEW.id_variation + UNION + # Changed name + SELECT NEW.id_permutation, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT (OLD.name <=> NEW.name) + UNION + */ + # Changed description + SELECT NEW.id_permutation, 'description', OLD.description, NEW.description, NEW.id_change_set + WHERE NOT (OLD.description <=> NEW.description) + UNION + # Changed cost_local_manufacturing + SELECT NEW.id_permutation, 'cost_local_manufacturing', CONVERT(OLD.cost_local_manufacturing, CHAR), CONVERT(NEW.cost_local_manufacturing, CHAR), NEW.id_change_set + WHERE NOT (OLD.cost_local_manufacturing <=> NEW.cost_local_manufacturing) + UNION + # Changed id_currency_cost_manufacturing + SELECT NEW.id_permutation, 'id_currency_cost_manufacturing', CONVERT(OLD.id_currency_cost_manufacturing, CHAR), CONVERT(NEW.id_currency_cost_manufacturing, CHAR), NEW.id_change_set + WHERE NOT (OLD.id_currency_cost_manufacturing <=> NEW.id_currency_cost_manufacturing) + UNION + # Changed profit_local_min + SELECT NEW.id_permutation, 'profit_local_min', CONVERT(OLD.profit_local_min, CHAR), CONVERT(NEW.profit_local_min, CHAR), NEW.id_change_set + WHERE NOT (OLD.profit_local_min <=> NEW.profit_local_min) + UNION + # Changed id_currency_profit_min + SELECT NEW.id_permutation, 'id_currency_profit_min', CONVERT(OLD.id_currency_profit_min, CHAR), CONVERT(NEW.id_currency_profit_min, CHAR), NEW.id_change_set + WHERE NOT (OLD.id_currency_profit_min <=> NEW.id_currency_profit_min) + UNION + /* + # Changed price_GBP_min + SELECT NEW.id_permutation, 'price_GBP_min', CONVERT(OLD.price_GBP_min, CHAR), CONVERT(NEW.price_GBP_min, CHAR), NEW.id_change_set + WHERE NOT (OLD.price_GBP_min <=> NEW.price_GBP_min) + UNION + */ + # Changed latency_manufacture + SELECT NEW.id_product, 'latency_manufacture', CONVERT(OLD.latency_manufacture, CHAR), CONVERT(NEW.latency_manufacture, CHAR), NEW.id_change_set + WHERE NOT OLD.latency_manufacture <=> NEW.latency_manufacture + UNION + # Changed quantity_min + SELECT NEW.id_product, 'quantity_min', CONVERT(OLD.quantity_min, CHAR), CONVERT(NEW.quantity_min, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_min <=> NEW.quantity_min + UNION + # Changed quantity_max + SELECT NEW.id_product, 'quantity_max', CONVERT(OLD.quantity_max, CHAR), CONVERT(NEW.quantity_max, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + UNION + # Changed quantity_step + SELECT NEW.id_product, 'quantity_step', CONVERT(OLD.quantity_step, CHAR), CONVERT(NEW.quantity_step, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_step <=> NEW.quantity_step + UNION + # Changed quantity_stock + SELECT NEW.id_product, 'quantity_stock', CONVERT(OLD.quantity_stock, CHAR), CONVERT(NEW.quantity_stock, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_stock <=> NEW.quantity_stock + UNION + # Changed is_subscription + SELECT NEW.id_product, 'is_subscription', CONVERT(CONVERT(OLD.is_subscription, SIGNED), CHAR), CONVERT(CONVERT(NEW.is_subscription, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.is_subscription <=> NEW.is_subscription + UNION + # Changed id_recurrence_interval + SELECT NEW.id_product, 'id_recurrence_interval', CONVERT(OLD.id_recurrence_interval, CHAR), CONVERT(NEW.id_recurrence_interval, CHAR), NEW.id_change_set + WHERE NOT OLD.id_recurrence_interval <=> NEW.id_recurrence_interval + UNION + # Changed count_recurrence_interval + SELECT NEW.id_product, 'count_recurrence_interval', CONVERT(OLD.count_recurrence_interval, CHAR), CONVERT(NEW.count_recurrence_interval, CHAR), NEW.id_change_set + WHERE NOT OLD.count_recurrence_interval <=> NEW.count_recurrence_interval + UNION + # Changed id_stripe_product + SELECT NEW.id_permutation, 'id_stripe_product', OLD.id_stripe_product, NEW.id_stripe_product, NEW.id_change_set + WHERE NOT (OLD.id_stripe_product <=> NEW.id_stripe_product) + UNION + # Changed active + SELECT NEW.id_permutation, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_permutation, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; +# Shop Product Permutation Variation Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Permutation_Variation_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Product_Permutation_Variation_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Permutation_Variation_Link +BEFORE INSERT ON Shop_Product_Permutation_Variation_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Permutation_Variation_Link +BEFORE UPDATE ON Shop_Product_Permutation_Variation_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Product_Permutation_Variation_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_product + SELECT NEW.id_link, 'id_product', OLD.id_product, NEW.id_product, NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_variation + SELECT NEW.id_link, 'id_variation', OLD.id_variation, NEW.id_variation, NEW.id_change_set + WHERE NOT OLD.id_variation <=> NEW.id_variation + UNION + */ + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_link, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; +# Shop Product Currency Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Currency_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Product_Currency_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Currency_Link +BEFORE INSERT ON Shop_Product_Currency_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; + /* + SET NEW.price_local = ( + SELECT PP.price_GBP_full * C.factor_from_GBP + FROM Shop_Product_Permutation PP + INNER JOIN Shop_Product P ON PP.id_product = P.id_product + INNER JOIN Shop_Currency C ON NEW.id_currency = C.id_currency + WHERE NEW.id_product = P.id_product + LIMIT 1 + ); + */ +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Currency_Link +BEFORE UPDATE ON Shop_Product_Currency_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + /* + SET NEW.price_local = ( + SELECT P.price_GBP_full * C.factor_from_GBP + FROM Shop_Product P + INNER JOIN Shop_Currency C ON NEW.id_currency = C.id_currency + WHERE NEW.id_product = P.id_product + LIMIT 1 + ); + */ + + INSERT INTO Shop_Product_Currency_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_product + SELECT NEW.id_link, 'id_product', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_currency + SELECT NEW.id_link, 'id_currency', CONVERT(OLD.id_currency, CHAR), CONVERT(NEW.id_currency, CHAR), NEW.id_change_set + WHERE NOT OLD.id_currency <=> NEW.id_currency + UNION + # Changed price_local + SELECT NEW.id_link, 'price_local', OLD.price_local, NEW.price_local, NEW.id_change_set + WHERE NOT OLD.price_local <=> NEW.price_local + UNION + */ + # Changed price_local_VAT_incl + SELECT NEW.id_link, 'price_local_VAT_incl', OLD.price_local_VAT_incl, NEW.price_local_VAT_incl, NEW.id_change_set + WHERE NOT OLD.price_local_VAT_incl <=> NEW.price_local_VAT_incl + UNION + # Changed price_local_VAT_excl + SELECT NEW.id_link, 'price_local_VAT_excl', OLD.price_local_VAT_excl, NEW.price_local_VAT_excl, NEW.id_change_set + WHERE NOT OLD.price_local_VAT_excl <=> NEW.price_local_VAT_excl + UNION + # Changed id_stripe_price + SELECT NEW.id_link, 'id_stripe_price', OLD.id_stripe_price, NEW.id_stripe_price, NEW.id_change_set + WHERE NOT OLD.id_stripe_price <=> NEW.id_stripe_price + UNION + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; + +# Shop Product Currency Region Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Currency_Region_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Product_Currency_Region_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Currency_Region_Link +BEFORE INSERT ON Shop_Product_Currency_Region_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; + /* + SET NEW.price_local = ( + SELECT PP.price_GBP_full * C.factor_from_GBP + FROM Shop_Product_Permutation PP + INNER JOIN Shop_Product P ON PP.id_product = P.id_product + INNER JOIN Shop_Currency C ON NEW.id_currency = C.id_currency + WHERE NEW.id_product = P.id_product + LIMIT 1 + ); + */ +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Currency_Region_Link +BEFORE UPDATE ON Shop_Product_Currency_Region_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + /* + SET NEW.price_local = ( + SELECT P.price_GBP_full * C.factor_from_GBP + FROM Shop_Product P + INNER JOIN Shop_Currency C ON NEW.id_currency = C.id_currency + WHERE NEW.id_product = P.id_product + LIMIT 1 + ); + */ + + INSERT INTO Shop_Product_Currency_Region_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_product + SELECT NEW.id_link, 'id_product', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_currency + SELECT NEW.id_link, 'id_currency', CONVERT(OLD.id_currency, CHAR), CONVERT(NEW.id_currency, CHAR), NEW.id_change_set + WHERE NOT OLD.id_currency <=> NEW.id_currency + UNION + # Changed price_local + SELECT NEW.id_link, 'price_local', OLD.price_local, NEW.price_local, NEW.id_change_set + WHERE NOT OLD.price_local <=> NEW.price_local + UNION + */ + # Changed price_local_VAT_incl + SELECT NEW.id_link, 'price_local_VAT_incl', OLD.price_local_VAT_incl, NEW.price_local_VAT_incl, NEW.id_change_set + WHERE NOT OLD.price_local_VAT_incl <=> NEW.price_local_VAT_incl + UNION + # Changed price_local_VAT_excl + SELECT NEW.id_link, 'price_local_VAT_excl', OLD.price_local_VAT_excl, NEW.price_local_VAT_excl, NEW.id_change_set + WHERE NOT OLD.price_local_VAT_excl <=> NEW.price_local_VAT_excl + UNION + # Changed id_stripe_price + SELECT NEW.id_link, 'id_stripe_price', OLD.id_stripe_price, NEW.id_stripe_price, NEW.id_change_set + WHERE NOT OLD.id_stripe_price <=> NEW.id_stripe_price + UNION + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; + +# Shop Image Type + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Image_Type; +DROP TRIGGER IF EXISTS before_update_Shop_Image_Type; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Image_Type +BEFORE INSERT ON Shop_Image_Type +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Image_Type +BEFORE UPDATE ON Shop_Image_Type +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Image_Type_Audit ( + id_type, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_type, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_type, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed name_plural + SELECT NEW.id_type, 'name_plural', OLD.name_plural, NEW.name_plural, NEW.id_change_set + WHERE NOT OLD.name_plural <=> NEW.name_plural + UNION + # Changed active + SELECT NEW.id_type, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_type, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; +# Shop Image + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Image; +DROP TRIGGER IF EXISTS before_update_Shop_Image; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Image +BEFORE INSERT ON Shop_Image +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Image +BEFORE UPDATE ON Shop_Image +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change set ID must be provided.'; + END IF; + IF ISNULL(NEW.id_product) AND ISNULL(NEW.id_permutation) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Image must NOT have ID for product AND product permutation.'; + END IF; + + INSERT INTO Shop_Image_Audit ( + id_image, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed id_type_image + SELECT NEW.id_image, 'id_type_image', CONVERT(OLD.id_type_image, CHAR), CONVERT(NEW.id_type_image, CHAR), NEW.id_change_set + WHERE NOT OLD.id_type_image <=> NEW.id_type_image + UNION + # Changed id_type_file + SELECT NEW.id_image, 'id_type_file', CONVERT(OLD.id_type_file, CHAR), CONVERT(NEW.id_type_file, CHAR), NEW.id_change_set + WHERE NOT OLD.id_type_file <=> NEW.id_type_file + UNION + # Changed id_product + SELECT NEW.id_image, 'id_product', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_permutation + SELECT NEW.id_image, 'id_permutation', CONVERT(OLD.id_permutation, CHAR), CONVERT(NEW.id_permutation, CHAR), NEW.id_change_set + WHERE NOT OLD.id_permutation <=> NEW.id_permutation + UNION + # Changed url + SELECT NEW.id_image, 'url', OLD.url, NEW.url, NEW.id_change_set + WHERE NOT OLD.url <=> NEW.url + UNION + # Changed active + SELECT NEW.id_image, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_image, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; +# Shop Delivery Option Type + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Delivery_Option; +DROP TRIGGER IF EXISTS before_update_Shop_Delivery_Option; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Delivery_Option +BEFORE INSERT ON Shop_Delivery_Option +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Delivery_Option +BEFORE UPDATE ON Shop_Delivery_Option +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Delivery_Option_Audit ( + id_option, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_option, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_option, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed latency_delivery_min + SELECT NEW.id_option, 'latency_delivery_min', CONVERT(OLD.latency_delivery_min, CHAR), CONVERT(NEW.latency_delivery_min, CHAR), NEW.id_change_set + WHERE NOT OLD.latency_delivery_min <=> NEW.latency_delivery_min + UNION + # Changed latency_delivery_max + SELECT NEW.id_option, 'latency_delivery_max', CONVERT(OLD.latency_delivery_max, CHAR), CONVERT(NEW.latency_delivery_max, CHAR), NEW.id_change_set + WHERE NOT OLD.latency_delivery_max <=> NEW.latency_delivery_max + UNION + # Changed quantity_min + SELECT NEW.id_option, 'quantity_min', CONVERT(OLD.quantity_min, CHAR), CONVERT(NEW.quantity_min, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_min <=> NEW.quantity_min + UNION + # Changed quantity_max + SELECT NEW.id_option, 'quantity_max', CONVERT(OLD.quantity_max, CHAR), CONVERT(NEW.quantity_max, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + UNION + # Changed active + SELECT NEW.id_option, 'active', CONVERT(OLD.active, CHAR), CONVERT(NEW.active, CHAR), NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + UNION + # Changed display_order + SELECT NEW.id_option, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; +# Shop Product Delivery Option Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Delivery_Option_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Product_Delivery_Option_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Delivery_Option_Link +BEFORE INSERT ON Shop_Product_Delivery_Option_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Delivery_Option_Link +BEFORE UPDATE ON Shop_Product_Delivery_Option_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Product_Delivery_Option_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_product + SELECT NEW.id_link, 'id_product', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_permutation + SELECT NEW.id_link, 'id_permutation', CONVERT(OLD.id_permutation, CHAR), CONVERT(NEW.id_permutation, CHAR), NEW.id_change_set + WHERE NOT OLD.id_permutation <=> NEW.id_permutation + UNION + # Changed id_option + SELECT NEW.id_link, 'id_option', CONVERT(OLD.id_option, CHAR), CONVERT(NEW.id_option, CHAR), NEW.id_change_set + WHERE NOT OLD.id_option <=> NEW.id_option + UNION + # Changed id_region + SELECT NEW.id_link, 'id_region', CONVERT(OLD.id_region, CHAR), CONVERT(NEW.id_region, CHAR), NEW.id_change_set + WHERE NOT OLD.id_region <=> NEW.id_region + UNION + */ + # Changed price_local + SELECT NEW.id_link, 'price_local', CONVERT(OLD.price_local, CHAR), CONVERT(NEW.price_local, CHAR), NEW.id_change_set + WHERE NOT OLD.price_local <=> NEW.price_local + UNION + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_link, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; +# Shop Discount + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Discount; +DROP TRIGGER IF EXISTS before_update_Shop_Discount; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Discount +BEFORE INSERT ON Shop_Discount +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_Shop_Discount +BEFORE UPDATE ON Shop_Discount +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Discount_Audit ( + id_discount, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_discount, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_discount, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed multiplier + SELECT NEW.id_discount, 'multiplier', OLD.multiplier, NEW.multiplier, NEW.id_change_set + WHERE NOT OLD.multiplier <=> NEW.multiplier + UNION + # Changed subtractor + SELECT NEW.id_discount, 'subtractor', OLD.subtractor, NEW.subtractor, NEW.id_change_set + WHERE NOT OLD.subtractor <=> NEW.subtractor + UNION + # Changed apply_multiplier_first + SELECT NEW.id_discount, 'apply_multiplier_first', CONVERT(CONVERT(OLD.apply_multiplier_first, SIGNED), CHAR), CONVERT(CONVERT(NEW.apply_multiplier_first, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.apply_multiplier_first <=> NEW.apply_multiplier_first + UNION + # Changed quantity_min + SELECT NEW.id_discount, 'quantity_min', OLD.quantity_min, NEW.quantity_min, NEW.id_change_set + WHERE NOT OLD.quantity_min <=> NEW.quantity_min + UNION + # Changed quantity_max + SELECT NEW.id_discount, 'quantity_max', OLD.quantity_max, NEW.quantity_max, NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + UNION + # Changed date_start + SELECT NEW.id_discount, 'date_start', OLD.date_start, NEW.date_start, NEW.id_change_set + WHERE NOT OLD.date_start <=> NEW.date_start + UNION + # Changed date_end + SELECT NEW.id_discount, 'date_end', OLD.date_end, NEW.date_end, NEW.id_change_set + WHERE NOT OLD.date_end <=> NEW.date_end + UNION + # Changed display_order + SELECT NEW.id_discount, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + UNION + # Changed active + SELECT NEW.id_discount, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + ; +END // +DELIMITER ; + + +# Shop Discount Region Currency Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Discount_Region_Currency_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Discount_Region_Currency_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Discount_Region_Currency_Link +BEFORE INSERT ON Shop_Discount_Region_Currency_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Discount_Region_Currency_Link +BEFORE UPDATE ON Shop_Discount_Region_Currency_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Discount_Region_Currency_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_discount + SELECT NEW.id_link, 'id_discount', CONVERT(OLD.id_discount, CHAR), CONVERT(NEW.id_discount, CHAR), NEW.id_change_set + WHERE NOT OLD.id_discount <=> NEW.id_discount + UNION + # Changed id_region + SELECT NEW.id_link, 'id_region', CONVERT(OLD.id_region, CHAR), CONVERT(NEW.id_region, CHAR), NEW.id_change_set + WHERE NOT OLD.id_region <=> NEW.id_region + UNION + */ + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; +# Shop Permission Group + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Permission_Group; +DROP TRIGGER IF EXISTS before_update_Shop_Permission_Group; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Permission_Group +BEFORE INSERT ON Shop_Permission_Group +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Permission_Group +BEFORE UPDATE ON Shop_Permission_Group +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Permission_Group_Audit ( + id_group, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_group, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_group, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed active + SELECT NEW.id_group, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_group, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; +# Shop Permission + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Permission; +DROP TRIGGER IF EXISTS before_update_Shop_Permission; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Permission +BEFORE INSERT ON Shop_Permission +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Permission +BEFORE UPDATE ON Shop_Permission +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Permission_Audit ( + id_permission, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_permission, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_permission, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed id_permission_group + SELECT NEW.id_permission, 'id_permission_group', CONVERT(OLD.id_permission_group, CHAR), CONVERT(NEW.id_permission_group, CHAR), NEW.id_change_set + WHERE NOT OLD.id_permission_group <=> NEW.id_permission_group + UNION + # Changed Id_access_level_required + SELECT NEW.id_permission, 'Id_access_level_required', CONVERT(OLD.Id_access_level_required, CHAR), CONVERT(NEW.Id_access_level_required, CHAR), NEW.id_change_set + WHERE NOT OLD.Id_access_level_required <=> NEW.Id_access_level_required + UNION + # Changed active + SELECT NEW.id_permission, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_permission, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; +# Shop Role + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Role; +DROP TRIGGER IF EXISTS before_update_Shop_Role; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Role +BEFORE INSERT ON Shop_Role +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Role +BEFORE UPDATE ON Shop_Role +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Role_Audit ( + id_role, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_role, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_role, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed active + SELECT NEW.id_role, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_role, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; + +# Shop Role Permission Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Role_Permission_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Role_Permission_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Role_Permission_Link +BEFORE INSERT ON Shop_Role_Permission_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Role_Permission_Link +BEFORE UPDATE ON Shop_Role_Permission_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Role_Permission_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_role + SELECT NEW.id_link, 'id_role', CONVERT(OLD.id_role, CHAR), CONVERT(NEW.id_role, CHAR), NEW.id_change_set + WHERE NOT OLD.id_role <=> NEW.id_role + UNION + # Changed id_permission + SELECT NEW.id_link, 'id_permission', CONVERT(OLD.id_permission, CHAR), CONVERT(NEW.id_permission, CHAR), NEW.id_change_set + WHERE NOT OLD.id_permission <=> NEW.id_permission + UNION + */ + # Changed id_access_level + SELECT NEW.id_link, 'id_access_level', CONVERT(OLD.id_access_level, CHAR), CONVERT(NEW.id_access_level, CHAR), NEW.id_change_set + WHERE NOT OLD.id_access_level <=> NEW.id_access_level + UNION + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; + +# Shop User + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User; +DROP TRIGGER IF EXISTS before_update_Shop_User; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User +BEFORE INSERT ON Shop_User +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_User +BEFORE UPDATE ON Shop_User +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_User_Audit ( + id_user, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed name + SELECT NEW.id_user, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT (OLD.name <=> NEW.name) + UNION + # Changed is_super_user + SELECT NEW.id_user, 'is_super_user', CONVERT(CONVERT(OLD.is_super_user, SIGNED), CHAR), CONVERT(CONVERT(NEW.is_super_user, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.is_super_user <=> NEW.is_super_user) + UNION + # Changed active + SELECT NEW.id_user, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; +# Shop User Role Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User_Role_Link; +DROP TRIGGER IF EXISTS before_update_Shop_User_Role_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Role_Link +BEFORE INSERT ON Shop_User_Role_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_User_Role_Link +BEFORE UPDATE ON Shop_User_Role_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_User_Role_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; +# Shop Address + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Address; +DROP TRIGGER IF EXISTS before_update_Shop_Address; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Address +BEFORE INSERT ON Shop_Address +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Address +BEFORE UPDATE ON Shop_Address +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Address_Audit ( + id_address, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed region + SELECT NEW.id_address, 'id_region', OLD.id_region, NEW.id_region, NEW.id_change_set + WHERE NOT OLD.id_region <=> NEW.id_region + UNION + # Changed name_full + SELECT NEW.id_address, 'name_full', OLD.name_full, NEW.name_full, NEW.id_change_set + WHERE NOT OLD.name_full <=> NEW.name_full + UNION + # Changed phone_number + SELECT NEW.id_address, 'phone_number', OLD.phone_number, NEW.phone_number, NEW.id_change_set + WHERE NOT OLD.phone_number <=> NEW.phone_number + UNION + # Changed postcode + SELECT NEW.id_address, 'postcode', OLD.postcode, NEW.postcode, NEW.id_change_set + WHERE NOT OLD.postcode <=> NEW.postcode + UNION + # Changed address_line_1 + SELECT NEW.id_address, 'address_line_1', OLD.address_line_1, NEW.address_line_1, NEW.id_change_set + WHERE NOT OLD.address_line_1 <=> NEW.address_line_1 + UNION + # Changed address_line_2 + SELECT NEW.id_address, 'address_line_2', OLD.address_line_2, NEW.address_line_2, NEW.id_change_set + WHERE NOT OLD.address_line_2 <=> NEW.address_line_2 + UNION + # Changed city + SELECT NEW.id_address, 'city', OLD.city, NEW.city, NEW.id_change_set + WHERE NOT OLD.city <=> NEW.city + UNION + # Changed county + SELECT NEW.id_address, 'county', OLD.county, NEW.county, NEW.id_change_set + WHERE NOT OLD.county <=> NEW.county + UNION + # Changed active + SELECT NEW.id_address, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; +# Shop Product Variation Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User_Basket; +DROP TRIGGER IF EXISTS before_update_Shop_User_Basket; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Basket +BEFORE INSERT ON Shop_User_Basket +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_User_Basket +BEFORE UPDATE ON Shop_User_Basket +FOR EACH ROW +BEGIN + IF NEW.id_change_set_user <=> OLD.id_change_set_user THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_User_Basket_Audit ( + id_item, + name_field, + value_prev, + value_new, + id_change_set_user + ) + # Changed id_user + SELECT NEW.id_item, 'id_user', OLD.id_user, NEW.id_user, NEW.id_change_set_user + WHERE NOT OLD.id_user <=> NEW.id_user + UNION + # Changed id_product + SELECT NEW.id_item, 'id_product', OLD.id_product, NEW.id_product, NEW.id_change_set_user + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed quantity + SELECT NEW.id_item, 'quantity', CONVERT(OLD.quantity, CHAR), CONVERT(NEW.quantity, CHAR), NEW.id_change_set_user + WHERE NOT (OLD.quantity <=> NEW.quantity) + UNION + # Changed active + SELECT NEW.id_item, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set_user + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; +# Shop User Order Type + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User_Order_Status; +DROP TRIGGER IF EXISTS before_update_Shop_User_Order_Status; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Order_Status +BEFORE INSERT ON Shop_User_Order_Status +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_User_Order_Status +BEFORE UPDATE ON Shop_User_Order_Status +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_User_Order_Status_Audit ( + id_Status, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_Status, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_Status, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed name_plural + SELECT NEW.id_Status, 'name_plural', OLD.name_plural, NEW.name_plural, NEW.id_change_set + WHERE NOT OLD.name_plural <=> NEW.name_plural + UNION + # Changed active + SELECT NEW.id_Status, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_Status, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; +# Shop Product Variation Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User_Order; +DROP TRIGGER IF EXISTS before_update_Shop_User_Order; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Order +BEFORE INSERT ON Shop_User_Order +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_User_Order +BEFORE UPDATE ON Shop_User_Order +FOR EACH ROW +BEGIN + IF OLD.id_change_set_user <=> NEW.id_change_set_user THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + IF NOT (NEW.id_checkout_session <=> OLD.id_checkout_session) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Checkout session ID must not change.'; + END IF; + + INSERT INTO Shop_User_Order_Audit ( + id_order, + name_field, + value_prev, + value_new, + id_change_set_user + ) + # Changed id_user + SELECT NEW.id_order, 'id_user', OLD.id_user, NEW.id_user, NEW.id_change_set_user + WHERE NOT OLD.id_user <=> NEW.id_user + UNION + # Changed value_total + SELECT NEW.id_order, 'value_total', CONVERT(OLD.value_total, CHAR), CONVERT(NEW.value_total, CHAR), NEW.id_change_set_user + WHERE NOT (OLD.value_total <=> NEW.value_total) + UNION + # Changed id_order_status + SELECT NEW.id_order, 'id_order_status', CONVERT(OLD.id_order_status, CHAR), CONVERT(NEW.id_order_status, CHAR), NEW.id_change_set_user + WHERE NOT (OLD.id_order_status <=> NEW.id_order_status) + UNION + # Changed id_checkout_session + SELECT NEW.id_order, 'id_checkout_session', OLD.id_checkout_session, NEW.id_checkout_session, NEW.id_change_set_user + WHERE NOT (OLD.id_checkout_session <=> NEW.id_checkout_session) + UNION + # Changed active + SELECT NEW.id_order, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set_user + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; +# Shop User Order Product Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User_Order_Product_Link; +DROP TRIGGER IF EXISTS before_update_Shop_User_Order_Product_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Order_Product_Link +BEFORE INSERT ON Shop_User_Order_Product_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_User_Order_Product_Link +BEFORE UPDATE ON Shop_User_Order_Product_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_User_Order_Product_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed id_product + SELECT NEW.id_link, 'active', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT (OLD.id_product <=> NEW.id_product) + UNION + # Changed quantity + SELECT NEW.id_link, 'quantity', CONVERT(OLD.quantity, CHAR), CONVERT(NEW.quantity, CHAR), NEW.id_change_set + WHERE NOT (OLD.quantity <=> NEW.quantity) + UNION + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; +USE PARTS; + + +/* + +CALL p_shop_user_eval ( + UUID(), # a_guid + '', # a_id_user + 0, # a_get_inactive_users + '1', # a_ids_permission + '', # a_ids_access_level + '1' # a_ids_product +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_user_eval; + +DELIMITER // +CREATE PROCEDURE p_shop_user_eval ( + IN a_guid VARCHAR(36), + IN a_id_user VARCHAR(200), + IN a_get_inactive_users BIT, + IN a_ids_permission VARCHAR(500), + IN a_ids_access_level VARCHAR(100), + IN a_ids_permutation VARCHAR(4000) +) +BEGIN + -- Variable declaration + DECLARE v_has_filter_permission BIT; + DECLARE v_has_filter_user BIT; + DECLARE v_has_filter_access_level BIT; + DECLARE v_has_filter_permutation BIT; + DECLARE v_id_permission_product INT; + DECLARE v_id_permission INT; + -- DECLARE v_ids_product VARCHAR(500); + DECLARE v_id_access_level_view INT; + # DECLARE v_id_access_level_product_required INT; + DECLARE v_priority_access_level_view INT; + DECLARE v_priority_access_level_edit INT; + DECLARE v_priority_access_level_admin INT; + DECLARE v_id_access_level INT; + DECLARE v_priority_access_level INT; + DECLARE v_now DATETIME; + DECLARE v_ids_row_delete VARCHAR(500); + DECLARE v_code_error_data VARCHAR(200); + DECLARE v_id_error_data INT; + DECLARE v_code_error_permission VARCHAR(200); + + SET v_id_error_data = 1; + SET v_code_error_data := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = v_id_error_data); + + SET v_code_error_permission := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 2); + + -- Clear previous proc results + # DROP TABLE IF EXISTS tmp_User_Role_Link; + # DROP TEMPORARY TABLE IF EXISTS tmp_User_Role_Link; + DROP TABLE IF EXISTS tmp_Shop_Product_p_Shop_User_Eval; + # DROP TABLE IF EXISTS Shop_User_Eval_Temp; + + + -- Parse arguments + get default values + /* + IF a_guid IS NULL THEN + SET a_guid = UUID(); + END IF; + */ + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + IF a_get_inactive_users IS NULL THEN + SET a_get_inactive_users = 0; + END IF; + /* + IF a_get_user_permissions IS NULL THEN + SET a_get_user_permissions = 0; + END IF; + */ + IF a_ids_permission IS NULL THEN + SET a_ids_permission = ''; + ELSE + SET a_ids_permission = TRIM(a_ids_permission); + END IF; + IF a_ids_access_level IS NULL THEN + SET a_ids_access_level = ''; + ELSE + SET a_ids_access_level = TRIM(a_ids_access_level); + END IF; + IF a_ids_permutation IS NULL THEN + SET a_ids_permutation = ''; + ELSE + SET a_ids_permutation = TRIM(a_ids_permutation); + END IF; + + -- Permanent Table + CREATE TABLE IF NOT EXISTS Shop_User_Eval_Temp ( + id_row INT PRIMARY KEY AUTO_INCREMENT NOT NULL, + guid VARCHAR(36) NOT NULL, + id_user VARCHAR(200), + id_permission_required INT NOT NULL, + CONSTRAINT FK_Shop_User_Eval_Temp_id_permission_required + FOREIGN KEY (id_permission_required) + REFERENCES Shop_Permission (id_permission), + /* + id_access_level_required INT NOT NULL, + CONSTRAINT FK_Shop_User_Eval_Temp_id_access_level_required + FOREIGN KEY (id_access_level_required) + REFERENCES Shop_Access_Level (id_access_level), + */ + priority_access_level_required INT NOT NULL, + /* + CONSTRAINT FK_Shop_User_Eval_Temp_priority_access_level_required + FOREIGN KEY (priority_access_level_required) + REFERENCES Shop_Access_Level (priority), + */ + id_product INT NULL, + CONSTRAINT FK_Shop_User_Eval_Temp_id_product + FOREIGN KEY (id_product) + REFERENCES parts.Shop_Product (id_product), + id_permutation INT NULL, + CONSTRAINT FK_Shop_User_Eval_Temp_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES parts.Shop_Product_Permutation (id_permutation), + is_super_user BIT NULL, + priority_access_level_user INT NULL, + /* + CONSTRAINT FK_Shop_User_Eval_Temp_priority_access_level_minimum + FOREIGN KEY (priority_access_level_minimum) + REFERENCES Shop_Access_Level (priority) + */ + can_view BIT, + can_edit BIT, + can_admin BIT -- DEFAULT 0 + ); + + CREATE TABLE IF NOT EXISTS tmp_Shop_Product_p_Shop_User_Eval ( + id_row INT PRIMARY KEY AUTO_INCREMENT NOT NULL, + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_p_Shop_User_Eval_id_product FOREIGN KEY (id_product) + REFERENCES parts.Shop_Product (id_product), + id_permutation INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_p_Shop_User_Eval_id_permutation FOREIGN KEY (id_permutation) + REFERENCES parts.Shop_Product_Permutation (id_permutation), + id_access_level_required INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_p_Shop_User_Eval_id_access_level_required FOREIGN KEY (id_access_level_required) + REFERENCES Shop_Access_Level (id_access_level), + guid VARCHAR(36) NOT NULL, + rank_permutation INT NOT NULL + ); + + CREATE TABLE IF NOT EXISTS tmp_Msg_Error ( + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + guid VARCHAR(36) NOT NULL, + id_type INT NOT NULL, + CONSTRAINT FK_tmp_Msg_Error_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Msg_Error_Type (id_type), + code VARCHAR(50), + msg VARCHAR(4000) NOT NULL + ); + + # select * from Shop_Msg_Error_Type; + + -- Parse filters + IF a_guid IS NULL OR EXISTS (SELECT * FROM Shop_User_Eval_Temp WHERE a_guid = guid) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + a_guid, + v_code_error_data, + 'Invalid guid argument.' + ) + ; + END IF; + SET v_has_filter_user = CASE WHEN a_id_user = '' THEN 0 ELSE 1 END; + SET a_ids_permission = REPLACE(a_ids_permission, '|', ','); + SET v_has_filter_permission = CASE WHEN a_ids_permission = '' THEN 0 ELSE 1 END; + SET a_ids_access_level = REPLACE(a_ids_access_level, '|', ','); + SET v_has_filter_access_level = CASE WHEN a_ids_access_level = '' THEN 0 ELSE 1 END; + SET a_ids_permutation = REPLACE(a_ids_permutation, '|', ','); + SET v_has_filter_permutation = CASE WHEN a_ids_permutation = '' THEN 0 ELSE 1 END; + SET v_id_access_level_view = (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'VIEW' LIMIT 1); + SET v_priority_access_level_view = (SELECT priority FROM Shop_Access_Level WHERE id_access_level = v_id_access_level_view); + SET v_priority_access_level_edit = (SELECT priority FROM Shop_Access_Level WHERE code = 'EDIT' LIMIT 1); + SET v_priority_access_level_admin = (SELECT priority FROM Shop_Access_Level WHERE code = 'ADMIN' LIMIT 1); + + /* + select v_priority_access_level_view, + v_priority_access_level_edit, + v_priority_access_level_admin + ; + */ + + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE GUID = a_guid) THEN + IF v_has_filter_access_level THEN + CALL p_split(a_ids_access_level, ','); + SET v_id_access_level := ( + SELECT AL.id_access_level + FROM Split_Temp ST + INNER JOIN Shop_Access_Level AL + ON CONVERT(ST.substring, DECIMAL(10,0)) = AL.id_access_level + AND AL.active + ORDER BY AL.priority ASC + LIMIT 1 + ); + DROP TABLE Split_Temp; + IF 0 = v_id_access_level OR v_id_access_level <=> NULL THEN + # SET v_has_filter_access_level = 0; + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + a_guid, + v_code_error_data, + 'Access level ID not found.' + ) + ; + END IF; + /* + END IF; + IF NOT v_has_filter_access_level THEN + */ + ELSE + SET v_id_access_level = v_id_access_level_view; + END IF; + END IF; + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE GUID = a_guid) THEN + IF v_has_filter_permutation THEN + INSERT INTO tmp_Shop_Product_p_Shop_User_Eval ( + id_product, + id_permutation, + id_access_level_required, + guid, + rank_permutation + ) + SELECT + PP.id_product, + PP.id_permutation, + PP.id_access_level_required, + a_guid, + RANK() OVER (ORDER BY PP.id_product, PP.id_permutation, AL.priority) AS rank_permutation + FROM Shop_Product_Permutation PP + INNER JOIN Shop_Access_Level AL + ON PP.id_access_level_required = AL.id_access_level + AND AL.active + WHERE FIND_IN_SET(PP.id_permutation, a_ids_permutation) > 0 + # AND P.active # not worried as we want users to be able to see their order history + ; + /* + DELETE FROM tmp_Shop_Product_p_Shop_User_Eval + WHERE rank_permutation > 1 + ; + */ + SET v_has_filter_permutation = EXISTS (SELECT * FROM tmp_Shop_Product_p_Shop_User_Eval WHERE a_guid = guid); + END IF; + + IF v_has_filter_permission THEN + # Invalid permission IDs + IF EXISTS (SELECT id_permission FROM Shop_Permission WHERE FIND_IN_SET(id_permission, a_ids_permission) > 0 AND NOT active) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + a_guid, + v_code_error_data, + CONCAT('The following permissions are no longer active: ', (SELECT GROUP_CONCAT(name SEPARATOR ', ') FROM Shop_Permission WHERE FIND_IN_SET(id_permission, a_ids_permission) > 0 AND NOT active)) + ) + ; + END IF; + END IF; + END IF; + + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE GUID = a_guid) THEN + IF v_has_filter_user THEN + SET a_id_user := (SELECT id_user FROM Shop_User WHERE id_user LIKE a_id_user AND active); + SET v_has_filter_user = NOT (a_id_user <=> NULL); + IF NOT v_has_filter_user THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + a_guid, + v_code_error_data, + 'User ID not found.' + ) + ; + END IF; + END IF; + END IF; + + -- Get users + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE GUID = a_guid) THEN + INSERT INTO Shop_User_Eval_Temp ( + guid, + id_user, + id_permission_required, + priority_access_level_required + /* + priority_access_level_user, + is_super_user, + can_view, + can_edit, + can_admin + */ + ) + SELECT a_guid, + a_id_user, + P.id_permission, + AL.priority + FROM parts.Shop_Permission P + INNER JOIN Shop_Access_Level AL + ON P.id_access_level_required = AL.id_access_level + AND AL.active + WHERE FIND_IN_SET(P.id_permission, a_ids_permission) > 0 + ; + + IF v_has_filter_permutation THEN + SET v_ids_row_delete := (SELECT GROUP_CONCAT(id_row SEPARATOR ',') FROM Shop_User_Eval_Temp WHERE a_guid = guid); + + INSERT INTO Shop_User_Eval_Temp ( + guid, + id_user, + id_permission_required, + id_product, + id_permutation, + priority_access_level_required + ) + SELECT UE_T.guid, + UE_T.id_user, + UE_T.id_permission_required, + t_P.id_product, + t_P.id_permutation, + CASE WHEN UE_T.priority_access_level_required < AL.priority THEN UE_T.priority_access_level_required ELSE AL.priority END -- UE_T.priority_access_level_required + FROM tmp_Shop_Product_p_Shop_User_Eval t_P + INNER JOIN Shop_Access_Level AL + ON t_P.id_access_leveL_required = AL.id_access_level + AND AL.active + CROSS JOIN Shop_User_Eval_Temp UE_T + ON a_id_user = UE_T.id_user + WHERE a_guid = t_P.guid + ; + + DELETE FROM Shop_User_Eval_Temp + WHERE FIND_IN_SET(id_row, v_ids_row_delete) > 0 + ; + END IF; + + /* + INSERT INTO Shop_User_Eval_Temp ( + guid, + id_user, + id_permission_required, + # id_access_level_required, + priority_access_level_required, + priority_access_level_user, + is_super_user + /* + can_view, + can_edit, + can_admin + * + ) + SELECT a_guid, + U.id_user, + P.id_permission, + AL.priority, + /* + v_id_permission, + v_id_access_level, + * + MIN(AL.priority), + U.is_super_user + /* + CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN priority_access_level_minimum <= v_priority_access_level_view THEN 1 ELSE 0 END END, + CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN priority_access_level_minimum <= v_priority_access_level_edit THEN 1 ELSE 0 END END, + CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN priority_access_level_minimum <= v_priority_access_level_admin THEN 1 ELSE 0 END END + * + FROM parts.Shop_User U + INNER JOIN Shop_User_Role_Link URL + ON U.id_user = URL.id_user + AND URL.active + INNER JOIN Shop_Role_Permission_Link RPL + ON URL.id_role = RPL.id_role + AND RPL.active + INNER JOIN Shop_Permission P + ON RPL.id_permission = P.id_permission + AND P.active + INNER JOIN Shop_Access_Level AL + ON RPL.id_access_level = AL.id_access_level + AND AL.active + WHERE U.id_user = a_id_user + AND (a_get_inactive_users OR U.active) + AND FIND_IN_SET(P.id_permission, a_ids_permission) > 0 + # AND v_id_permission = P.id_permission + # AND v_id_access_level = AL.id_access_leveld + GROUP BY U.id_user, P.id_permission # , is_super_user + ; + */ + + IF v_has_filter_user THEN + UPDATE Shop_User_Eval_Temp UE_T + INNER JOIN Shop_User U + ON UE_T.id_user = U.id_user + AND U.active + INNER JOIN Shop_User_Role_Link URL + ON U.id_user = URL.id_user + AND URL.active + INNER JOIN Shop_Role_Permission_Link RPL + ON URL.id_role = RPL.id_role + AND RPL.active + INNER JOIN Shop_Access_Level AL + ON RPL.id_access_level = AL.id_access_level + AND AL.active + SET UE_T.priority_access_level_user = AL.priority, + UE_T.is_super_user = U.is_super_user, + UE_T.can_view = CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN ISNULL(AL.priority) THEN 1 ELSE CASE WHEN AL.priority <= v_priority_access_level_view AND AL.priority <= UE_T.priority_access_level_required THEN 1 ELSE 0 END END END, + UE_T.can_edit = CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN NOT ISNULL(AL.priority) AND AL.priority <= v_priority_access_level_edit AND AL.priority <= UE_T.priority_access_level_required THEN 1 ELSE 0 END END, + UE_T.can_admin = CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN NOT ISNULL(AL.priority) AND AL.priority <= v_priority_access_level_admin AND AL.priority <= UE_T.priority_access_level_required THEN 1 ELSE 0 END END + WHERE UE_T.guid = a_guid + AND UE_T.id_user = a_id_user + AND RPL.id_permission = UE_T.id_permission_required + # GROUP BY UE_T.id_user + ; + ELSE + UPDATE Shop_User_Eval_Temp UE_T + SET UE_T.priority_access_level_user = v_priority_access_level_view, + UE_T.is_super_user = 0, + UE_T.can_view = (v_priority_access_level_view <= UE_T.priority_access_level_required), + UE_T.can_edit = 0, + UE_T.can_admin = 0 + WHERE UE_T.guid = a_guid + AND UE_T.id_user = a_id_user + # GROUP BY UE_T.id_user + ; + END IF; + END IF; + + -- Clean up + DROP TABLE IF EXISTS tmp_Shop_Product_p_Shop_User_Eval; + # DROP TEMPORARY TABLE IF EXISTS tmp_User_Role_Link; + # DROP TABLE IF EXISTS tmp_Msg_Error; +END // +DELIMITER ; + + +-- DROP TABLE IF EXISTS Shop_User_Eval_Temp; + + +/* +CALL p_shop_user_eval ( + '56c9dfc1-e22f-11ee-aab4-b42e9986184a', # a_guid + '', # a_id_user # 'auth0|6582b95c895d09a70ba10fef', + false, # a_get_inactive_users + 2, # a_ids_permission + 1, # a_ids_access_level + -- null, # a_ids_product + '1,2,3' # a_ids_permutation +); + + +SELECT * +FROM Shop_User_Eval_Temp +; + +DROP TABLE Shop_User_Eval_Temp; + + +SELECT * +FROM Shop_Permission +; + +SELECT * +FROM Shop_Access_Level +; + +SELECT * +FROM Shop_Product +; + +SELECT * +FROM Shop_Product_Permutation +; + + +*/ + +/* +SELECT 'NOODS' AS guid, + U.id_user AS id_user, + P.id_permission AS id_permission_required, + AL.id_access_level AS id_access_level_required, + /* + v_id_permission, + v_id_access_level, + * + AL.priority, # MIN(AL.priority), + U.is_super_user + /* + CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN priority_access_level_minimum <= v_priority_access_level_view THEN 1 ELSE 0 END END, + CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN priority_access_level_minimum <= v_priority_access_level_edit THEN 1 ELSE 0 END END, + CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN priority_access_level_minimum <= v_priority_access_level_admin THEN 1 ELSE 0 END END + * +FROM parts.Shop_User U +INNER JOIN Shop_User_Role_Link URL + ON U.id_user = URL.id_user + AND URL.active +INNER JOIN Shop_Role_Permission_Link RPL + ON URL.id_role = RPL.id_role + AND RPL.active +INNER JOIN Shop_Permission P + ON RPL.id_permission = P.id_permission + AND P.active +inner JOIN Shop_Access_Level AL + # ON P.id_access_level_required = AL.id_access_level + ON RPL.id_access_level = AL.id_access_level + AND AL.active +WHERE U.id_user = 'auth0|6582b95c895d09a70ba10fef' + AND U.active + AND FIND_IN_SET(P.id_permission, '1,2') > 0 + # AND v_id_access_level = AL.id_access_leveld +# GROUP BY U.id_user, P.id_permission, AL.id_access_level # , is_super_user + +*/ + +USE PARTS; + +/* + +CALL p_shop_get_many_product ( + '', # a_id_user + 1, # a_get_all_category + '', # a_ids_category + 0, # a_get_inactive_category + 1, # a_get_all_product + '', # a_ids_product + 0, # a_get_inactive_product + 0, # a_get_first_product_only + 1, # a_get_all_product_permutation + '', # a_ids_permutation + 0, # a_get_inactive_permutation + 0, # a_get_all_image + '', # a_ids_image + 0, # a_get_inactive_image + 1, # a_get_first_image_only + 1, # a_get_all_delivery_region + '', # a_ids_delivery_region + 0, # a_get_inactive_delivery_region + 1, # a_get_all_currency + '', # a_ids_currency + 0, # a_get_inactive_currency + 1, # a_get_all_discount + '', # a_ids_discount + 0 # a_get_inactive_discount +); + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_many_product; + + +DELIMITER // +CREATE PROCEDURE p_shop_get_many_product ( + IN a_id_user VARCHAR(200), + IN a_get_all_category BIT, + IN a_ids_category VARCHAR(500), + IN a_get_inactive_category BIT, + IN a_get_all_product BIT, + IN a_ids_product VARCHAR(500), + IN a_get_inactive_product BIT, + IN a_get_first_product_only BIT, + IN a_get_all_product_permutation BIT, + IN a_ids_permutation VARCHAR(4000), + IN a_get_inactive_permutation BIT, + IN a_get_all_image BIT, + IN a_ids_image VARCHAR(4000), + IN a_get_inactive_image BIT, + IN a_get_first_image_only BIT, + IN a_get_all_delivery_region BIT, + IN a_ids_delivery_region VARCHAR(4000), + IN a_get_inactive_delivery_region BIT, + IN a_get_all_currency BIT, + IN a_ids_currency VARCHAR(4000), + IN a_get_inactive_currency BIT, + IN a_get_all_discount BIT, + IN a_ids_discount VARCHAR(4000), + IN a_get_inactive_discount BIT +) +BEGIN + -- Argument redeclaration + -- Variable declaration + DECLARE v_has_filter_category BIT; + DECLARE v_has_filter_product BIT; + DECLARE v_has_filter_permutation BIT; + DECLARE v_has_filter_image BIT; + DECLARE v_has_filter_delivery_region BIT; + DECLARE v_has_filter_currency BIT; + DECLARE v_has_filter_discount BIT; + DECLARE v_guid VARCHAR(36); + # DECLARE v_id_user VARCHAR(100); + DECLARE v_ids_permutation_unavailable VARCHAR(4000); + DECLARE v_id_permission_product INT; + DECLARE v_ids_product_permission VARCHAR(4000); + DECLARE v_ids_permutation_permission VARCHAR(4000); + DECLARE v_id_access_level_view INT; + DECLARE v_now DATETIME; + DECLARE v_id_minimum INT; + + SET v_guid := UUID(); + SET v_id_access_level_view := (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'VIEW'); + + + -- Argument validation + default values + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + IF a_get_all_category IS NULL THEN + SET a_get_all_category = 0; + END IF; + IF a_ids_category IS NULL THEN + SET a_ids_category = ''; + ELSE + SET a_ids_category = REPLACE(TRIM(a_ids_category), '|', ','); + END IF; + IF a_get_inactive_category IS NULL THEN + SET a_get_inactive_category = 0; + END IF; + IF a_ids_product IS NULL THEN + SET a_ids_product = ''; + ELSE + SET a_ids_product = REPLACE(TRIM(a_ids_product), '|', ','); + END IF; + IF a_get_inactive_product IS NULL THEN + SET a_get_inactive_product = 0; + END IF; + IF a_get_first_product_only IS NULL THEN + SET a_get_first_product_only = 1; + END IF; + IF a_get_all_product IS NULL THEN + SET a_get_all_product = 0; + END IF; + IF a_ids_permutation IS NULL THEN + SET a_ids_permutation = ''; + ELSE + SET a_ids_permutation = REPLACE(TRIM(a_ids_permutation), '|', ','); + END IF; + IF a_get_inactive_permutation IS NULL THEN + SET a_get_inactive_permutation = 0; + END IF; + IF a_get_all_image IS NULL THEN + SET a_get_all_image = 1; + END IF; + IF a_ids_image IS NULL THEN + SET a_ids_image = ''; + ELSE + SET a_ids_image = REPLACE(TRIM(a_ids_image), '|', ','); + END IF; + IF a_get_inactive_image IS NULL THEN + SET a_get_inactive_image = 0; + END IF; + IF a_get_first_image_only IS NULL THEN + SET a_get_first_image_only = 0; + END IF; + IF a_get_inactive_image IS NULL THEN + SET a_get_inactive_image = 0; + END IF; + IF a_get_all_delivery_region IS NULL THEN + SET a_get_all_delivery_region = 1; + END IF; + IF a_ids_delivery_region IS NULL THEN + SET a_ids_delivery_region = ''; + ELSE + SET a_ids_delivery_region = REPLACE(TRIM(a_ids_delivery_region), '|', ','); + END IF; + IF a_get_inactive_delivery_region IS NULL THEN + SET a_get_inactive_delivery_region = 0; + END IF; + IF a_get_all_currency IS NULL THEN + SET a_get_all_currency = 1; + END IF; + IF a_ids_currency IS NULL THEN + SET a_ids_currency = ''; + ELSE + SET a_ids_currency = REPLACE(TRIM(a_ids_currency), '|', ','); + END IF; + IF a_get_inactive_currency IS NULL THEN + SET a_get_inactive_currency = 0; + END IF; + IF a_get_all_discount IS NULL THEN + SET a_get_all_discount = 1; + END IF; + IF a_ids_discount IS NULL THEN + SET a_ids_discount = ''; + ELSE + SET a_ids_discount = REPLACE(TRIM(a_ids_discount), '|', ','); + END IF; + IF a_get_inactive_discount IS NULL THEN + SET a_get_inactive_discount = 0; + END IF; + + + -- Temporary tables + DROP TABLE IF EXISTS tmp_Discount; + DROP TABLE IF EXISTS tmp_Currency; + DROP TABLE IF EXISTS tmp_Delivery_Region; + DROP TABLE IF EXISTS tmp_Shop_Image; + DROP TABLE IF EXISTS tmp_Shop_Variation; + DROP TABLE IF EXISTS tmp_Shop_Product; + DROP TABLE IF EXISTS tmp_Shop_Category; + + CREATE TABLE tmp_Shop_Category ( + id_category INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Category_id_category + FOREIGN KEY (id_category) + REFERENCES Shop_Category(id_category), + active BIT NOT NULL, + display_order INT NOT NULL, + can_view BIT, + can_edit BIT, + can_admin BIT + ); + + CREATE TABLE tmp_Shop_Product ( + id_category INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_category + FOREIGN KEY (id_category) + REFERENCES Shop_Category(id_category), + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + -- product_has_variations BIT NOT NULL, + id_permutation INT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + active_category BIT NOT NULL, + active_product BIT NOT NULL, + active_permutation BIT NULL, + display_order_category INT NOT NULL, + display_order_product INT NOT NULL, + display_order_permutation INT NULL, + rank_permutation INT NOT NULL, # _in_category + name VARCHAR(255) NOT NULL, + description VARCHAR(4000) NOT NULL, + /* + price_GBP_full FLOAT NOT NULL, + price_GBP_min FLOAT NOT NULL, + */ + latency_manufacture INT NOT NULL, + quantity_min FLOAT NOT NULL, + quantity_max FLOAT NOT NULL, + quantity_step FLOAT NOT NULL, + quantity_stock FLOAT NOT NULL, + is_subscription BIT NOT NULL, + id_recurrence_interval INT, + CONSTRAINT FK_tmp_Shop_Product_id_recurrence_interval + FOREIGN KEY (id_recurrence_interval) + REFERENCES Shop_Recurrence_Interval(id_interval), + count_recurrence_interval INT, + id_stripe_product VARCHAR(100), + product_has_variations INT NOT NULL, + can_view BIT, + can_edit BIT, + can_admin BIT + ); + + /* + CREATE TEMPORARY TABLE tmp_Shop_Variation ( + id_variation INT NOT NULL, + id_product INT NOT NULL, + display_order INT NOT NULL + ); + */ + + CREATE TABLE tmp_Shop_Image ( + id_image INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Image_id_image + FOREIGN KEY (id_image) + REFERENCES Shop_Image(id_image), + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Image_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NULL, + CONSTRAINT FK_tmp_Shop_Image_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + active BIT NOT NULL, + display_order INT NOT NULL, + rank_in_product_permutation INT NOT NULL + ); + + CREATE TABLE tmp_Delivery_Region ( + id_region INT NOT NULL, + CONSTRAINT FK_tmp_Delivery_Region_id_region + FOREIGN KEY (id_region) + REFERENCES Shop_Region(id_region), + active BIT NOT NULL, + display_order INT NOT NULL + ); + + CREATE TABLE tmp_Currency ( + id_currency INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Currency_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency), + active BIT NOT NULL, + display_order INT NOT NULL + ); + + CREATE TABLE tmp_Discount ( + id_discount INT NOT NULL, + CONSTRAINT FK_tmp_Discount_id_discount + FOREIGN KEY (id_discount) + REFERENCES Shop_Discount(id_discount), + active BIT NOT NULL, + display_order INT NOT NULL + ); + + CREATE TABLE IF NOT EXISTS tmp_Msg_Error ( # IF NOT EXISTS + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + guid VARCHAR(36) NOT NULL, + # code VARCHAR(50) NOT NULL, + # CONSTRAINT chk_tmp_Msg_Error_code CHECK (code IN (SELECT code FROM Shop_Msg_Error_Type)), + id_type INT NOT NULL, + CONSTRAINT FK_tmp_Msg_Error_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Msg_Error_Type(id_type), + msg VARCHAR(4000) NOT NULL + ); + + + -- Parse filters + SET v_has_filter_category = CASE WHEN a_ids_category = '' THEN 0 ELSE 1 END; + SET v_has_filter_product = CASE WHEN a_ids_product = '' THEN 0 ELSE 1 END; + SET v_has_filter_permutation = CASE WHEN a_ids_permutation = '' THEN 0 ELSE 1 END; + SET v_has_filter_image = CASE WHEN a_ids_image = '' THEN 0 ELSE 1 END; + SET v_has_filter_delivery_region = CASE WHEN a_ids_delivery_region = '' THEN 0 ELSE 1 END; + SET v_has_filter_currency = CASE WHEN a_ids_currency = '' THEN 0 ELSE 1 END; + SET v_has_filter_discount = CASE WHEN a_ids_discount = '' THEN 0 ELSE 1 END; + + -- select v_has_filter_product, v_has_filter_permutation; + + INSERT INTO tmp_Shop_Product ( + id_category, + id_product, + id_permutation, + active_category, + active_product, + active_permutation, + display_order_category, + display_order_product, + display_order_permutation, + rank_permutation, + name, + description, + /* + price_GBP_VAT_incl, + price_GBP_VAT_excl, + price_GBP_min, + */ + latency_manufacture, + quantity_min, + quantity_max, + quantity_step, + quantity_stock, + is_subscription, + id_recurrence_interval, + count_recurrence_interval, + id_stripe_product, + product_has_variations + ) + SELECT + P.id_category, + P.id_product, + -- P.has_variations AS product_has_variations, + PP.id_permutation, + C.active AS active_category, + P.active AS active_product, + PP.active AS active_permutation, + C.display_order AS display_order_category, + P.display_order AS display_order_product, + PP.display_order AS display_order_permutation, + RANK() OVER (ORDER BY C.display_order, P.display_order, PP.display_order) AS rank_permutation, #PARTITION BY P.id_category # _in_category + P.name, + PP.description, + /* + PP.price_GBP_VAT_incl, + PP.price_GBP_VAT_excl, + PP.price_GBP_min, + */ + PP.latency_manufacture, + PP.quantity_min, + PP.quantity_max, + PP.quantity_step, + PP.quantity_stock, + PP.is_subscription, + PP.id_recurrence_interval, + PP.count_recurrence_interval, + PP.id_stripe_product, + P.has_variations + FROM Shop_Product P + INNER JOIN Shop_Product_Permutation PP + ON P.id_product = PP.id_product + INNER JOIN Shop_Category C + ON P.id_category = C.id_category + WHERE + # permutations + ( + ( + a_get_all_product_permutation + OR v_has_filter_permutation AND FIND_IN_SET(PP.id_permutation, a_ids_permutation) > 0 + ) + AND (a_get_inactive_permutation OR PP.active) + ) + # categories + AND ( + ( + a_get_all_category + OR v_has_filter_category AND FIND_IN_SET(P.id_category, a_ids_category) > 0 + ) + AND (a_get_inactive_category OR C.active) + ) + # products + AND ( + ( + a_get_all_product + OR v_has_filter_product AND FIND_IN_SET(P.id_product, a_ids_product) > 0 + ) + AND (a_get_inactive_product OR P.active) + ) + ; + + -- select * from tmp_Shop_Product; + + IF a_get_first_product_only THEN + DELETE FROM tmp_Shop_Product t_P + WHERE t_P.rank_permutation > 1 + ; + END IF; + + INSERT INTO tmp_Shop_Category ( + id_category, + active, + display_order + ) + SELECT DISTINCT C.id_category, + C.active, + C.display_order + FROM tmp_Shop_Product t_P + INNER JOIN Shop_Category C + ON t_P.id_category = C.id_category + ORDER BY C.display_order + ; + + /* + INSERT INTO tmp_Shop_Variation ( + id_variation, id_product # , display_order + ) + SELECT P.id_variation, P.id_product # , P.display_order + FROM Shop_Variation V + INNER JOIN tmp_Shop_Product t_P + ON V.id_product = t_P.id_product + WHERE V.active; + */ + + # Product Images + INSERT INTO tmp_Shop_Image ( + id_product, + id_permutation, + id_image, + active, + display_order, + rank_in_product_permutation + ) + SELECT id_product, + id_permutation, + id_image, + active, + ROW_NUMBER() OVER (ORDER BY display_order_product_temp, display_order_image), + RANK() OVER (PARTITION BY id_product, id_permutation ORDER BY display_order_product_temp, display_order_image) + FROM ( + SELECT t_P.id_product, + I.id_permutation, + I.id_image, + I.active, + I.display_order AS display_order_image, + t_P.rank_permutation AS display_order_product_temp + FROM Shop_Image I + INNER JOIN tmp_Shop_Product t_P + ON I.id_product = t_P.id_product + AND NOT t_P.product_has_variations + UNION + SELECT t_P.id_product, + I.id_permutation, + I.id_image, + I.active, + I.display_order AS display_order_image, + t_P.rank_permutation AS display_order_product_temp + FROM Shop_Image I + INNER JOIN tmp_Shop_Product t_P + ON I.id_permutation = t_P.id_permutation + AND t_P.product_has_variations + ) IPP + WHERE (a_get_all_image OR a_get_first_image_only OR FIND_IN_SET(id_image, a_ids_image) > 0) + AND (a_get_inactive_image OR IPP.active) + ; + + IF a_get_first_image_only THEN + DELETE FROM tmp_Shop_Image + WHERE rank_in_product_permutation > 1 + ; + END IF; + + /* + IF v_has_filter_image THEN + DELETE FROM tmp_Shop_Product + WHERE id_product NOT IN (SELECT DISTINCT id_product FROM tmp_Shop_Image); + DELETE FROM tmp_Shop_Category + WHERE id_category NOT IN (SELECT DISTINCT id_category FROM tmp_Shop_Product); + END IF; + */ + + # Delivery Regions + INSERT INTO tmp_Delivery_Region ( + id_region, + active, + display_order + ) + WITH RECURSIVE Recursive_CTE_Delivery_Region AS ( + SELECT + DR.id_region AS id_region_parent, + NULL AS id_region_child + FROM Shop_Region DR + INNER JOIN Shop_Product_Delivery_Option_Link PDOL + ON DR.id_region = PDOL.id_region + INNER JOIN tmp_Shop_Product t_P + ON PDOL.id_product = t_P.id_product + AND PDOL.id_permutation <=> t_P.id_permutation + WHERE + ( + a_get_all_delivery_region + OR FIND_IN_SET(DR.id_region, a_ids_delivery_region) > 0 + ) + AND ( + a_get_inactive_delivery_region + OR DR.active + ) + UNION + SELECT + DRB.id_region_parent, + DRB.id_region_child + FROM Shop_Region_Branch DRB + INNER JOIN Recursive_CTE_Delivery_Region r_DR + ON DRB.id_region_parent = r_DR.id_region_child + AND ( + a_get_inactive_delivery_region + OR DRB.active + ) + ) + SELECT + DR.id_region, + DR.active, + DR.display_order + FROM Shop_Region DR + INNER JOIN Recursive_CTE_Delivery_Region r_DR + ON DR.id_region = r_DR.id_region_parent + OR DR.id_region = r_DR.id_region_child + ; + + IF v_has_filter_delivery_region THEN + SET v_ids_permutation_unavailable = ( + SELECT GROUP_CONCAT(t_P.id_permutation SEPARATOR ', ') + FROM tmp_Shop_Product t_P + INNER JOIN Shop_Product_Currency_Region_Link PCRL + ON t_P.id_permutation = PCRL.id_permutation + LEFT JOIN tmp_Delivery_Region t_DR + ON PCRL.id_region_purchase = t_DR.id_region + WHERE ISNULL(t_DR.id_region) + ); + IF NOT ISNULL(v_ids_permutation_unavailable) THEN + INSERT INTO tmp_Msg_Error ( + guid, + id_type, + msg + ) + VALUES ( + v_guid, + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'PRODUCT_AVAILABILITY' LIMIT 1), + CONCAT('Error: The following permutation IDs are not available in this region: ', v_ids_permutation_unavailable) + ); + END IF; + /* + DELETE FROM tmp_Shop_Product t_P + WHERE t_P.id_permutation NOT IN ( + SELECT + id_permutation + FROM Shop_Product_Currency_Region_Link PCL + INNER JOIN tmp_Delivery_Region t_DR + ON PCRL.id_region_purchase = t_DR.id_region + ); + */ + END IF; + + select * from tmp_Shop_Product; + + # Currencies + INSERT INTO tmp_Currency ( + id_currency, + active, + display_order + ) + SELECT + C.id_currency, + C.active, + C.display_order + FROM Shop_Product_Currency_Region_Link PCRL + INNER JOIN Shop_Currency C ON PCRL.id_currency = C.id_currency + /* + LEFT JOIN Shop_Discount_Region_Currency_Link DRCL ON C.id_currency = DRCL.id_currency + LEFT JOIN Shop_Discount D ON DRCL.id_discount = D.id_discount + INNER JOIN tmp_Shop_Product t_P + ON D.id_product = t_P.id_product + AND D.id_permutation <=> t_P.id_permutation + INNER JOIN tmp_Delivery_Region t_DR ON DRCL.id_region = t_DR.id_region + INNER JOIN Shop_Product_Currency_Region_Link PCRL ON C.id_currency = PCRL.id_currency + */ + INNER JOIN tmp_Shop_Product t_P + ON PCRL.id_product <=> t_P.id_product + AND PCRL.id_permutation <=> t_P.id_permutation + INNER JOIN tmp_Delivery_Region t_DR ON PCRL.id_region_purchase = t_DR.id_region + WHERE + ( + a_get_all_currency + OR FIND_IN_SET(C.id_currency, a_ids_currency) > 0 + ) + AND ( + a_get_inactive_currency + OR ( + C.active + AND PCRL.active + ) + ) + ; + + select * from tmp_Currency; + + IF v_has_filter_currency THEN + SET v_ids_permutation_unavailable = ( + SELECT GROUP_CONCAT(t_P.id_permutation SEPARATOR ', ') + FROM tmp_Shop_Product t_P + LEFT JOIN ( + SELECT * + FROM Shop_Product_Currency_Region_Link PCRL + WHERE + ( + a_get_all_currency + OR FIND_IN_SET(PCRL.id_currency, a_ids_currency) > 0 + ) + ) PCRL + ON t_P.id_permutation = PCRL.id_permutation + LEFT JOIN tmp_Currency t_C + ON PCRL.id_currency = t_C.id_currency + WHERE ISNULL(t_C.id_currency) + ); + IF NOT ISNULL(v_ids_permutation_unavailable) THEN + INSERT INTO tmp_Msg_Error ( + guid, + id_type, + msg + ) + VALUES ( + v_guid, + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'PRODUCT_AVAILABILITY' LIMIT 1), + CONCAT('Error: The following permutation IDs are not available in this currency: ', v_ids_permutation_unavailable) + ); + END IF; + /* + DELETE FROM tmp_Shop_Product t_P + WHERE t_P.id_permutation NOT IN ( + SELECT + id_permutation + FROM Shop_Product_Currency_Region_Link PCL + INNER JOIN tmp_Currency t_C + ON PCRL.id_currency = t_C.id_currency + ); + */ + END IF; + + # Discounts + INSERT INTO tmp_Discount ( + id_discount, + active, + display_order + ) + SELECT + D.id_discount, + D.active, + D.display_order + FROM Shop_Discount D + INNER JOIN tmp_Shop_Product t_P + ON D.id_product = t_P.id_product + AND D.id_permutation <=> t_P.id_permutation + WHERE + ( + a_get_all_discount + OR FIND_IN_SET(D.id_discount, a_ids_discount) > 0 + ) + AND ( + a_get_inactive_discount + OR D.active + ) + ; + + # select 'pre-permission results'; + # select * from tmp_Shop_Product; + + -- Permissions + IF EXISTS (SELECT * FROM tmp_Shop_Category LIMIT 1) THEN + # SET v_id_user := (SELECT id_user FROM Shop_User WHERE name = CURRENT_USER()); + SET v_id_permission_product := (SELECT id_permission FROM Shop_Permission WHERE code = 'STORE_PRODUCT' LIMIT 1); + -- SET v_ids_product_permission := (SELECT GROUP_CONCAT(id_product SEPARATOR ',') FROM tmp_Shop_Product); + SET v_ids_permutation_permission := (SELECT GROUP_CONCAT(id_permutation SEPARATOR ',') FROM tmp_Shop_Product WHERE NOT ISNULL(id_permutation)); + + -- SELECT v_guid, a_id_user, false, v_id_permission_product, v_id_access_level_view, v_ids_permutation_permission; + -- select * from Shop_User_Eval_Temp; + + CALL p_shop_user_eval(v_guid, a_id_user, false, v_id_permission_product, v_id_access_level_view, v_ids_permutation_permission); + + -- select * from Shop_User_Eval_Temp; + + UPDATE tmp_Shop_Product t_P + INNER JOIN Shop_User_Eval_Temp UE_T + ON t_P.id_permutation = UE_T.id_permutation + AND UE_T.GUID = v_guid + SET t_P.can_view = UE_T.can_view, + t_P.can_edit = UE_T.can_edit, + t_P.can_admin = UE_T.can_admin; + + DELETE FROM tmp_Shop_Product t_P + WHERE + FIND_IN_SET(t_P.id_product, (SELECT GROUP_CONCAT(UET.id_product SEPARATOR ',') FROM Shop_User_Eval_Temp UET)) = 0 # id_product NOT LIKE CONCAT('%', (SELECT GROUP_CONCAT(id_product SEPARATOR '|') FROM Shop_User_Eval_Temp), '%'); + OR ( + ISNULL(t_P.can_view) + AND ( + NOT v_has_filter_category + OR FIND_IN_SET(t_P.id_category, a_ids_category) = 0 + ) + AND ( + NOT v_has_filter_product + OR FIND_IN_SET(t_P.id_product, a_ids_product) = 0 + ) + AND ( + NOT v_has_filter_permutation + OR FIND_IN_SET(t_P.id_permutation, a_ids_permutation) = 0 + ) + ) + ; + + # CALL p_shop_user_eval_clear_temp(v_guid); + # DROP TABLE IF EXISTS Shop_User_Eval_Temp; + DELETE FROM Shop_User_Eval_Temp + WHERE GUID = v_guid + ; + END IF; + + + -- select * from tmp_Shop_Product; + + -- Returns + SET v_now := NOW(); + + # Categories + SELECT + DISTINCT t_C.id_category, + C.name, + C.description, + C.display_order + FROM tmp_Shop_Category t_C + INNER JOIN Shop_Category C + ON t_C.id_category = C.id_category + INNER JOIN tmp_Shop_Product t_P + ON t_C.id_category = t_P.id_category + ORDER BY C.display_order + ; + + # Products + SELECT + t_P.id_product, + t_P.id_permutation, + t_P.name, + t_P.description, + P.has_variations, + P.id_category, + t_P.latency_manufacture, + t_P.quantity_min, + t_P.quantity_max, + t_P.quantity_step, + t_P.quantity_stock, + t_P.id_stripe_product, + t_P.is_subscription, + RI.name AS name_recurrence_interval, + RI.name_plural AS name_plural_recurrence_interval, + t_P.count_recurrence_interval, + t_P.display_order_category, + t_P.display_order_product, + t_P.display_order_permutation, + IFNULL(t_P.can_view, 0), + IFNULL(t_P.can_edit, 0), + IFNULL(t_P.can_admin, 0) + FROM tmp_Shop_Product t_P + INNER JOIN Shop_Product P + ON t_P.id_product = P.id_product + LEFT JOIN Shop_Recurrence_Interval RI + ON t_P.id_recurrence_interval = RI.id_interval + ORDER BY t_P.rank_permutation + ; + + # Variations + SELECT + V.id_variation, + t_P.id_product, + t_P.id_permutation, + t_P.id_category, + VT.code AS code_variation_type, + VT.name AS name_variation_type, + V.code AS code_variation, + V.name AS name_variation, + RANK() OVER (ORDER BY t_P.rank_permutation, PPVL.display_order) AS display_order + FROM Shop_Variation V + INNER JOIN Shop_Variation_Type VT + ON V.id_type = VT.id_type + INNER JOIN Shop_Product_Permutation_Variation_Link PPVL ON V.id_variation = PPVL.id_variation + INNER JOIN tmp_Shop_Product t_P ON PPVL.id_permutation <=> t_P.id_permutation + WHERE V.active + AND PPVL.active + ; + + /* + # Permutation variations output + SELECT t_P.id_permutation, + t_P.id_product, + t_P.id_category, + id_variation + FROM Shop_Product_Permutation_Variation_Link PPVL + INNER JOIN tmp_Shop_Product t_P + ON t_P.id_permutation = PPVL.id_permutation + ORDER BY t_P.display_order + ; + */ + + # Product Price + SELECT + PCRL.id_link AS id_price, + t_P.id_permutation, + t_P.id_product, + t_P.id_category, + t_C.id_currency, + C.code AS code_currency, + C.name AS name_currency, + C.symbol AS symbol_currency, + t_DR.id_region, + PCRL.price_local_VAT_incl, + PCRL.price_local_VAT_excl, + ROW_NUMBER() OVER(ORDER BY t_P.rank_permutation, C.display_order) AS display_order + FROM Shop_Product_Currency_Region_Link PCRL + INNER JOIN tmp_Shop_Product t_P + ON t_P.id_product = PCRL.id_product + AND t_P.id_permutation <=> PCRL.id_permutation + -- INNER JOIN Shop_Product P ON PCRL.id_product = P.id_product + INNER JOIN tmp_Currency t_C ON PCRL.id_currency = t_C.id_currency + INNER JOIN Shop_Currency C ON t_C.id_currency = C.id_currency + INNER JOIN tmp_Delivery_Region t_DR ON PCRL.id_region_purchase = t_DR.id_region + WHERE ( + a_get_inactive_product + AND a_get_inactive_permutation + AND a_get_inactive_currency + AND a_get_inactive_delivery_region + OR PCRL.active + ) + ORDER BY t_P.rank_permutation + ; + + /* + # Currency + SELECT + DISTINCT C.id_currency, + C.code, + C.name, + C.factor_from_GBP, + t_C.display_order + FROM Shop_Currency C + INNER JOIN tmp_Currency t_C ON C.id_currency = t_C.id_currency + GROUP BY C.id_currency, t_C.display_order + ORDER BY t_C.display_order + ; + */ + + # Images + SELECT + t_I.id_image, + t_I.id_product, + t_I.id_permutation, + t_P.id_category, + I.url, + I.active, + I.display_order + FROM tmp_Shop_Image t_I + INNER JOIN Shop_Image I + ON t_I.id_image = I.id_image + INNER JOIN tmp_Shop_Product t_P + ON t_I.id_product = t_P.id_product + AND t_I.id_permutation <=> t_P.id_permutation + ORDER BY t_P.rank_permutation, I.display_order + ; + + # Delivery options + SELECT + _DO.id_option, + PDOL.id_product, + PDOL.id_permutation, + t_P.id_category, + _DO.code, + _DO.name, + _DO.latency_delivery_min, + _DO.latency_delivery_max, + _DO.quantity_min, + _DO.quantity_max, + GROUP_CONCAT(DR.code SEPARATOR ',') AS codes_region, + GROUP_CONCAT(DR.name SEPARATOR ',') AS names_region, + PDOL.price_local, + PDOL.display_order + FROM Shop_Delivery_Option _DO + INNER JOIN Shop_Product_Delivery_Option_Link PDOL + ON _DO.id_option = PDOL.id_delivery_option + AND ( + a_get_inactive_delivery_region + OR PDOL.active + ) + INNER JOIN tmp_Shop_Product t_P + ON PDOL.id_product = t_P.id_product + AND PDOL.id_permutation <=> t_P.id_permutation + INNER JOIN tmp_Delivery_Region t_DR ON PDOL.id_region = t_DR.id_region + INNER JOIN Shop_Region DR ON t_DR.id_region = DR.id_region + WHERE ( + a_get_inactive_delivery_region + OR _DO.active + ) + GROUP BY t_P.id_category, t_P.id_product, PDOL.id_permutation, t_P.rank_permutation, DR.id_region, _DO.id_option, PDOL.id_link + ORDER BY t_P.rank_permutation, PDOL.display_order + ; + + # Discounts + SELECT + D.id_discount, + P.id_category, + D.id_product, + D.id_permutation, + DR.id_region, + C.id_currency, + D.code AS code_discount, + D.name AS name_discount, + D.multiplier, + D.subtractor, + D.apply_multiplier_first, + D.quantity_min, + D.quantity_max, + D.date_start, + D.date_end, + GROUP_CONCAT(DR.code) AS codes_region, + GROUP_CONCAT(DR.name) AS names_region, + GROUP_CONCAT(C.code) AS codes_currency, + GROUP_CONCAT(C.name) AS names_currency, + ROW_NUMBER() OVER(ORDER BY D.display_order) AS display_order + FROM tmp_Discount t_D + INNER JOIN Shop_Discount D ON t_D.id_discount = D.id_discount + INNER JOIN Shop_Product P ON D.id_product = P.id_product + INNER JOIN tmp_Shop_Product t_P + ON D.id_product = t_P.id_product + -- AND D.id_permutation <=> t_P.id_permutation + INNER JOIN Shop_Discount_Region_Currency_Link DRCL + ON D.id_discount = DRCL.id_discount + INNER JOIN tmp_Delivery_Region t_DR ON DRCL.id_region = t_DR.id_region + INNER JOIN Shop_Region DR ON t_DR.id_region = DR.id_region + INNER JOIN tmp_Currency t_C ON DRCL.id_currency = t_C.id_currency + INNER JOIN Shop_Currency C ON t_C.id_currency = C.id_currency + GROUP BY D.id_discount, DR.id_region, C.id_currency + ORDER BY D.display_order, DR.display_order, C.display_order + ; + + /* + # Delivery Regions + SELECT + t_DR.id_region, + t_P.id_category, + t_P.id_product, + t_P.id_permutation, + DR.code, + DR.name + FROM tmp_Delivery_Region t_DR + INNER JOIN Shop_Delivery_Region DR ON t_DR.id_region = DR.id_region + INNER JOIN Shop_Product_Region_Currency_Link PDRL + ON DR.id_region = PDRL.id_region + AND ( + a_get_inactive_delivery_region + OR PDRL.active + ) + INNER JOIN tmp_Shop_Product t_P + ON PDRL.id_product = t_P.id_product + AND PDRL.id_permutation <=> t_P.id_permutation + INNER JOIN tmp_Currency t_C ON PDRL.id_currency = t_C.id_currency + ORDER BY t_DR.display_order + ; + */ + + # Errors + SELECT + t_ME.display_order, + t_ME.guid, + t_ME.id_type, + t_ME.msg, + MET.code, + MET.name, + MET.description + FROM tmp_Msg_Error t_ME + INNER JOIN Shop_Msg_Error_Type MET + ON t_ME.id_type = MET.id_type + WHERE guid = v_guid + ; + + /* + # Return arguments for test + SELECT + a_ids_category, + a_get_inactive_category, + a_ids_product, + a_get_inactive_product, + a_get_first_product_only, + a_get_all_product, + a_ids_image, + a_get_inactive_image, + a_get_first_image_only, + a_get_all_image + ; + */ + + # select 'other outputs'; + # select * from tmp_Shop_Product; + + -- Clean up + DROP TABLE IF EXISTS tmp_Discount; + DROP TABLE IF EXISTS tmp_Currency; + DROP TABLE IF EXISTS tmp_Delivery_Region; + DROP TABLE IF EXISTS tmp_Shop_Image; + DROP TABLE IF EXISTS tmp_Shop_Variation; + DROP TABLE IF EXISTS tmp_Shop_Product; + DROP TABLE IF EXISTS tmp_Shop_Category; +END // +DELIMITER ; + + +/* + +CALL p_shop_get_many_product ( + '', # a_id_user + 1, # a_get_all_category + '', # a_ids_category + 0, # a_get_inactive_category + 1, # a_get_all_product + '', # a_ids_product + 0, # a_get_inactive_product + 0, # a_get_first_product_only + 1, # a_get_all_product_permutation + '', # a_ids_permutation + 0, # a_get_inactive_permutation + 0, # a_get_all_image + '', # a_ids_image + 0, # a_get_inactive_image + 1, # a_get_first_image_only + 0, # a_get_all_delivery_region + '1', # a_ids_delivery_region + 0, # a_get_inactive_delivery_region + 0, # a_get_all_currency + '2', # a_ids_currency + 0, # a_get_inactive_currency + 1, # a_get_all_discount + '', # a_ids_discount + 0 # a_get_inactive_discount +); + +select * from shop_image; +select * from shop_product; +select * from TMP_MSG_ERROR; +DROP TABLE TMP_MSG_ERROR; + +insert into shop_product_change_set (comment) + values ('set product not subscription - test bool output to python'); + update shop_product + set is_subscription = 0, + id_change_set = (select id_change_set from shop_product_change_set order by id_change_set desc limit 1) + where id_product = 1 +*/ + +USE PARTS; + +/* + +CALL p_shop_edit_user ( + 'auth0|6582b95c895d09a70ba10fef', # a_id_user + '', # a_name + '', # a_email + 0 # a_email_verified +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_edit_user; + + +DELIMITER // +CREATE PROCEDURE p_shop_edit_user ( + IN a_id_user VARCHAR(200), + IN a_name VARCHAR(255), + IN a_email VARCHAR(254), + IN a_email_verified BIT +) +BEGIN + -- Argument redeclaration + -- Variable declaration + DECLARE v_has_filter_user BIT; + -- DECLARE v_now DATETIME; + + + -- Argument validation + default values + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + IF a_name IS NULL THEN + SET a_name = ''; + ELSE + SET a_name = TRIM(a_name); + END IF; + IF a_email IS NULL THEN + SET a_email = ''; + ELSE + SET a_email = TRIM(a_email); + END IF; + IF a_email_verified IS NULL THEN + SET a_email_verified = 0; + END IF; + + -- Temporary tables + DROP TABLE IF EXISTS tmp_Msg_Error; + DROP TABLE IF EXISTS tmp_Shop_User; + + CREATE TABLE tmp_Shop_User ( + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_tmp_Shop_User_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user), + active BIT NOT NULL + ); + + CREATE TABLE tmp_Msg_Error ( + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + id_type INT NOT NULL, + # code VARCHAR(50) NOT NULL, + # CONSTRAINT chk_tmp_Msg_Error_code CHECK (code IN (SELECT code FROM Shop_Msg_Error_Type)), + CONSTRAINT FK_tmp_Msg_Error_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Msg_Error_Type(id_type), + msg VARCHAR(4000) NOT NULL + ); + + + -- Parse filters + SET v_has_filter_user = CASE WHEN a_id_user = '' THEN 0 ELSE 1 END; + + + -- User + IF v_has_filter_user THEN + INSERT INTO tmp_Shop_User ( + id_user, + active + ) + SELECT id_user, + active + FROM Shop_User + WHERE id_user LIKE CONCAT('%', a_id_user, '%') + AND active + LIMIT 1 + ; + + IF NOT EXISTS (SELECT id_user FROM tmp_Shop_User LIMIT 1) THEN + INSERT INTO Shop_User ( + id_user, + name, + email, + email_verified + ) + VALUES ( + a_id_user, + a_name, + a_email, + a_email_verified + ); + + INSERT INTO tmp_Shop_User ( + id_user, + active + ) + SELECT id_user, + active + FROM Shop_User + WHERE id_user LIKE CONCAT('%', a_id_user, '%') + AND active + LIMIT 1 + ; + END IF; + + SET a_id_user := (SELECT id_user FROM tmp_Shop_User LIMIT 1); + ELSE + INSERT INTO tmp_Msg_Error ( + id_type, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + 'No user ID provided.' + ) + ; + END IF; + + + /* + IF NOT EXISTS (SELECT msg FROM tmp_Msg_Error LIMIT 1) THEN + END IF; + */ + + + -- Returns + # User + SELECT * + FROM tmp_Shop_User + ; + + # Errors + SELECT * + FROM tmp_Msg_Error + ; + + /* + # Return arguments for test + SELECT a_id_user, + a_name, + a_email, + a_email_verified + ; + */ + + -- Clean up + DROP TABLE IF EXISTS tmp_Msg_Error; + DROP TABLE IF EXISTS tmp_Shop_User; +END // +DELIMITER ; + + + +/* + +CALL p_shop_edit_user ( + '', + '', + '', + 0 +) + +*/ + +USE PARTS; + +/* + +CALL p_shop_get_many_currency ( + 0 # a_get_inactive_currency +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_many_currency; + + +DELIMITER // +CREATE PROCEDURE p_shop_get_many_currency ( + IN a_get_inactive_currency BIT +) +BEGIN + IF a_get_inactive_currency IS NULL THEN + SET a_get_inactive_currency = 0; + END IF; + + SELECT + C.id_currency, + C.code, + C.name, + C.factor_from_GBP, + C.active, + C.display_order + FROM Shop_Currency C + WHERE a_get_inactive_currency + OR C.active + ORDER BY C.display_order + ; +END // +DELIMITER ; + + +CALL p_shop_get_many_currency ( + 0 # a_get_inactive_currency +); + +USE PARTS; + +/* + +CALL p_shop_get_many_region ( + 0 # a_get_inactive_region +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_many_region; + + +DELIMITER // +CREATE PROCEDURE p_shop_get_many_region ( + IN a_get_inactive_region BIT +) +BEGIN + IF a_get_inactive_region IS NULL THEN + SET a_get_inactive_region = 0; + END IF; + + SELECT + R.id_region, + R.code, + R.name, + R.active, + R.display_order + FROM Shop_Region R + WHERE a_get_inactive_region + OR R.active + ORDER BY R.display_order + ; +END // +DELIMITER ; + +CALL p_shop_get_many_region ( + 0 # a_get_inactive_region +); + +USE PARTS; + +/* + +CALL p_shop_edit_user_basket ( + '', # a_id_user + '', # a_ids_permutation_basket + '', # a_quantities_permutation_basket + 1, # a_id_permutation_edit + NULL, # a_quantity_permutation_edit + 1, # a_sum_not_edit + 1, # a_id_currency_edit + 1 # a_id_region_purchase +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_edit_user_basket; + + +DELIMITER // +CREATE PROCEDURE p_shop_edit_user_basket ( + IN a_id_user VARCHAR(200), + IN a_ids_permutation_basket VARCHAR(4000), + IN a_quantities_permutation_basket VARCHAR(4000), + IN a_id_permutation_edit INT, + IN a_quantity_permutation_edit INT, + IN a_sum_not_edit BIT, + IN a_id_currency INT, + IN a_id_region_purchase INT +) +BEGIN + -- Argument redeclaration + -- Variable declaration + DECLARE v_has_filter_user BIT; + DECLARE v_has_filter_permutation_basket BIT; + DECLARE v_has_filter_permutation_edit BIT; + DECLARE v_has_filter_region BIT; + DECLARE v_has_filter_currency BIT; + DECLARE v_n_id_permutation_basket INT; + DECLARE v_n_quantity_permutation_basket INT; + DECLARE v_row_number INT; + DECLARE v_guid VARCHAR(36); + # DECLARE v_id_user VARCHAR(100); + DECLARE v_id_permission_product INT; + DECLARE v_ids_permutation_permission VARCHAR(4000); + DECLARE v_now DATETIME; + # DECLARE v_quantity_new INT; + DECLARE v_change_set_used BIT; + DECLARE v_id_change_set INT; + + SET v_guid = UUID(); + + -- Argument validation + default values + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + IF a_ids_permutation_basket IS NULL THEN + SET a_ids_permutation_basket = ''; + ELSE + SET a_ids_permutation_basket = TRIM(a_ids_permutation_basket); + END IF; + IF a_quantities_permutation_basket IS NULL THEN + SET a_quantities_permutation_basket = ''; + ELSE + SET a_quantities_permutation_basket = TRIM(a_quantities_permutation_basket); + END IF; + IF a_sum_not_edit IS NULL THEN + SET a_sum_not_edit = 1; + END IF; + + -- Temporary tables + DROP TABLE IF EXISTS tmp_Msg_Error; + DROP TABLE IF EXISTS tmp_Shop_Basket; + DROP TEMPORARY TABLE IF EXISTS tmp_Shop_Quantity; + DROP TABLE IF EXISTS tmp_Shop_Product; + DROP TABLE IF EXISTS tmp_Shop_User; + + CREATE TABLE tmp_Shop_User ( + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_tmp_Shop_User_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user), + active BIT NOT NULL + ); + + CREATE TABLE tmp_Shop_Product ( + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + display_order INT NOT NULL, + active INT NOT NULL DEFAULT 1 + ); + + CREATE TEMPORARY TABLE tmp_Shop_Quantity( + quantity INT NOT NULL, + display_order INT NOT NULL, + active INT NOT NULL DEFAULT 1 + ); + + CREATE TABLE tmp_Shop_Basket ( + id_category INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Basket_id_category + FOREIGN KEY (id_category) + REFERENCES Shop_Category(id_category), + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Basket_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Basket_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + id_region_purchase INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Basket_id_region_purchase + FOREIGN KEY (id_region_purchase) + REFERENCES Shop_Region(id_region), + id_currency INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Basket_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency), + quantity INT NOT NULL, + active BIT NOT NULL DEFAULT 1 + /* + display_order_category INT NOT NULL, + display_order_product INT NOT NULL + */ + ); + + CREATE TABLE IF NOT EXISTS tmp_Msg_Error ( + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + guid VARCHAR(36) NOT NULL, + id_type INT NOT NULL, + # code VARCHAR(50) NOT NULL, + # CONSTRAINT chk_tmp_Msg_Error_code CHECK (code IN (SELECT code FROM Shop_Msg_Error_Type)), + CONSTRAINT FK_tmp_Msg_Error_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Msg_Error_Type(id_type), + msg VARCHAR(4000) NOT NULL + ); + + + -- Parse filters + SET v_has_filter_user = NOT (a_id_user = ''); + SET v_has_filter_permutation_basket = NOT (a_ids_permutation_basket = ''); + SET v_has_filter_permutation_edit = NOT ISNULL(a_id_permutation_edit); + SET v_has_filter_currency = NOT ISNULL(a_id_currency); + SET v_has_filter_region = NOT ISNULL(a_id_region_purchase); + # SET v_quantity_new = CASE WHEN a_sum_not_edit THEN quantity + a_quantity_product_edit ELSE a_quantity_product_edit END; + /* + SELECT v_has_filter_user, v_has_filter_basket + ; + + */ + + -- Currency + IF NOT v_has_filter_currency THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + 'Currency ID not provided.' + ) + ; + END IF; + IF v_has_filter_currency AND NOT EXISTS ( SELECT * FROM Shop_Currency WHERE id_currency = a_id_currency) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('Currency ID not found: ', a_id_currency, '.') + ) + ; + END IF; + + -- Region + IF NOT v_has_filter_region THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + 'Region ID not provided.' + ) + ; + END IF; + IF v_has_filter_region AND NOT EXISTS ( SELECT * FROM Shop_Region WHERE id_region = a_id_region_purchase) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('Region ID not found: ', a_id_region_purchase, '.') + ) + ; + END IF; + + -- User + IF v_has_filter_user THEN + INSERT INTO tmp_Shop_User ( + id_user, + active + ) + SELECT id_user, + active + FROM Shop_User + WHERE id_user LIKE CONCAT('%', a_id_user, '%') + AND active + LIMIT 1 + ; + + IF NOT EXISTS (SELECT id_user FROM tmp_Shop_User LIMIT 1) THEN + SET v_has_filter_user = 0; + + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('User ID not found: ', a_id_user, '.') + ) + ; + END IF; + + SET a_id_user := (SELECT id_user FROM tmp_Shop_User LIMIT 1); + END IF; + + IF v_has_filter_user AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + SET v_change_set_used = 0; + INSERT INTO Shop_User_Change_Set ( + comment + ) + VALUES ( + 'edit basket' + ); + SET v_id_change_set := (SELECT id_change_set FROM Shop_User_Change_Set ORDER BY id_change_set DESC LIMIT 1); + END IF; + + -- Get basket + -- User + IF v_has_filter_user AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + INSERT INTO tmp_Shop_Basket ( + id_category, + id_product, + id_permutation, + id_region_purchase, + id_currency, + quantity, + active + /* + display_order_category, + display_order_product + */ + ) + SELECT + C.id_category, + UB.id_product, + UB.id_permutation, + UB.id_region_purchase, + UB.id_currency, + UB.quantity, + UB.active + /* + C.display_order, + P.display_order + */ + FROM Shop_User_Basket UB + /* + INNER JOIN tmp_Shop_User t_U + ON UB.id_user = t_U.id_user + */ + INNER JOIN Shop_Product_Permutation PP + ON UB.id_product = PP.id_product + AND PP.active + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + AND P.active + INNER JOIN Shop_Category C + ON P.id_category = C.id_category + AND C.active + WHERE UB.id_user = a_id_user + ; + END IF; + + -- Currency + IF EXISTS (SELECT * FROM tmp_Shop_Basket WHERE active LIMIT 1) + AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + IF EXISTS (SELECT * FROM tmp_Shop_Basket WHERE active AND id_currency != a_id_currency) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT( + 'Currency ID does not match currency of other items in basket. Basket currency: ', + (SELECT code FROM Shop_Currency WHERE id_currency = ( + SELECT + id_currency + FROM tmp_Shop_Basket + WHERE active + AND id_currency != a_id_currency + LIMIT 1 + )), + ', new currency: ', + (SELECT code FROM Shop_Currency WHERE id_currency = a_id_currency), + '.' + ) + ) + ; + END IF; + END IF; + + -- Region + IF EXISTS (SELECT * FROM tmp_Shop_Basket WHERE active LIMIT 1) + AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + IF EXISTS ( + SELECT * + FROM tmp_Shop_Basket + WHERE + active + AND id_region_purchase != a_id_region_purchase + ) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('Purchase region ID does not match region of other items in basket. Basket currency: ', + (SELECT code FROM Shop_Region WHERE id_region = ( + SELECT + id_region_purchase + FROM tmp_Shop_Basket + WHERE active + AND id_region != a_id_region_purchase + LIMIT 1 + )), + ', new currency: ', + (SELECT code FROM Shop_Region WHERE id_region = a_id_region_purchase), + '.' + ) + ) + ; + END IF; + END IF; + + -- String product id, permutation id, quantity list + IF NOT EXISTS (SELECT * FROM tmp_Shop_Basket WHERE active LIMIT 1) AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN -- NOT v_has_filter_user AND + # Get product ids + CALL p_split(a_ids_permutation_basket, ','); + INSERT INTO tmp_Shop_Product ( + id_product, id_permutation, display_order + ) + SELECT PP.id_product, ST.substring, ST.display_order + FROM Split_Temp ST + INNER JOIN Shop_Product_Permutation PP + ON ST.substring = PP.id_permutation + -- AND PP.active + ; + /* + SELECT substring as id_product, display_order + FROM Split_Temp + ; + */ + DROP TABLE Split_Temp; + + # Get product quantities + CALL p_split(a_quantities_permutation_basket, ','); + INSERT INTO tmp_Shop_Quantity ( + quantity, display_order + ) + SELECT substring, display_order + FROM Split_Temp + ; + /* + SELECT substring AS quantity_product, display_order + FROM Split_Temp + ; + */ + DROP TABLE Split_Temp; + + # Compare number of product ids to number of quantities + SET v_n_id_permutation_basket := (SELECT display_order FROM tmp_Shop_Product ORDER BY display_order DESC LIMIT 1); + SET v_n_quantity_permutation_basket := (SELECT display_order FROM tmp_Shop_Quantity ORDER BY display_order DESC LIMIT 1); + IF NOT v_n_id_permutation_basket = v_n_quantity_permutation_basket THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('Number of permutations (', v_n_id_permutation_basket, ') does not equal number of quantities (', v_n_quantity_permutation_basket, ') for basket.') + ) + ; + ELSE + INSERT INTO tmp_Shop_Basket ( + id_category, + id_product, + id_permutation, + id_region_purchase, + id_currency, + quantity + ) + SELECT + C.id_category, + P.id_product, + t_P.id_permutation, + a_id_region_purchase, + a_id_currency, + t_Q.quantity + FROM tmp_Shop_Product t_P + INNER JOIN tmp_Shop_Quantity t_Q + ON t_P.display_order = t_Q.display_order + INNER JOIN Shop_Product_Permutation PP + ON t_P.id_permutation = PP.id_permutation + AND PP.active + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + AND P.active + INNER JOIN Shop_Category C + ON P.id_category = C.id_category + AND C.active + -- RIGHT JOIN tmp_Shop_Basket t_UB ON ISNULL(t_UB.id_product) + -- WHERE t_P.id_product NOT IN (SELECT id_product FROM tmp_Shop_Basket) + ; + + /* + IF EXISTS( + SELECT * + FROM Shop_Product P + INNER JOIN Shop_Category C + ON P.id_category = C.id_category + INNER JOIN tmp_Shop_Basket t_B + ON P.id_product = t_B.id_product + WHERE C.active = 0 OR P.active = 0 LIMIT 1 + ) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('No valid product IDs in list: ', a_ids_permutation_basket, '.') + ) + ; + END IF; + */ + END IF; + END IF; + + /* + select v_has_filter_edit; + select * from tmp_Shop_Basket; + select * from tmp_Msg_Error; + */ + + + # Edit basket product + IF v_has_filter_permutation_edit AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + IF EXISTS ( + SELECT * + FROM Shop_Product_Permutation PP + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + INNER JOIN Shop_Category C + ON P.id_category = C.id_category + WHERE + ( + C.active = 0 + OR P.active = 0 + OR PP.active = 0 + ) + AND PP.id_permutation = a_id_permutation_edit + LIMIT 1 + ) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('Invalid product ID to edit: ', a_id_product_edit, '.') + ) + ; + END IF; + END IF; + IF v_has_filter_permutation_edit AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + IF EXISTS ( + SELECT * + FROM tmp_Shop_Basket + WHERE + id_permutation = a_id_permutation_edit + ) THEN + UPDATE tmp_Shop_Basket + SET quantity = CASE WHEN a_sum_not_edit = 1 THEN IFNULL(quantity, 0) + a_quantity_permutation_edit ELSE a_quantity_permutation_edit END, + active = CASE WHEN CASE WHEN a_sum_not_edit = 1 THEN IFNULL(quantity, 0) + a_quantity_permutation_edit ELSE a_quantity_permutation_edit END = 0 THEN 0 ELSE 1 END + WHERE id_permutation = a_id_permutation_edit + ; + + IF EXISTS ( + SELECT * + FROM tmp_Shop_Basket t_B + WHERE t_B.quantity < 0 + ) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + 'Invalid basket quantity.' + ) + ; + END IF; + + IF v_has_filter_user AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + SET v_change_set_used = 1; + + UPDATE Shop_User_Basket UB + INNER JOIN tmp_Shop_Basket t_UB + ON UB.id_permutation = a_id_permutation_edit + SET UB.quantity = t_UB.quantity, + UB.active = t_UB.active, + UB.id_change_set_user = v_id_change_set + WHERE UB.id_permutation = a_id_permutation_edit + AND id_user = a_id_user + ; + END IF; + ELSE + IF a_quantity_permutation_edit < 0 THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + 'Invalid basket quantity.' + ) + ; + ELSE + INSERT INTO tmp_Shop_Basket ( + id_category, + id_product, + id_permutation, + id_region_purchase, + id_currency, + quantity, + active + ) + SELECT + P.id_category, + P.id_product, + PP.id_permutation, + a_id_region_purchase, + a_id_currency, + a_quantity_permutation_edit, + CASE WHEN a_quantity_permutation_edit > 0 THEN 1 ELSE 0 END + FROM Shop_Product_Permutation PP + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + WHERE id_permutation = a_id_permutation_edit + ; + IF v_has_filter_user THEN + IF EXISTS ( + SELECT * + FROM Shop_User_Basket UB + WHERE + UB.id_permutation = a_id_permutation_edit + ) THEN + SET v_change_set_used = 1; + + UPDATE Shop_User_Basket + INNER JOIN tmp_Shop_Basket t_UB ON UB.id_permutation = t_UB.id_permutation + SET UB.quantity = t_UB.quantity, + UB.active = t_UB.active, + UB.id_change_set_user = v_id_change_set + WHERE UB.id_permutation = a_id_permutation_edit + AND id_user = a_id_user + ; + ELSE + INSERT INTO Shop_User_Basket ( + id_user, + id_product, + id_permutation, + id_region_purchase, + id_currency, + quantity, + active + ) + SELECT a_id_user, + t_UB.id_product, + t_UB.id_permutation, + t_UB.id_region_purchase, + t_UB.id_currency, + t_UB.quantity, + t_UB.active + FROM tmp_Shop_Basket t_UB + WHERE id_permutation = a_id_permutation_edit + ; + END IF; + END IF; + END IF; + END IF; + END IF; + + + -- Checks + /* + SELECT * FROM tmp_Shop_Basket; + SELECT + GROUP_CONCAT(t_UB.id_product SEPARATOR ',') AS basket_product_ids + FROM tmp_Shop_Basket t_UB + -- WHERE ISNULL(t_UB.id_permutation) + ; + SELECT + GROUP_CONCAT(t_UB.id_permutation SEPARATOR ',') AS basket_permutation_ids + FROM tmp_Shop_Basket t_UB + WHERE NOT ISNULL(t_UB.id_permutation) + ; + */ + -- Returns + CALL p_shop_get_many_product ( + a_id_user, # a_id_user + 1, # a_get_all_categories + '', # a_ids_category + 0, # a_get_inactive_categories + 0, # a_get_all_products + ( + SELECT + GROUP_CONCAT(t_B.id_product SEPARATOR ',') + FROM tmp_Shop_Basket t_B + WHERE active = 1 + ), # a_ids_product + 0, # a_get_inactive_products + 0, # a_get_first_product_only + 0, # a_get_all_product_permutations + ( + SELECT + GROUP_CONCAT(t_B.id_permutation SEPARATOR ',') + FROM tmp_Shop_Basket t_B + WHERE NOT ISNULL(t_B.id_permutation) + AND active = 1 + ), # a_ids_permutation + 0, # a_get_inactive_permutations + 0, # a_get_all_images + '', # a_ids_image + 0, # a_get_inactive_images + 1, # a_get_first_image_only + 0, # a_get_all_delivery_region + a_id_region_purchase, # a_ids_delivery_region + 0, # a_get_inactive_delivery_region + 0, # a_get_all_currency + a_id_currency, # a_ids_currency + 0, # a_get_inactive_currency + 1, # a_get_all_discount + '', # a_ids_discount + 0 # a_get_inactive_discount + ); + + # Basket + SELECT t_UB.id_category, + t_UB.id_product, + t_UB.id_permutation, + P.name, + PCL.price_local_VAT_incl, + PCL.price_local_VAT_excl, + PCL.id_currency, + t_UB.quantity + FROM tmp_Shop_Basket t_UB + INNER JOIN Shop_Product_Permutation PP + ON t_UB.id_permutation = PP.id_permutation + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + INNER JOIN Shop_Category C + ON P.id_category = C.id_category + INNER JOIN Shop_Product_Currency_Link PCL + ON PP.id_permutation = PCL.id_permutation + AND PCL.id_region_purchase = a_id_region_purchase + AND PCL.id_currency = a_id_currency + WHERE t_UB.active = 1 + ORDER BY C.display_order, P.display_order + ; + + # Errors + /* Completed by product get many */ + SELECT + t_ME.display_order, + t_ME.guid, + t_ME.id_type, + t_ME.msg, + MET.code, + MET.name, + MET.description + FROM tmp_Msg_Error t_ME + INNER JOIN Shop_Msg_Error_Type MET + ON t_ME.id_type = MET.id_type + WHERE GUID = v_guid + ; + + /* + # Return arguments for test + SELECT + a_ids_category, + a_get_inactive_categories, + a_ids_product, + a_get_inactive_products, + a_get_first_product_only, + a_get_all_products, + a_ids_image, + a_get_inactive_images, + a_get_first_image_only, + a_get_all_images + ; + */ + + -- Clean up + IF NOT v_change_set_used THEN + DELETE FROM Shop_User_Change_Set + WHERE id_change_set = v_id_change_set + ; + END IF; + + # DROP TABLE IF EXISTS tmp_Msg_Error; + DELETE FROM tmp_Msg_Error WHERE guid = v_guid; + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN + DROP TABLE tmp_Msg_Error; + END IF; + DROP TABLE IF EXISTS tmp_Shop_Basket; + DROP TEMPORARY TABLE IF EXISTS tmp_Shop_Quantity; + DROP TABLE IF EXISTS tmp_Shop_Product; + DROP TABLE IF EXISTS tmp_Shop_User; +END // +DELIMITER ; + + +/* + +CALL p_shop_edit_user_basket ( + '', # a_id_user + '', # a_ids_permutation_basket + '', # a_quantities_permutation_basket + 2, # a_id_permutation_edit + 1, # a_quantity_permutation_edit + 1, # a_sum_not_edit + 2, # a_id_currency_edit + 1 # a_id_region_purchase +); + +CALL p_shop_edit_user_basket ( + '', # a_id_user + '1', # a_ids_permutation_basket + '9', # a_quantities_permutation_basket + 1, # a_id_permutation_edit + 69, # a_quantity_permutation_edit + 1, # a_sum_not_edit + 1, # a_id_currency_edit + 1 # a_id_region_purchase +); +CALL p_shop_edit_user_basket ( + 'auth0|6582b95c895d09a70ba10feF', # a_id_user + '2', # a_ids_permutation_basket + '7', # a_quantities_permutation_basket + 2, # a_id_permutation_edit + NULL, # a_quantity_permutation_edit + 1, # a_sum_not_edit + 1, # a_id_currency_edit + 1 # a_id_region_purchase +); + + + {'a_id_user': 'auth0|6582b95c895d09a70ba10fef', + 'a_ids_permutation_basket': '1', + '7', # a_quantities_permutation_basket + 'a_id_permutation_edit': 1, + 'a_quantity_permutation_edit': 1, + 'a_sum_not_edit': 1} + + select * from shop_user_basket; + insert into shop_user_change_set (comment) + values( 'deactivate duplicates'); + update SHOP_USER_BASKET + set active = 0, + id_change_set_user = (select id_change_set from shop_user_change_set order by id_change_set desc limit 1) + where id_user = 'auth0|6582b95c895d09a70ba10fef' + and id_product = 1 + ; + select * from shop_user_basket; +*/ + +USE PARTS; + +/* + +CALL p_shop_get_many_user_order ( + '', + '', + 1, + '' +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_many_user_order; + + +DELIMITER // +CREATE PROCEDURE p_shop_get_many_user_order ( + IN a_id_user VARCHAR(200), + IN a_ids_order VARCHAR(4000), + IN a_n_order_max INT, + IN a_id_checkout_session VARCHAR(200) +) +BEGIN + -- Argument redeclaration + -- Variable declaration + DECLARE v_has_filter_user BIT; + DECLARE v_has_filter_order BIT; + DECLARE v_has_filter_session BIT; + DECLARE v_code_error_data VARCHAR(200); + DECLARE v_code_error_permission VARCHAR(200); + DECLARE v_guid VARCHAR(36); + + SET v_code_error_data := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 1); + SET v_code_error_permission := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 2); + SET v_guid = UUID(); + + -- Argument validation + default values + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + IF a_ids_order IS NULL THEN + SET a_ids_order = ''; + ELSE + SET a_ids_order = TRIM(a_ids_order); + END IF; + IF a_n_order_max IS NULL THEN + SET a_n_order_max = 1; + END IF; + IF a_id_checkout_session IS NULL THEN + SET a_id_checkout_session = ''; + ELSE + SET a_id_checkout_session = TRIM(a_id_checkout_session); + END IF; + + + + -- Temporary tables + DROP TABLE IF EXISTS tmp_Shop_User; + DROP TABLE IF EXISTS tmp_Shop_Order; + + CREATE TABLE tmp_Shop_User( + id_user VARCHAR(200) NOT NULL PRIMARY KEY, + CONSTRAINT FK_tmp_Shop_User_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user), + active BIT NOT NULL + ); + + CREATE TABLE tmp_Shop_Order ( + id_order INT NOT NULL PRIMARY KEY, + CONSTRAINT FK_tmp_Shop_Order_id_order + FOREIGN KEY (id_order) + REFERENCES Shop_User_Order(id_order), + active BIT NOT NULL + ); + + CREATE TABLE IF NOT EXISTS tmp_Msg_Error ( + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + guid VARCHAR(36) NOT NULL, + # id_type INT NOT NULL, + # CONSTRAINT FK_tmp_Msg_Error_id_type FOREIGN KEY (id_type) + # REFERENCES Shop_Msg_Error_Type (id_type), + code VARCHAR(50), + msg VARCHAR(4000) NOT NULL + ); + + + -- Parse filters + SET v_has_filter_user = CASE WHEN a_id_user = '' THEN 0 ELSE 1 END; + SET a_ids_order = REPLACE(a_ids_order, '|', ','); + SET v_has_filter_order = CASE WHEN a_ids_order = '' THEN 0 ELSE 1 END; + SET v_has_filter_session = CASE WHEN a_id_checkout_session = '' THEN 0 ELSE 1 END; + + -- User + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error LIMIT 1) THEN + IF v_has_filter_user THEN + INSERT INTO tmp_Shop_User ( + id_user, + active + ) + SELECT id_user, + active + FROM Shop_User + WHERE id_user LIKE CONCAT('%', a_id_user, '%') + AND active + LIMIT 1 + ; + + SET v_has_filter_user = EXISTS (SELECT id_user FROM tmp_Shop_User LIMIT 1); + SET a_id_user := (SELECT id_user FROM tmp_Shop_User LIMIT 1); + END IF; + END IF; + IF NOT v_has_filter_user THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_data, + 'User ID not valid.' + ) + ; + END IF; + + -- Permissions + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + CALL p_shop_user_eval ( + v_guid, # a_guid + a_id_user, # a_id_user + 0, # a_get_inactive_users + CONVERT((SELECT id_permission FROM Shop_Permission WHERE 'STORE_USER' = code), CHAR), # a_ids_permission + (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'VIEW' AND active), # a_ids_access_level + '', # a_ids_product + '' # a_ids_permutation + ); + + IF NOT (SELECT can_edit FROM Shop_User_Eval_Temp WHERE guid = v_guid) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_permission, + 'User ID does not have permission to access orders.' + ) + ; + END IF; + + DELETE FROM Shop_User_Eval_Temp + WHERE guid = v_guid + ; + END IF; + + -- Invalid Orders + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + # Invalid Order IDs + IF EXISTS (SELECT * FROM Shop_User_Order WHERE NOT (id_user = a_id_user) AND v_has_filter_order AND FIND_IN_SET(id_order, a_ids_order) > 0) THEN # id_order LIKE CONCAT('%', a_ids_order, '%') LIMIT 1) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_data, + CONCAT('You do not have access to the following order IDs: ', (SELECT GROUP_CONCAT(id_order SEPARATOR ', ') FROM Shop_User_Order WHERE NOT (id_user = a_id_user) AND FIND_IN_SET(id_order, a_ids_order) > 0)) # id_order LIKE CONCAT('%', a_ids_order, '%'))) # AND v_has_filter_order # filtered by parent condition + ) + ; + END IF; + # Invalid Checkout Session IDs + IF EXISTS (SELECT * FROM Shop_User_Order WHERE NOT (id_user = a_id_user) AND v_has_filter_session AND id_checkout_session = a_id_checkout_session) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_data, + CONCAT('You do not have access to the following checkout session IDs: ', (SELECT GROUP_CONCAT(id_order SEPARATOR ', ') FROM Shop_User_Order WHERE NOT (id_user = a_id_user) AND id_checkout_session = a_id_checkout_session)) # AND v_has_filter_order # filtered by parent condition + ) + ; + END IF; + END IF; + + -- Valid Orders + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + + INSERT INTO tmp_Shop_Order ( + id_order, + active + ) + SELECT UO.id_order, + UO.active + FROM Shop_User_Order UO + INNER JOIN tmp_Shop_User t_U + ON UO.id_user = t_U.id_user + AND t_U.active + WHERE ((NOT v_has_filter_order OR FIND_IN_SET(UO.id_order, a_ids_order) > 0) # UO.id_order LIKE CONCAT('%', a_ids_order, '%')) + OR (NOT v_has_filter_session OR UO.id_checkout_session = a_id_checkout_session)) + AND UO.active + ; + END IF; + + + + -- Returns + /* + SELECT * + FROM tmp_Shop_User + ; + */ + + SELECT t_O.id_order, + UOPL.id_product, + UOPL.id_permutation, + UOPL.quantity + FROM tmp_Shop_Order t_O + INNER JOIN Shop_User_Order UO + ON t_O.id_order = UO.id_order + INNER JOIN Shop_User_Order_Product_Link UOPL + ON UO.id_order = UOPL.id_order + WHERE t_O.active + ; + + + # Errors + SELECT * + FROM tmp_Msg_Error + WHERE guid = v_guid + ; + + + /* + # Return arguments for test + SELECT + a_id_user, + a_ids_order, + a_n_order_max, + a_id_checkout_session + ; + */ + + -- Clean up + DROP TABLE IF EXISTS tmp_Shop_User; + DROP TABLE IF EXISTS tmp_Shop_Order; +END // +DELIMITER ; + + +/* + +CALL p_shop_get_many_user_order ( + 'auth0|6582b95c895d09a70ba10fef', + '1', + 0, + '' +); + +CALL p_shop_get_many_user_order ( + '', + '1', + 0, + '' +); + +insert into shop_product_change_set (comment) + values ('set product not subscription - test bool output to python'); + update shop_product + set is_subscription = 0, + id_change_set = (select id_change_set from shop_product_change_set order by id_change_set desc limit 1) + where id_product = 1 +select * from shop_User; +select * from shop_User_oRDER; +*/ + +USE PARTS; + +/* + +CALL p_shop_get_many_stripe_product_new ( + '' +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_many_stripe_product_new; + + +DELIMITER // +CREATE PROCEDURE p_shop_get_many_stripe_product_new ( + IN a_id_user VARCHAR(200) +) +BEGIN + DECLARE v_has_filter_user BIT; + DECLARE v_code_error_data VARCHAR(200); + DECLARE v_code_error_permission VARCHAR(200); + DECLARE v_guid VARCHAR(36); + + SET v_code_error_data := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 1); + SET v_code_error_permission := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 2); + SET v_guid = UUID(); + + + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + + + + -- Temporary tables + DROP TABLE IF EXISTS tmp_Shop_Product; + DROP TABLE IF EXISTS tmp_Shop_User; + + CREATE TABLE tmp_Shop_User( + id_user VARCHAR(200) NOT NULL PRIMARY KEY, + CONSTRAINT FK_tmp_Shop_User_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user), + active BIT NOT NULL + ); + + CREATE TABLE tmp_Shop_Product ( + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + active BIT NOT NULL, + display_order_product INT NOT NULL, + display_order_permutation INT NOT NULL, + name VARCHAR(200) NOT NULL, + description VARCHAR(4000) NOT NULL + ); + + CREATE TABLE IF NOT EXISTS tmp_Msg_Error ( # IF NOT EXISTS + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + guid VARCHAR(36) NOT NULL, + code VARCHAR(50) NOT NULL, + # CONSTRAINT chk_tmp_Msg_Error_code CHECK (code IN (SELECT code FROM Shop_Msg_Error_Type)), + /* + id_type INT NOT NULL, + CONSTRAINT FK_tmp_Msg_Error_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Msg_Error_Type(id_type), + */ + msg VARCHAR(4000) NOT NULL + ); + + + + -- Parse filters + SET v_has_filter_user = CASE WHEN a_id_user = '' THEN 0 ELSE 1 END; + + + + -- User + IF v_has_filter_user THEN + INSERT INTO tmp_Shop_User ( + id_user, + active + ) + SELECT id_user, + active + FROM Shop_User + WHERE id_user LIKE CONCAT('%', a_id_user, '%') + AND active + LIMIT 1 + ; + + SET v_has_filter_user = EXISTS (SELECT id_user FROM tmp_Shop_User LIMIT 1); + SET a_id_user := (SELECT id_user FROM tmp_Shop_User LIMIT 1); + END IF; + + IF NOT v_has_filter_user THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_data, + 'User ID not valid.' + ) + ; + END IF; + + -- Get products + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + INSERT INTO tmp_Shop_Product ( + id_product, + id_permutation, + active, + display_order_product, + display_order_permutation, + name, + description + ) + SELECT id_product, + id_permutation, + active, + display_order_product, + display_order_permutation, + name, + description + FROM ( + SELECT id_product, + NULL AS id_permutation, + active, + display_order AS display_order_product, + NULL AS display_order_permutation, + name, + description, + id_stripe_product + FROM Shop_Product P + UNION + SELECT t_PPPV.id_product, + id_permutation, + t_PPPV.active, + display_order_product, + display_order_permutation, + CONCAT(P.name, ': ', names_variation) AS name, + CONCAT(P.description, ' With variations: ', type_name_pairs_variation) AS description, + t_PPPV.id_stripe_product + FROM ( + SELECT P.id_product, + PP.id_permutation, + PP.active, + P.display_order AS display_order_product, + PP.display_order AS display_order_permutation, + GROUP_CONCAT(V.name SEPARATOR ' ') AS names_variation, + GROUP_CONCAT(CONCAT(VT.name, ': ', V.name) SEPARATOR ', ') AS type_name_pairs_variation, + PP.id_stripe_product + FROM Shop_Product_Permutation PP + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + AND P.active + INNER JOIN Shop_Product_Permutation_Variation_Link PPVL + ON PP.id_permutation = PPVL.id_permutation + AND PPVL.active + INNER JOIN Shop_Variation V + ON PPVL.id_variation = V.id_variation + AND V.active + INNER JOIN Shop_Variation_Type VT + ON V.id_type = VT.id_type + AND VT.active + GROUP BY id_product, id_permutation -- , VT.id_type, V.id_variation + ) t_PPPV + INNER JOIN Shop_Product P + ON t_PPPV.id_product = P.id_product + ) t_PPP + WHERE ISNULL(id_stripe_product) + AND active + ; + END IF; + + -- Permissions + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + CALL p_shop_user_eval ( + v_guid, # a_guid + a_id_user, # a_id_user + 0, # a_get_inactive_users + CONVERT((SELECT id_permission FROM Shop_Permission WHERE 'STORE_ADMIN' = code), CHAR), # a_ids_permission + (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'ADMIN' AND active), # a_ids_access_level + (SELECT GROUP_CONCAT(id_product SEPARATOR ',') From tmp_Shop_Product), # a_ids_product + (SELECT GROUP_CONCAT(id_permutation SEPARATOR ',') From tmp_Shop_Product) # a_ids_permutation -- WHERE NOT ISNULL(id_permutation) + ); + + IF EXISTS (SELECT can_admin FROM Shop_User_Eval_Temp WHERE guid = v_guid AND NOT can_admin) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_permission, + 'User ID does not have permission to get all new stripe products.' + ) + ; + END IF; + + DELETE FROM Shop_User_Eval_Temp + WHERE guid = v_guid + ; + END IF; + + + + + -- Returns + /* + SELECT * + FROM tmp_Shop_User + ; + */ + + IF EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + DELETE FROM tmp_Shop_Product; + END IF; + + SELECT id_product, + id_permutation, + name, + description + FROM tmp_Shop_Product + ORDER BY display_order_product, display_order_permutation + ; + SELECT PP.id_permutation, + V.id_variation, + V.name AS name_variation, + VT.id_type AS id_type_variation, + VT.name as name_variation_type + FROM tmp_Shop_Product t_P + INNER JOIN Shop_Product_Permutation PP + ON t_P.id_permutation = PP.id_permutation + INNER JOIN Shop_Product_Permutation_Variation_Link PPVL + ON PP.id_permutation = PPVL.id_permutation + AND PPVL.active + INNER JOIN Shop_Variation V + ON PPVL.id_variation = V.id_variation + AND V.active + INNER JOIN Shop_Variation_Type VT + ON V.id_type = VT.id_type + AND VT.active + ; + + + # Errors + SELECT * + FROM tmp_Msg_Error + WHERE guid = v_guid + ; + + + /* + # Return arguments for test + SELECT + a_id_user + ; + */ + + -- Clean up + DROP TABLE IF EXISTS tmp_Shop_Product; + DROP TABLE IF EXISTS tmp_Shop_User; +END // +DELIMITER ; + + +/* +CALL p_shop_get_many_stripe_product_new ( + '' +); + +CALL p_shop_get_many_stripe_product_new ( + 'auth0|6582b95c895d09a70ba10fef' +); + + + +select * from shop_product; +select * from shop_product_permutation_variation_link; + +CALL p_shop_user_eval ( + 'ead789a1-c7ac-11ee-a256-b42e9986184a', # a_guid + 'auth0|6582b95c895d09a70ba10fef', # a_id_user + 0, # a_get_inactive_users + '4', # a_ids_permission + '3', # a_ids_access_level + '1', # a_ids_product + '1' # a_ids_permutation -- WHERE NOT ISNULL(id_permutation) + ); + +*/ + +USE PARTS; + +/* + +CALL p_shop_get_many_stripe_price_new ( + '' +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_many_stripe_price_new; + + +DELIMITER // +CREATE PROCEDURE p_shop_get_many_stripe_price_new ( + IN a_id_user VARCHAR(200) +) +BEGIN + DECLARE v_has_filter_user BIT; + DECLARE v_code_error_data VARCHAR(200); + DECLARE v_code_error_permission VARCHAR(200); + DECLARE v_guid VARCHAR(36); + + SET v_code_error_data := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 1); + SET v_code_error_permission := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 2); + SET v_guid = UUID(); + + + + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + + + + -- Temporary tables + DROP TABLE IF EXISTS tmp_Shop_Product_Currency_Link; + DROP TABLE IF EXISTS tmp_Shop_User; + + CREATE TABLE tmp_Shop_User( + id_user VARCHAR(200) NOT NULL PRIMARY KEY, + CONSTRAINT FK_tmp_Shop_User_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user), + active BIT NOT NULL + ); + + CREATE TABLE tmp_Shop_Product_Currency_Link ( + id_link INT NOT NULL PRIMARY KEY, + CONSTRAINT FK_tmp_Shop_Product_Currency_Link_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Currency_Link(id_link), + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_Currency_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NULL, + CONSTRAINT FK_tmp_Shop_Product_Currency_Link_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + id_currency INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_Currency_Link_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency), + active BIT NOT NULL + ); + + CREATE TABLE IF NOT EXISTS tmp_Msg_Error ( # IF NOT EXISTS + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + guid VARCHAR(36) NOT NULL, + code VARCHAR(50) NOT NULL, + # CONSTRAINT chk_tmp_Msg_Error_code CHECK (code IN (SELECT code FROM Shop_Msg_Error_Type)), + /* + id_type INT NOT NULL, + CONSTRAINT FK_tmp_Msg_Error_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Msg_Error_Type(id_type), + */ + msg VARCHAR(4000) NOT NULL + ); + + + + -- Parse filters + SET v_has_filter_user = CASE WHEN a_id_user = '' THEN 0 ELSE 1 END; + + + + -- User permissions + IF v_has_filter_user THEN + INSERT INTO tmp_Shop_User ( + id_user, + active + ) + SELECT id_user, + active + FROM Shop_User + WHERE id_user LIKE CONCAT('%', a_id_user, '%') + AND active + LIMIT 1 + ; + + SET v_has_filter_user = EXISTS (SELECT id_user FROM tmp_Shop_User LIMIT 1); + SET a_id_user := (SELECT id_user FROM tmp_Shop_User LIMIT 1); + END IF; + IF NOT v_has_filter_user THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_data, + 'Valid user ID not provided.' + ) + ; + END IF; + + -- Get products + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + INSERT INTO tmp_Shop_Product_Currency_Link ( + id_link, + id_product, + id_permutation, + id_currency, + active + ) + SELECT id_link, + id_product, + id_permutation, + id_currency, + active + FROM Shop_Product_Currency_Link + WHERE ISNULL(id_stripe_price) + AND active + ; + END IF; + + -- Permissions + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + # SELECT * FROM tmp_Msg_Error LIMIT 1; + CALL p_shop_user_eval ( + v_guid, # a_guid + a_id_user, # a_id_user + 0, # a_get_inactive_users + CONVERT((SELECT id_permission FROM Shop_Permission WHERE 'STORE_ADMIN' = code), CHAR), # a_ids_permission + (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'ADMIN' AND active), # a_ids_access_level + (SELECT GROUP_CONCAT(DISTINCT id_product SEPARATOR ',') FROM tmp_Shop_Product_Currency_Link), # (SELECT DISTINCT id_product FROM tmp_Shop_Product_Currency_Link) calc_PCL) # a_ids_product + (SELECT GROUP_CONCAT(DISTINCT id_permutation SEPARATOR ',') FROM tmp_Shop_Product_Currency_Link) # a_ids_permutation + ); + # SELECT * FROM tmp_Msg_Error LIMIT 1; + + IF EXISTS (SELECT can_admin FROM Shop_User_Eval_Temp WHERE guid = v_guid AND NOT can_admin LIMIT 1) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_permission, + 'User ID does not have permission to get all new stripe prices.' + ) + ; + END IF; + + DELETE FROM Shop_User_Eval_Temp + WHERE guid = v_guid + ; + END IF; + + + + -- Returns + IF EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + DELETE FROM tmp_Shop_Product_Currency_Link; + END IF; + /* + SELECT * + FROM tmp_Shop_User + ; + */ + + + SELECT t_PCL.id_product, + t_PCL.id_permutation, + P.price_GBP_full * C.factor_from_GBP AS unit_price, + C.code AS code_currency, + P.id_stripe_product, + P.is_subscription, + LOWER(RI.code) AS name_recurring_interval, + P.count_recurrence_interval + FROM tmp_Shop_Product_Currency_Link t_PCL + INNER JOIN Shop_Product P + ON t_PCL.id_product = P.id_product + AND P.active + INNER JOIN Shop_Recurrence_Interval RI + ON P.id_recurrence_interval = RI.id_interval + AND RI.active + INNER JOIN Shop_Currency C + ON t_PCL.id_currency = C.id_currency + AND C.active + WHERE t_PCL.active + ; + + + # Errors + SELECT * + FROM tmp_Msg_Error + WHERE guid = v_guid + ; + + + /* + # Return arguments for test + SELECT + a_id_user + ; + */ + + -- Clean up + DROP TABLE IF EXISTS tmp_Shop_User; + DROP TABLE IF EXISTS tmp_Shop_Product_Currency_Link; +END // +DELIMITER ; + + +/* +CALL p_shop_get_many_stripe_price_new ( + '' +); + +CALL p_shop_get_many_stripe_price_new ( + 'auth0|6582b95c895d09a70ba10fef' +); + +*/ + +USE PARTS; + +/* + +CALL p_populate_database () + +*/ + +/* +-- Remove previous proc +DROP PROCEDURE IF EXISTS p_populate_database; + + +DELIMITER // +CREATE PROCEDURE p_populate_database () +BEGIN +*/ + + +# Access Levels +INSERT INTO Shop_Access_Level ( + display_order, code, name, priority +) +VALUES + (1, 'VIEW', 'View', 3), + (2, 'EDIT', 'Edit', 2), + (3, 'ADMIN', 'Admin', 1) +; + +# Error Message Types +INSERT INTO Shop_Msg_Error_Type ( + code, name, description +) +VALUES + ('BAD_DATA', 'Invalid data', 'Rubbish data'), + ('NO_PERMISSION', 'No permission', 'Not authorised'), + ('PRODUCT_AVAILABILITY', 'Product not available', 'Product not available') +; + +# File Types +INSERT INTO File_Type ( + code, name, extension +) +VALUES + ('JPEG', 'Joint Photographic Export Group', 'jpg'), + ('PNG', 'Portable Network Graphic', 'png'), + ('GIF', 'GIF', 'gif'), + ('MPEG-4', 'Multimedia Photographic Export Group 4', 'mp4') +; + +# Generic / shared properties +INSERT INTO Shop_General ( + quantity_max +) +VALUES ( + 10 +); + +# Categories +INSERT INTO Shop_Category ( + display_order, + code, + name, + description +) +VALUES + (1, 'ASS', 'Assistive Devices', 'Braille product line and other assistive devices'), + (99, 'MISC', 'Miscellaneous', 'Not category allocated products'), + (2, 'TECH', 'Technology', 'Technological devices') +; + +# Recurrence Interval +INSERT INTO Shop_Recurrence_Interval ( + code, name, name_plural +) +VALUES + ('WEEK', 'Week', 'Weeks'), + ('MONTH', 'Month', 'Months'), + ('YEAR', 'Year', 'Years') +; + +INSERT INTO Shop_Region ( + display_order, code, name +) +VALUES + (1, 'UK', 'United Kingdom') +; + +/* +INSERT INTO Shop_Region_Branch ( + display_order, id_region_parent, id_region_child +) +VALUES + (1, 1, 2) +; +*/ + +# Currency +INSERT INTO Shop_Currency ( + display_order, code, name, symbol, factor_from_GBP +) +VALUES + (1, 'GBP', 'Great British Pound', '£', 1), + (2, 'EUR', 'Euro', '€', 1.17) +; + +# Taxes and Surcharges +INSERT INTO Shop_Tax_Or_Surcharge ( + display_order, + id_tax, + code, + name, + id_region_buyer, + id_region_seller, + fixed_fee, + multiplier, + apply_fixed_fee_before_multiplier, + quantity_min, + quantity_max +) +VALUES + (1, 1, 'VAT', 'Value Added Tax', 1, 1, 0, 0.2, 1, 0, 1) +; + +# Products +INSERT INTO Shop_Product ( + display_order, + id_category, + name, + has_variations, + id_access_level_required +) +VALUES + ( + 1, + 1, + 'Braille Keyboard Translator', + 1, + 3 + ), + ( + 2, + 2, + 'Test product 1', + 0, + 3 + ), + ( + 3, + 3, + 'Phone', + 0, + 1 + ), + ( + 4, + 3, + 'Laptop', + 0, + 1 + ), + ( + 5, + 3, + 'Smart Watch', + 0, + 1 + ) +; + +# Variation Types +INSERT INTO Shop_Variation_Type ( + display_order, code, name, name_plural +) +VALUES + (1, 'COLOUR', 'Colour', 'Colours') +; + +# Variations +INSERT INTO Shop_Variation ( + display_order, id_type, code, name +) +VALUES + (1, 1, 'RED', 'Red'), + (2, 1, 'BLUE', 'Blue') +; + +# Product Permutations +INSERT INTO Shop_Product_Permutation ( + display_order, + id_product, + description, + cost_local_manufacturing, + id_currency_cost_manufacturing, + profit_local_min, + id_currency_profit_min, + latency_manufacture, + quantity_min, + quantity_max, + quantity_step, + quantity_stock, + is_subscription, + id_recurrence_interval, + count_recurrence_interval, + id_access_level_required, + id_stripe_product +) +VALUES + ( + 1, + 1, + 'Good Red', + 5, + 1, + 3, + 1, + 14, + 1, + 3, + 1, + 99, + 0, + NULL, + NULL, + 1, + NULL + ), + ( + 2, + 1, + 'Good Blue', + 6, + 1, + 4, + 1, + 14, + 1, + 3, + 1, + 99, + 0, + NULL, + NULL, + 1, + NULL + ), + ( + 3, + 2, + 'Test product describes good', + 10, + 1, + 5, + 1, + 14, + 1, + 2, + 1, + 99, + 0, + NULL, + NULL, + 1, + NULL + ), + ( + 4, + 3, + 'Phone describes good', + 10, + 1, + 5, + 1, + 14, + 1, + 2, + 1, + 99, + 0, + NULL, + NULL, + 1, + NULL + ), + ( + 5, + 4, + 'Laptop describes good', + 10, + 1, + 5, + 1, + 14, + 1, + 2, + 1, + 99, + 0, + NULL, + NULL, + 1, + NULL + ), + ( + 6, + 5, + 'Smart watch describes good', + 10, + 1, + 5, + 1, + 14, + 1, + 2, + 1, + 99, + 0, + NULL, + NULL, + 1, + NULL + ) +; + +# Product Permutation Variation Links +INSERT INTO Shop_Product_Permutation_Variation_Link ( + display_order, id_permutation, id_variation +) +VALUES + (1, 1, 1), + (2, 2, 2) +; + +# Product Currency Link +INSERT INTO Shop_Product_Currency_Region_Link ( + id_product, id_permutation, id_currency, id_region_purchase, price_local_VAT_incl, price_local_VAT_excl +) +VALUES + (1, 1, 1, 1, 24, 20), + (1, 1, 2, 1, 48, 40), + (1, 2, 1, 1, 96, 80), + (2, 3, 1, 1, 144, 120), + (3, 4, 1, 1, 600, 500), + (4, 5, 1, 1, 1500, 1200), + (5, 6, 1, 1, 180, 150) +; + +INSERT INTO Shop_Image_Type ( + display_order, code, name, name_plural +) +VALUES + (1, 'FULL', 'Full Quality Image', 'Full Quality Images'), + (2, 'LOW', 'Low Quality Image', 'Low Quality Images'), + (3, 'THUMBNAIL', 'Thumbnail Image', 'Thumbnail Images') +; + +INSERT INTO Shop_Image ( + display_order, id_product, id_permutation, id_type_image, id_type_file, url +) +VALUES + (1, 1, 1, 1, 1, '/static/images/prod_PB0NUOSEs06ymG.jpg'), + # (1, NULL, 1, 1, 1, '/static/images/prod_PB0NUOSEs06ymG.jpg'), + (2, 1, 2, 1, 1, '/static/images/prod_PB0NUOSEs06ymG.jpg'), + # (1, NULL, 2, 1, 1, '/static/images/prod_PB0NUOSEs06ymG.jpg') + (3, 2, 3, 1, 1, '/static/images/prod_PB0NUOSEs06ymG.jpg'), + (4, 3, 4, 1, 1, '/static/images/prod_.jpg'), + (5, 4, 5, 1, 1, '/static/images/prod_1.jpg'), + (6, 5, 6, 1, 1, '/static/images/prod_2.jpg') +; + +INSERT INTO Shop_Delivery_Option ( + display_order, code, name, latency_delivery_min, latency_delivery_max, quantity_min, quantity_max +) +VALUES + (1, 'COLLECT', 'Collection', 0, 0, 0, 1), + (2, 'SIGNED_1', 'First Class Signed-For', 2, 4, 0, 1) +; + +INSERT INTO Shop_Product_Delivery_Option_Link ( + display_order, id_product, id_permutation, id_delivery_option, id_region, id_currency, price_local +) +VALUES + (1, 1, 1, 1, 1, 1, 5), + (2, 1, 2, 1, 1, 1, 9), + (3, 2, NULL, 1, 1, 1, 10), + (4, 3, 4, 1, 1, 1, 10), + (5, 4, 5, 1, 1, 1, 10), + (6, 5, 6, 1, 1, 1, 10) +; + +# Discounts +INSERT INTO Shop_Discount ( + id_product, + id_permutation, + code, + name, + multiplier, + quantity_min, + quantity_max, + date_start, + date_end, + display_order +) +VALUES + (1, 1, 'CRIMBO50', 'Christmas 50% off sale!', 0.5, 3, 9, NOW(), '2023-12-31 23:59:59', 1), + (1, 2, 'CRIMBO50', 'Christmas 50% off sale!', 0.5, 3, 9, NOW(), '2023-12-31 23:59:59', 1) +; + +# Discount Delivery Region Links +INSERT INTO Shop_Discount_Region_Currency_Link ( + id_discount, + id_region, + id_currency +) +VALUES + (1, 1, 1), + (2, 1, 1), + (1, 1, 2), + (2, 1, 2) +; + +# Permission Groups +INSERT INTO Shop_Permission_Group ( + display_order, code, name +) +VALUES + (0, 'ADMIN', 'Website Admin'), + (1, 'HOME', 'Home, Contact Us, and other public information'), + (2, 'PRODUCT', 'Store Products'), + (3, 'USER', 'Store User') +; + +# Permissions +INSERT INTO Shop_Permission ( + display_order, code, name, id_permission_group, id_access_level_required +) +VALUES + (1, 'HOME', 'Home Page', 2, 1), + (2, 'STORE_PRODUCT', 'Store Product Page', 3, 1), + (3, 'STORE_USER', 'Store User Account Page', 4, 2), + (4, 'STORE_ADMIN', 'Store Admin Page', 1, 3), + (99, 'CONTACT_US', 'Contact Us Page', 2, 1) +; + +# Roles +INSERT INTO Shop_Role ( + display_order, + code, + name +) +VALUES + (1, 'DIRECTOR', 'Director'), + (2, 'USER', 'User') +; + +# Role Permission link +INSERT INTO Shop_Role_Permission_Link ( + id_role, id_permission, id_access_level +) +VALUES + (1, 1, 3), + (1, 2, 3), + (1, 3, 3), + (1, 4, 3), + (1, 5, 3), + (2, 1, 1), + (2, 2, 1), + (2, 3, 1), + (2, 4, 1), + (2, 5, 1) +; + +# Users +INSERT INTO Shop_User ( + id_user, + name, + email, + # email_verified, + is_super_user +) +VALUES + ('auth0|6582b95c895d09a70ba10fef', 'Teddy', 'edward.middletonsmith@gmail.com', 1), + ('parts_guest', 'Guest', '', 0) +; + +# User Role link +INSERT INTO Shop_User_Role_Link ( + id_user, id_role +) +VALUES + ('auth0|6582b95c895d09a70ba10fef', 1) +; + +# Addresses +INSERT INTO Shop_Address ( + id_user, id_region, name_full, phone_number, postcode, address_line_1, address_line_2, city, county +) +SELECT U.id_user, 1, U.name, '07375 571430', 'NN6 6EB', 'The Laurels', 'Cold Ashby Road', 'Cold Ashby', 'Northamptonshire' + FROM Shop_User U +; + +# User Basket +INSERT INTO Shop_User_Basket ( + id_user, + id_product, + id_permutation, + quantity +) +VALUES + ('auth0|6582b95c895d09a70ba10fef', 1, 1, 69) +; + +# User Order Status +INSERT INTO Shop_User_Order_Status ( + display_order, code, name, name_plural +) +VALUES + (1, 'SUCCESS', 'Success', 'Successes'), + (2, 'FAIL', 'Failure', 'Failures') +; + +# User Order +INSERT INTO Shop_User_Order ( + id_user, value_total, id_order_status, id_checkout_session, id_currency +) +VALUES + ('auth0|6582b95c895d09a70ba10fef', 25, 1, 'noods', 1), + ('auth0|6582b95c895d09a70ba10fef', 25, 1, 'noods', 1) +; + +# User Order Product Link +INSERT INTO Shop_User_Order_Product_Link ( + id_order, id_product, id_permutation, quantity +) +VALUES + (1, 1, 1, 69), + (1, 2, NULL, 69), + (1, 1, 2, 69) +; + +/* + -- Clean up +END // +DELIMITER ; + + +-- Call +CALL p_populate_database(); + +-- Remove proc +DROP PROCEDURE IF EXISTS p_populate_database; +*/ +USE PARTS; + +# Product Change Sets +SELECT * FROM Shop_Product_Change_Set; + +# User Change Sets +SELECT * FROM Shop_User_Change_Set; + +# Access Levels +SELECT * FROM Shop_Access_Level; +SELECT * FROM Shop_Access_Level_Audit; + +# Error Message type +SELECT * FROM Shop_Msg_Error_Type; + +# File Types +SELECT * FROM File_Type; +SELECT * FROM File_Type_Audit; + +# Generic / shared properties +SELECT * FROM Shop_General; +SELECT * FROM Shop_General_Audit; + +# Categories +SELECT * FROM Shop_Category; +SELECT * FROM Shop_Category_Audit; + +# Recurrence Interval +SELECT * FROM Shop_Recurrence_Interval; +SELECT * FROM Shop_Recurrence_Interval_Audit; + +# Region +SELECT * FROM Shop_Region; +SELECT * FROM Shop_Region_Audit; + +# Region Branch +SELECT * FROM Shop_Region_Branch; +SELECT * FROM Shop_Region_Branch_Audit; + +# Currency +SELECT * FROM Shop_Currency; +SELECT * FROM Shop_Currency_Audit; + +# Taxes and Surcharges +SELECT * FROM Shop_Tax_Or_Surcharge; +SELECT * FROM Shop_Tax_Or_Surcharge_Audit; + +# Products +SELECT * FROM Shop_Product; +SELECT * FROM Shop_Product_Audit; + +# Variation Types +SELECT * FROM Shop_Variation_Type; +SELECT * FROM Shop_Variation_Type_Audit; + +# Variations +SELECT * FROM Shop_Variation; +SELECT * FROM Shop_Variation_Audit; + +# Permutations +SELECT * FROM Shop_Product_Permutation; +SELECT * FROM Shop_Product_Permutation_Audit; + +# Permutation Variation Links +SELECT * FROM Shop_Product_Permutation_Variation_Link; +SELECT * FROM Shop_Product_Permutation_Variation_Link_Audit; + +# Product Currency Links +SELECT * FROM Shop_Product_Currency_Region_Link; +SELECT * FROM Shop_Product_Currency_Region_Link_Audit; + +# Image Types +SELECT * FROM Shop_Image_Type; +SELECT * FROM Shop_Image_Type_Audit; + +# Images +SELECT * FROM Shop_Image; +SELECT * FROM Shop_Image_Audit; + +# Delivery Option Types +SELECT * FROM Shop_Delivery_Option; +SELECT * FROM Shop_Delivery_Option_Audit; + +# Delivery Options +SELECT * FROM Shop_Product_Delivery_Option_Link; +SELECT * FROM Shop_Product_Delivery_Option_Link_Audit; + +# Discounts +SELECT * FROM Shop_Discount; +SELECT * FROM Shop_Discount_Audit; + +# Discount Delivery Region Links +SELECT * FROM Shop_Discount_Region_Currency_Link; +SELECT * FROM Shop_Discount_Region_Currency_Link_Audit; + + +# Permission Groups +SELECT * FROM Shop_Permission_Group; +SELECT * FROM Shop_Permission_Group_Audit; + +# Permissions +SELECT * FROM Shop_Permission; +SELECT * FROM Shop_Permission_Audit; + +# Roles +SELECT * FROM Shop_Role; +SELECT * FROM Shop_Role_Audit; + +# Role Permission link +SELECT * FROM Shop_Role_Permission_Link; +SELECT * FROM Shop_Role_Permission_Link_Audit; + +# Users +SELECT * FROM Shop_User; +SELECT * FROM Shop_User_Audit; + +# User Role link +SELECT * FROM Shop_User_Role_Link; +SELECT * FROM Shop_User_Role_Link_Audit; + + +# Addresses +SELECT * FROM Shop_Address; +SELECT * FROM Shop_Address_Audit; + +# Basket +SELECT * FROM Shop_User_Basket; +SELECT * FROM Shop_User_Basket_Audit; + +# Order Statuses +SELECT * FROM Shop_User_Order_Status; +SELECT * FROM Shop_User_Order_Status_Audit; + +# Orders +SELECT * FROM Shop_User_Order; +SELECT * FROM Shop_User_Order_Audit; + +# Order Products +SELECT * FROM Shop_User_Order_Product_Link; +SELECT * FROM Shop_User_Order_Product_Link_Audit; diff --git a/static/sql/001_destroy.sql b/static/sql/001_destroy.sql new file mode 100644 index 00000000..4250f110 --- /dev/null +++ b/static/sql/001_destroy.sql @@ -0,0 +1,141 @@ + +/* Clear Store DataBase */ +USE PARTS; + + +# Drop dependencies +DROP TABLE IF EXISTS Shop_User_Eval_Temp; +DROP TABLE IF EXISTS tmp_Msg_Error; +DROP TABLE IF EXISTS tmp_Currency; +DROP TABLE IF EXISTS tmp_Delivery_Region; +DROP TABLE IF EXISTS tmp_Region; +DROP TABLE IF EXISTS tmp_Shop_User; +DROP TABLE IF EXISTS tmp_Shop_Order; +DROP TABLE IF EXISTS tmp_Shop_Product; +DROP TABLE IF EXISTS tmp_Shop_Product_p_Shop_User_Eval; +DROP TABLE IF EXISTS tmp_Shop_Image; +DROP TABLE IF EXISTS tmp_Shop_Variation; +DROP TABLE IF EXISTS tmp_Shop_Discount; +DROP TABLE IF EXISTS tmp_Discount; +DROP TABLE IF EXISTS tmp_Shop_Category; +DROP TABLE IF EXISTS tmp_Shop_Product_Currency_Region_Link; +DROP TABLE IF EXISTS tmp_Shop_Product_Currency_Link; +DROP TABLE IF EXISTS tmp_User_Role_Link; +DROP TABLE IF EXISTS tmp_Shop_Basket; + + +# Delete old tables +DROP TABLE IF EXISTS Shop_User_Order_Product_Link_Audit; +DROP TABLE IF EXISTS Shop_User_Order_Product_Link; + +DROP TABLE IF EXISTS Shop_User_Order_Audit; +DROP TABLE IF EXISTS Shop_User_Order; + +DROP TABLE IF EXISTS Shop_User_Order_Status_Audit; +DROP TABLE IF EXISTS Shop_User_Order_Status; + +DROP TABLE IF EXISTS Shop_User_Basket_Audit; +DROP TABLE IF EXISTS Shop_User_Basket; + +DROP TABLE IF EXISTS Shop_Address_Audit; +DROP TABLE IF EXISTS Shop_Address; + +DROP TABLE IF EXISTS Shop_User_Role_Link_Audit; +DROP TABLE IF EXISTS Shop_User_Role_Link; + +DROP TABLE IF EXISTS Shop_User_Audit; +DROP TABLE IF EXISTS Shop_User; + +DROP TABLE IF EXISTS Shop_Role_Permission_Link_Audit; +DROP TABLE IF EXISTS Shop_Role_Permission_Link; + +DROP TABLE IF EXISTS Shop_Role_Audit; +DROP TABLE IF EXISTS Shop_Role; + +DROP TABLE IF EXISTS Shop_Permission_Audit; +DROP TABLE IF EXISTS Shop_Permission; + +DROP TABLE IF EXISTS Shop_Permission_Group_Audit; +DROP TABLE IF EXISTS Shop_Permission_Group; + + +DROP TABLE IF EXISTS Shop_Discount_Region_Currency_Link_Audit; +DROP TABLE IF EXISTS Shop_Discount_Region_Currency_Link; + +DROP TABLE IF EXISTS Shop_Discount_Audit; +DROP TABLE IF EXISTS Shop_Discount; + +DROP TABLE IF EXISTS Shop_Product_Delivery_Option_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Delivery_Option_Link; + +DROP TABLE IF EXISTS Shop_Delivery_Option_Audit; +DROP TABLE IF EXISTS Shop_Delivery_Option; + +DROP TABLE IF EXISTS Shop_Image_Audit; +DROP TABLE IF EXISTS Shop_Image; + +DROP TABLE IF EXISTS Shop_Image_Type_Audit; +DROP TABLE IF EXISTS Shop_Image_Type; + +DROP TABLE IF EXISTS Shop_Product_Currency_Region_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Currency_Region_Link; +DROP TABLE IF EXISTS Shop_Product_Currency_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Currency_Link; + +DROP TABLE IF EXISTS Shop_Product_Variation_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Variation_Link; +DROP TABLE IF EXISTS Shop_Product_Permutation_Variation_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Permutation_Variation_Link; + +DROP TABLE IF EXISTS Shop_Product_Permutation_Audit; +DROP TABLE IF EXISTS Shop_Product_Permutation; + +DROP TABLE IF EXISTS Shop_Variation_Audit; +DROP TABLE IF EXISTS Shop_Variation; +DROP TABLE IF EXISTS Shop_Product_Variation_Type_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Variation_Type_Link; + +DROP TABLE IF EXISTS Shop_Variation_Type_Audit; +DROP TABLE IF EXISTS Shop_Variation_Type; + +DROP TABLE IF EXISTS Shop_Product_Audit; +DROP TABLE IF EXISTS Shop_Product; + +DROP TABLE IF EXISTS Shop_Tax_Or_Surcharge_Audit; +DROP TABLE IF EXISTS Shop_Tax_Or_Surcharge; + +DROP TABLE IF EXISTS Shop_Currency_Audit; +DROP TABLE IF EXISTS Shop_Currency; + +DROP TABLE IF EXISTS Shop_Delivery_Region_Branch_Audit; +DROP TABLE IF EXISTS Shop_Delivery_Region_Branch; +DROP TABLE IF EXISTS Shop_Region_Branch_Audit; +DROP TABLE IF EXISTS Shop_Region_Branch; + +DROP TABLE IF EXISTS Shop_Delivery_Region_Audit; +DROP TABLE IF EXISTS Shop_Delivery_Region; +DROP TABLE IF EXISTS Shop_Region_Audit; +DROP TABLE IF EXISTS Shop_Region; + +DROP TABLE IF EXISTS Shop_Recurrence_Interval_Audit; +DROP TABLE IF EXISTS Shop_Recurrence_Interval; + +DROP TABLE IF EXISTS Shop_Category_Audit; +DROP TABLE IF EXISTS Shop_Category; + +DROP TABLE IF EXISTS Shop_General_Audit; +DROP TABLE IF EXISTS Shop_General; + +DROP TABLE IF EXISTS File_Type_Audit; +DROP TABLE IF EXISTS File_Type; + +DROP TABLE IF EXISTS Msg_Error_Type; + +DROP TABLE IF EXISTS Shop_Access_Level_Audit; +DROP TABLE IF EXISTS Shop_Access_Level; + +DROP TABLE IF EXISTS Shop_User_Change_Set; + +DROP TABLE IF EXISTS Shop_Msg_Error_Type; + +DROP TABLE IF EXISTS Shop_Product_Change_Set; diff --git a/static/sql/100.0_tbl_Shop_Product_Change_Set.sql b/static/sql/100.0_tbl_Shop_Product_Change_Set.sql new file mode 100644 index 00000000..c5640af2 --- /dev/null +++ b/static/sql/100.0_tbl_Shop_Product_Change_Set.sql @@ -0,0 +1,13 @@ + +# Product Change Sets + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Change_Set'; + +CREATE TABLE Shop_Product_Change_Set ( + id_change_set INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + comment VARCHAR(500), + updated_last_on DATETIME, + updated_last_by VARCHAR(100) +); \ No newline at end of file diff --git a/static/sql/100.1_tbl_Shop_User_Change_Set.sql b/static/sql/100.1_tbl_Shop_User_Change_Set.sql new file mode 100644 index 00000000..cd18e052 --- /dev/null +++ b/static/sql/100.1_tbl_Shop_User_Change_Set.sql @@ -0,0 +1,13 @@ + +# User Change Sets + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Change_Set'; + +CREATE TABLE IF NOT EXISTS Shop_User_Change_Set ( + id_change_set INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + comment VARCHAR(500), + updated_last_on DATETIME, + updated_last_by VARCHAR(100) +); \ No newline at end of file diff --git a/static/sql/100.2_tbl_Shop_Access_Level.sql b/static/sql/100.2_tbl_Shop_Access_Level.sql new file mode 100644 index 00000000..2a119082 --- /dev/null +++ b/static/sql/100.2_tbl_Shop_Access_Level.sql @@ -0,0 +1,21 @@ + +# Access Levels + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Access_Level'; + +CREATE TABLE IF NOT EXISTS Shop_Access_Level ( + id_access_level INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + priority INT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Access_Level_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/100.3_tbl_Shop_Access_Level_Audit.sql b/static/sql/100.3_tbl_Shop_Access_Level_Audit.sql new file mode 100644 index 00000000..83a3f932 --- /dev/null +++ b/static/sql/100.3_tbl_Shop_Access_Level_Audit.sql @@ -0,0 +1,22 @@ + +# Access Level Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Access_Level_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Access_Level_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_access_level INT NOT NULL, + CONSTRAINT FK_Shop_Access_Level_Audit_id_access_level + FOREIGN KEY (id_access_level) + REFERENCES Shop_Access_Level(id_access_level) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Access_Level_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/100_tbl_Msg_Error_Type.sql b/static/sql/100_tbl_Msg_Error_Type.sql new file mode 100644 index 00000000..10f0995c --- /dev/null +++ b/static/sql/100_tbl_Msg_Error_Type.sql @@ -0,0 +1,13 @@ + +# Error Message Type + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Msg_Error_Type'; + +CREATE TABLE IF NOT EXISTS Shop_Msg_Error_Type ( + id_type INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(500) NOT NULL, + description VARCHAR(1000) +); diff --git a/static/sql/102_tbl_File_Type.sql b/static/sql/102_tbl_File_Type.sql new file mode 100644 index 00000000..d141259f --- /dev/null +++ b/static/sql/102_tbl_File_Type.sql @@ -0,0 +1,17 @@ + +# File Types + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'File_Type'; + +CREATE TABLE IF NOT EXISTS File_Type ( + id_type INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(100), + extension VARCHAR(50), + created_on DATETIME, + created_by VARCHAR(100), + updated_last_on DATETIME, + updated_last_by VARCHAR(100) +); diff --git a/static/sql/103_tbl_File_Type_Audit.sql b/static/sql/103_tbl_File_Type_Audit.sql new file mode 100644 index 00000000..6611f84a --- /dev/null +++ b/static/sql/103_tbl_File_Type_Audit.sql @@ -0,0 +1,22 @@ + +# File Type Audit + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'File_Type_Audit'; + +CREATE TABLE IF NOT EXISTS File_Type_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_File_Type_Audit_id_type + FOREIGN KEY (id_type) + REFERENCES File_Type(id_type) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + created_on DATETIME, + created_by VARCHAR(100), + updated_last_on DATETIME, + updated_last_by VARCHAR(100) +); \ No newline at end of file diff --git a/static/sql/104_tbl_Shop_General.sql b/static/sql/104_tbl_Shop_General.sql new file mode 100644 index 00000000..0c512c52 --- /dev/null +++ b/static/sql/104_tbl_Shop_General.sql @@ -0,0 +1,17 @@ + +# Generic / shared properties + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_General'; + +CREATE TABLE IF NOT EXISTS Shop_General ( + id_general INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + quantity_max FLOAT, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT CHK_Shop_General_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/105_tbl_Shop_General_Audit.sql b/static/sql/105_tbl_Shop_General_Audit.sql new file mode 100644 index 00000000..edc1f92e --- /dev/null +++ b/static/sql/105_tbl_Shop_General_Audit.sql @@ -0,0 +1,22 @@ + +# Shop General Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_General_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_General_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_general INT NOT NULL, + CONSTRAINT FK_Shop_General_Audit_id_general + FOREIGN KEY (id_general) + REFERENCES Shop_General(id_general) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_General_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/106_tbl_Shop_Category.sql b/static/sql/106_tbl_Shop_Category.sql new file mode 100644 index 00000000..89881e8b --- /dev/null +++ b/static/sql/106_tbl_Shop_Category.sql @@ -0,0 +1,21 @@ + +# Categories + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Category'; + +CREATE TABLE IF NOT EXISTS Shop_Category ( + id_category INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + description VARCHAR(4000), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Category_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/107_tbl_Shop_Category_Audit.sql b/static/sql/107_tbl_Shop_Category_Audit.sql new file mode 100644 index 00000000..e2abe961 --- /dev/null +++ b/static/sql/107_tbl_Shop_Category_Audit.sql @@ -0,0 +1,22 @@ + +# Category Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Category_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Category_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_category INT NOT NULL, + CONSTRAINT FK_Shop_Category_Audit_id_category + FOREIGN KEY (id_category) + REFERENCES Shop_Category(id_category) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Category_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/108_tbl_Shop_Recurrence_Interval.sql b/static/sql/108_tbl_Shop_Recurrence_Interval.sql new file mode 100644 index 00000000..1d8fdf95 --- /dev/null +++ b/static/sql/108_tbl_Shop_Recurrence_Interval.sql @@ -0,0 +1,20 @@ + +# Recurrence Interval + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Recurrence_Interval'; + +CREATE TABLE IF NOT EXISTS Shop_Recurrence_Interval ( + id_interval INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + name_plural VARCHAR(256), + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Recurrence_Interval_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/109_tbl_Shop_Recurrence_Interval_Audit.sql b/static/sql/109_tbl_Shop_Recurrence_Interval_Audit.sql new file mode 100644 index 00000000..31d51958 --- /dev/null +++ b/static/sql/109_tbl_Shop_Recurrence_Interval_Audit.sql @@ -0,0 +1,22 @@ + +# Recurrence Interval Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Recurrence_Interval_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Recurrence_Interval_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_interval INT NOT NULL, + CONSTRAINT FK_Shop_Recurrence_Interval_Audit_id_interval + FOREIGN KEY (id_interval) + REFERENCES Shop_Recurrence_Interval(id_interval) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(256), + value_new VARCHAR(256), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Recurrence_Interval_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/110.0_tbl_Shop_Region.sql b/static/sql/110.0_tbl_Shop_Region.sql new file mode 100644 index 00000000..a6d157fb --- /dev/null +++ b/static/sql/110.0_tbl_Shop_Region.sql @@ -0,0 +1,20 @@ + +# Regions + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Region'; + +CREATE TABLE IF NOT EXISTS Shop_Region ( + id_region INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(200) NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Region_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/110.1_tbl_Shop_Region_Audit.sql b/static/sql/110.1_tbl_Shop_Region_Audit.sql new file mode 100644 index 00000000..b3923078 --- /dev/null +++ b/static/sql/110.1_tbl_Shop_Region_Audit.sql @@ -0,0 +1,22 @@ + +# Region Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Region_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Region_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_region INT NOT NULL, + CONSTRAINT FK_Shop_Region_Audit_id_region + FOREIGN KEY (id_region) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + name_field VARCHAR(64) NOT NULL, + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Region_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/110.2_tbl_Shop_Region_Branch.sql b/static/sql/110.2_tbl_Shop_Region_Branch.sql new file mode 100644 index 00000000..70471629 --- /dev/null +++ b/static/sql/110.2_tbl_Shop_Region_Branch.sql @@ -0,0 +1,29 @@ + +# Region Branchs + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Region_Branch'; + +CREATE TABLE IF NOT EXISTS Shop_Region_Branch ( + id_branch INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_region_parent INT NOT NULL, + CONSTRAINT FK_Shop_Region_Branch_id_region_parent + FOREIGN KEY (id_region_parent) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + id_region_child INT NOT NULL, + CONSTRAINT FK_Shop_Region_Branch_id_region_child + FOREIGN KEY (id_region_child) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + -- depth INT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Region_Branch_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/110.3_tbl_Shop_Region_Branch_Audit.sql b/static/sql/110.3_tbl_Shop_Region_Branch_Audit.sql new file mode 100644 index 00000000..f60db5c9 --- /dev/null +++ b/static/sql/110.3_tbl_Shop_Region_Branch_Audit.sql @@ -0,0 +1,22 @@ + +# Region Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Region_Branch_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Region_Branch_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_branch INT NOT NULL, + CONSTRAINT FK_Shop_Region_Branch_Audit_id_branch + FOREIGN KEY (id_branch) + REFERENCES Shop_Region_Branch(id_branch) + ON UPDATE RESTRICT, + name_field VARCHAR(64) NOT NULL, + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Region_Branch_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/110.4_tbl_Shop_Currency.sql b/static/sql/110.4_tbl_Shop_Currency.sql new file mode 100644 index 00000000..1516e295 --- /dev/null +++ b/static/sql/110.4_tbl_Shop_Currency.sql @@ -0,0 +1,23 @@ + +# Currencies + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Currency'; + +CREATE TABLE IF NOT EXISTS Shop_Currency ( + id_currency INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(255) NOT NULL, + symbol VARCHAR(1) NOT NULL, + factor_from_GBP FLOAT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Currency_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); \ No newline at end of file diff --git a/static/sql/110.5_tbl_Shop_Currency_Audit.sql b/static/sql/110.5_tbl_Shop_Currency_Audit.sql new file mode 100644 index 00000000..07beb01f --- /dev/null +++ b/static/sql/110.5_tbl_Shop_Currency_Audit.sql @@ -0,0 +1,23 @@ + +# Currency Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Currency_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Currency_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_currency INT NOT NULL, + CONSTRAINT FK_Shop_Currency_Audit_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Currency_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); \ No newline at end of file diff --git a/static/sql/110.6_tbl_Shop_Tax_Or_Surcharge.sql b/static/sql/110.6_tbl_Shop_Tax_Or_Surcharge.sql new file mode 100644 index 00000000..6adeaa52 --- /dev/null +++ b/static/sql/110.6_tbl_Shop_Tax_Or_Surcharge.sql @@ -0,0 +1,38 @@ + +# Taxes and Surcharges + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Tax_Or_Surcharge'; + +CREATE TABLE Shop_Tax_Or_Surcharge ( + id_tax INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(200) NOT NULL, + id_region_buyer INT NOT NULL, + CONSTRAINT FK_Shop_Tax_Or_Surcharge_id_region_buyer + FOREIGN KEY (id_region_buyer) + REFERENCES Shop_Region(id_region), + id_region_seller INT NOT NULL, + CONSTRAINT FK_Shop_Tax_Or_Surcharge_id_region_seller + FOREIGN KEY (id_region_seller) + REFERENCES Shop_Region(id_region), + id_currency INT, + CONSTRAINT FK_Shop_Tax_Or_Surcharge_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + fixed_fee FLOAT NOT NULL DEFAULT 0, + multiplier FLOAT NOT NULL DEFAULT 1 CHECK (multiplier > 0), + apply_fixed_fee_before_multiplier BIT DEFAULT 1, + quantity_min FLOAT NOT NULL DEFAULT 0, + quantity_max FLOAT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Tax_Or_Surcharge_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/110.7_tbl_Shop_Tax_Or_Surcharge_Audit.sql b/static/sql/110.7_tbl_Shop_Tax_Or_Surcharge_Audit.sql new file mode 100644 index 00000000..e36762db --- /dev/null +++ b/static/sql/110.7_tbl_Shop_Tax_Or_Surcharge_Audit.sql @@ -0,0 +1,23 @@ + +# Tax Or Surcharge Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Tax_Or_Surcharge_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Tax_Or_Surcharge_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_tax INT NOT NULL, + CONSTRAINT FK_Shop_Tax_Or_Surcharge_Audit_id_discount + FOREIGN KEY (id_tax) + REFERENCES Shop_Tax_Or_Surcharge(id_tax) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Tax_Or_Surcharge_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); \ No newline at end of file diff --git a/static/sql/110.8_tbl_Shop_Product.sql b/static/sql/110.8_tbl_Shop_Product.sql new file mode 100644 index 00000000..c8181eb9 --- /dev/null +++ b/static/sql/110.8_tbl_Shop_Product.sql @@ -0,0 +1,48 @@ + +# Products + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product'; + +CREATE TABLE IF NOT EXISTS Shop_Product ( + id_product INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL, + -- description VARCHAR(4000), + id_category INT NOT NULL, + has_variations BIT NOT NULL, + /* + price_GBP_full FLOAT, + price_GBP_min FLOAT, + # ratio_discount_overall FLOAT NOT NULL DEFAULT 0, + CONSTRAINT FK_Shop_Product_id_category + FOREIGN KEY (id_category) + REFERENCES Shop_Category(id_category) + ON UPDATE RESTRICT, + latency_manuf INT, + quantity_min FLOAT, + quantity_max FLOAT, + quantity_step FLOAT, + quantity_stock FLOAT, + is_subscription BIT, + id_recurrence_interval INT, + CONSTRAINT FK_Shop_Product_id_recurrence_interval + FOREIGN KEY (id_recurrence_interval) + REFERENCES Shop_Recurrence_Interval(id_interval), + count_recurrence_interval INT, + */ + id_access_level_required INT NOT NULL, + CONSTRAINT FK_Shop_Product_id_access_level_required + FOREIGN KEY (id_access_level_required) + REFERENCES Shop_Access_Level(id_access_level), + # id_stripe_product VARCHAR(100), + # id_stripe_price VARCHAR(100) NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/110.9_tbl_Shop_Product_Audit.sql b/static/sql/110.9_tbl_Shop_Product_Audit.sql new file mode 100644 index 00000000..7627dd3a --- /dev/null +++ b/static/sql/110.9_tbl_Shop_Product_Audit.sql @@ -0,0 +1,22 @@ + +# Products + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Audit_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/112_tbl_Shop_Variation_Type.sql b/static/sql/112_tbl_Shop_Variation_Type.sql new file mode 100644 index 00000000..9845b88c --- /dev/null +++ b/static/sql/112_tbl_Shop_Variation_Type.sql @@ -0,0 +1,21 @@ + +# Variation Types + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Variation_Type'; + +CREATE TABLE IF NOT EXISTS Shop_Variation_Type ( + id_type INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + name_plural VARCHAR(256), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Variation_Type_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/113.0_tbl_Shop_Variation_Type_Audit.sql b/static/sql/113.0_tbl_Shop_Variation_Type_Audit.sql new file mode 100644 index 00000000..aeb2cfb8 --- /dev/null +++ b/static/sql/113.0_tbl_Shop_Variation_Type_Audit.sql @@ -0,0 +1,22 @@ + +# Variation Type Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Variation_Type_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Variation_Type_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_Shop_Variation_Type_Audit_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Variation_Type(id_type) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Variation_Type_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/114_tbl_Shop_Variation.sql b/static/sql/114_tbl_Shop_Variation.sql new file mode 100644 index 00000000..520d9b1c --- /dev/null +++ b/static/sql/114_tbl_Shop_Variation.sql @@ -0,0 +1,25 @@ + +# Variations + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Variation'; + +CREATE TABLE Shop_Variation ( + id_variation INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_Shop_Variation_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Variation_Type(id_type) + ON UPDATE RESTRICT, + code VARCHAR(50), + name VARCHAR(255), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Variation_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/115_tbl_Shop_Variation_Audit.sql b/static/sql/115_tbl_Shop_Variation_Audit.sql new file mode 100644 index 00000000..21ed7962 --- /dev/null +++ b/static/sql/115_tbl_Shop_Variation_Audit.sql @@ -0,0 +1,22 @@ + +# Variation Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Variation_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Variation_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_variation INT NOT NULL, + CONSTRAINT FK_Shop_Variation_Audit_id_variation + FOREIGN KEY (id_variation) + REFERENCES Shop_Variation(id_variation) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Variation_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/117.1_tbl_Shop_Product_Permutation.sql b/static/sql/117.1_tbl_Shop_Product_Permutation.sql new file mode 100644 index 00000000..02afaa26 --- /dev/null +++ b/static/sql/117.1_tbl_Shop_Product_Permutation.sql @@ -0,0 +1,45 @@ + +# Product Permutation + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Permutation'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Permutation ( + id_permutation INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Variation_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + -- name VARCHAR(255) NOT NULL, + description VARCHAR(4000) NOT NULL, + cost_local_manufacturing FLOAT NOT NULL, + id_currency_cost_manufacturing INT NOT NULL, + profit_local_min FLOAT NOT NULL, + id_currency_profit_min INT NOT NULL, + latency_manufacture INT NOT NULL, + quantity_min FLOAT NOT NULL, + quantity_max FLOAT NOT NULL, + quantity_step FLOAT NOT NULL, + quantity_stock FLOAT NOT NULL, + is_subscription BIT NOT NULL, + id_recurrence_interval INT, + CONSTRAINT FK_Shop_Product_Permutation_id_recurrence_interval + FOREIGN KEY (id_recurrence_interval) + REFERENCES Shop_Recurrence_Interval(id_interval), + count_recurrence_interval INT, + id_access_level_required INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_id_access_level_required + FOREIGN KEY (id_access_level_required) + REFERENCES Shop_Access_Level(id_access_level), + id_stripe_product VARCHAR(100) NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Variation_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/117.2_tbl_Shop_Product_Permutation_Audit.sql b/static/sql/117.2_tbl_Shop_Product_Permutation_Audit.sql new file mode 100644 index 00000000..3600049a --- /dev/null +++ b/static/sql/117.2_tbl_Shop_Product_Permutation_Audit.sql @@ -0,0 +1,23 @@ + +# Product Permutation Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Permutation_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Permutation_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_permutation INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_Audit_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); diff --git a/static/sql/117.3_tbl_Shop_Product_Permutation_Variation_Link.sql b/static/sql/117.3_tbl_Shop_Product_Permutation_Variation_Link.sql new file mode 100644 index 00000000..2cb10164 --- /dev/null +++ b/static/sql/117.3_tbl_Shop_Product_Permutation_Variation_Link.sql @@ -0,0 +1,28 @@ + +# Product Permutation Variation Link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Permutation_Variation_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Permutation_Variation_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_permutation INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + id_variation INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_id_variation + FOREIGN KEY (id_variation) + REFERENCES Shop_Variation(id_variation) + ON UPDATE RESTRICT, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/117.4_tbl_Shop_Product_Permutation_Variation_Link_Audit.sql b/static/sql/117.4_tbl_Shop_Product_Permutation_Variation_Link_Audit.sql new file mode 100644 index 00000000..b7da4b47 --- /dev/null +++ b/static/sql/117.4_tbl_Shop_Product_Permutation_Variation_Link_Audit.sql @@ -0,0 +1,23 @@ + +# Product Permutation Variation Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Permutation_Variation_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Permutation_Variation_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Permutation_Variation_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); \ No newline at end of file diff --git a/static/sql/117.5_tbl_Shop_Product_Currency_Link.sql b/static/sql/117.5_tbl_Shop_Product_Currency_Link.sql new file mode 100644 index 00000000..cbbac324 --- /dev/null +++ b/static/sql/117.5_tbl_Shop_Product_Currency_Link.sql @@ -0,0 +1,40 @@ + +# Product Currency link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Currency_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Currency_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_permutation INT NULL, + CONSTRAINT FK_Shop_Product_Currency_Link_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + id_currency INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Link_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + id_region_purchase INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Link_id_region_purchase + FOREIGN KEY (id_region_purchase) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + price_local_VAT_incl FLOAT NULL, + price_local_VAT_excl FLOAT NULL, + id_stripe_price VARCHAR(200), + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Currency_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/117.5_tbl_Shop_Product_Currency_Region_Link.sql b/static/sql/117.5_tbl_Shop_Product_Currency_Region_Link.sql new file mode 100644 index 00000000..8478672d --- /dev/null +++ b/static/sql/117.5_tbl_Shop_Product_Currency_Region_Link.sql @@ -0,0 +1,40 @@ + +# Product Currency Region link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Currency_Region_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Currency_Region_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_permutation INT NULL, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + id_currency INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + id_region_purchase INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_region_purchase + FOREIGN KEY (id_region_purchase) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + price_local_VAT_incl FLOAT NULL, + price_local_VAT_excl FLOAT NULL, + id_stripe_price VARCHAR(200), + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/117.6_tbl_Shop_Product_Currency_Link_Audit.sql b/static/sql/117.6_tbl_Shop_Product_Currency_Link_Audit.sql new file mode 100644 index 00000000..e8b6b654 --- /dev/null +++ b/static/sql/117.6_tbl_Shop_Product_Currency_Link_Audit.sql @@ -0,0 +1,22 @@ + +# Product Currency Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Currency_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Currency_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Currency_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/117.6_tbl_Shop_Product_Currency_Region_Link_Audit.sql b/static/sql/117.6_tbl_Shop_Product_Currency_Region_Link_Audit.sql new file mode 100644 index 00000000..cd8dc4fb --- /dev/null +++ b/static/sql/117.6_tbl_Shop_Product_Currency_Region_Link_Audit.sql @@ -0,0 +1,22 @@ + +# Product Currency Region Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Currency_Region_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Currency_Region_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Currency_Region_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Currency_Region_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/118_tbl_Shop_Image_Type.sql b/static/sql/118_tbl_Shop_Image_Type.sql new file mode 100644 index 00000000..686d4130 --- /dev/null +++ b/static/sql/118_tbl_Shop_Image_Type.sql @@ -0,0 +1,21 @@ + +# Image Types + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Image_Type'; + +CREATE TABLE IF NOT EXISTS Shop_Image_Type ( + id_type INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + name_plural VARCHAR(256), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Image_Type_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/119_tbl_Shop_Image_Type_Audit.sql b/static/sql/119_tbl_Shop_Image_Type_Audit.sql new file mode 100644 index 00000000..717973d7 --- /dev/null +++ b/static/sql/119_tbl_Shop_Image_Type_Audit.sql @@ -0,0 +1,22 @@ + +# Image Type Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Image_Type_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Image_Type_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_Shop_Image_Type_Audit_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Image_Type(id_type) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Image_Type_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/120_tbl_Shop_Image.sql b/static/sql/120_tbl_Shop_Image.sql new file mode 100644 index 00000000..59b014bb --- /dev/null +++ b/static/sql/120_tbl_Shop_Image.sql @@ -0,0 +1,35 @@ + +# Images + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Image'; + +CREATE TABLE IF NOT EXISTS Shop_Image ( + id_image INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type_image INT NOT NULL, + CONSTRAINT FK_Shop_Image_id_type_image + FOREIGN KEY (id_type_image) + REFERENCES Shop_Image_Type(id_type), + id_type_file INT NOT NULL, + CONSTRAINT FK_Shop_Image_id_type_file + FOREIGN KEY (id_type_file) + REFERENCES File_Type(id_type), + id_product INT NULL, + CONSTRAINT FK_Shop_Image_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NULL, + CONSTRAINT FK_Shop_Image_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + url VARCHAR(255), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Image_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/121_tbl_Shop_Image_Audit.sql b/static/sql/121_tbl_Shop_Image_Audit.sql new file mode 100644 index 00000000..02bca58a --- /dev/null +++ b/static/sql/121_tbl_Shop_Image_Audit.sql @@ -0,0 +1,21 @@ + +# Image Type Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Image_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Image_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_image INT NOT NULL, + CONSTRAINT FK_Shop_Image_Audit_id_image + FOREIGN KEY (id_image) + REFERENCES Shop_Image(id_image), + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Image_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/122_tbl_Shop_Delivery_Option.sql b/static/sql/122_tbl_Shop_Delivery_Option.sql new file mode 100644 index 00000000..b1d30097 --- /dev/null +++ b/static/sql/122_tbl_Shop_Delivery_Option.sql @@ -0,0 +1,25 @@ + +# Delivery Options + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Delivery_Option'; + +CREATE TABLE IF NOT EXISTS Shop_Delivery_Option ( + id_option INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(100) NOT NULL, + description VARCHAR(4000), + latency_delivery_min INT NOT NULL, + latency_delivery_max INT NOT NULL, + quantity_min INT NOT NULL, + quantity_max INT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Delivery_Option_Type_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/123_tbl_Shop_Delivery_Option_Audit.sql b/static/sql/123_tbl_Shop_Delivery_Option_Audit.sql new file mode 100644 index 00000000..bf354b31 --- /dev/null +++ b/static/sql/123_tbl_Shop_Delivery_Option_Audit.sql @@ -0,0 +1,22 @@ + +# Delivery Option Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Delivery_Option_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Delivery_Option_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_option INT NOT NULL, + CONSTRAINT FK_Shop_Delivery_Option_Audit_id_option + FOREIGN KEY (id_option) + REFERENCES Shop_Delivery_Option(id_option) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Delivery_Option_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/124_tbl_Shop_Product_Delivery_Option_Link.sql b/static/sql/124_tbl_Shop_Product_Delivery_Option_Link.sql new file mode 100644 index 00000000..11c9b6b9 --- /dev/null +++ b/static/sql/124_tbl_Shop_Product_Delivery_Option_Link.sql @@ -0,0 +1,44 @@ + +# Delivery Option + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Delivery_Option_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Delivery_Option_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_permutation INT, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + id_delivery_option INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_id_delivery_option + FOREIGN KEY (id_delivery_option) + REFERENCES Shop_Delivery_Option(id_option) + ON UPDATE RESTRICT, + id_region INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_id_region + FOREIGN KEY (id_region) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + id_currency INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + price_local FLOAT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/125_tbl_Shop_Product_Delivery_Option_Link_Audit.sql b/static/sql/125_tbl_Shop_Product_Delivery_Option_Link_Audit.sql new file mode 100644 index 00000000..9bda5923 --- /dev/null +++ b/static/sql/125_tbl_Shop_Product_Delivery_Option_Link_Audit.sql @@ -0,0 +1,22 @@ + +# Delivery Option Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Delivery_Option_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Delivery_Option_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Delivery_Option_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(64) NOT NULL, + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Option_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/130.4_tbl_Shop_Discount.sql b/static/sql/130.4_tbl_Shop_Discount.sql new file mode 100644 index 00000000..fb2f70e0 --- /dev/null +++ b/static/sql/130.4_tbl_Shop_Discount.sql @@ -0,0 +1,48 @@ + +# Discounts + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Discount'; + +CREATE TABLE Shop_Discount ( + id_discount INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(200) NOT NULL, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Discount_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT, + CONSTRAINT FK_Shop_Discount_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + /* + id_delivery_region INT, + CONSTRAINT FK_Shop_Discount_id_delivery_region + FOREIGN KEY (id_delivery_region) + REFERENCES Shop_Delivery_Region(id_region) + ON UPDATE RESTRICT, + id_currency INT, + CONSTRAINT FK_Shop_Discount_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + */ + multiplier FLOAT NOT NULL DEFAULT 1 CHECK (multiplier > 0), + subtractor FLOAT NOT NULL DEFAULT 0, + apply_multiplier_first BIT DEFAULT 1, + quantity_min FLOAT NOT NULL DEFAULT 0, + quantity_max FLOAT NOT NULL, + date_start DATETIME NOT NULL, + date_end DATETIME NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Discount_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/131_tbl_Shop_Discount_Audit.sql b/static/sql/131_tbl_Shop_Discount_Audit.sql new file mode 100644 index 00000000..730782b4 --- /dev/null +++ b/static/sql/131_tbl_Shop_Discount_Audit.sql @@ -0,0 +1,23 @@ + +# Discount Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Discount_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Discount_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_discount INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Audit_id_discount + FOREIGN KEY (id_discount) + REFERENCES Shop_Discount(id_discount) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); \ No newline at end of file diff --git a/static/sql/132_tbl_Shop_Discount_Region_Currency_Link.sql b/static/sql/132_tbl_Shop_Discount_Region_Currency_Link.sql new file mode 100644 index 00000000..bb2864e6 --- /dev/null +++ b/static/sql/132_tbl_Shop_Discount_Region_Currency_Link.sql @@ -0,0 +1,32 @@ + +# Discount Region Currency Link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Discount_Region_Currency_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Discount_Region_Currency_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_discount INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Region_Currency_Link_id_discount + FOREIGN KEY (id_discount) + REFERENCES Shop_Discount(id_discount) + ON UPDATE RESTRICT, + id_region INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Region_Currency_Link_id_region + FOREIGN KEY (id_region) + REFERENCES Shop_Region(id_region) + ON UPDATE RESTRICT, + id_currency INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Region_Currency_Link_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Discount_Region_Currency_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/133_tbl_Shop_Discount_Region_Currency_Link_Audit.sql b/static/sql/133_tbl_Shop_Discount_Region_Currency_Link_Audit.sql new file mode 100644 index 00000000..d9e53a65 --- /dev/null +++ b/static/sql/133_tbl_Shop_Discount_Region_Currency_Link_Audit.sql @@ -0,0 +1,23 @@ + +# Discount Region Currency Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Discount_Region_Currency_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Discount_Region_Currency_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Region_Currency_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Discount_Region_Currency_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Discount_Region_Currency_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); \ No newline at end of file diff --git a/static/sql/153_tbl_Shop_Permission_Group.sql b/static/sql/153_tbl_Shop_Permission_Group.sql new file mode 100644 index 00000000..78341d66 --- /dev/null +++ b/static/sql/153_tbl_Shop_Permission_Group.sql @@ -0,0 +1,21 @@ + +# Permission Groups + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Permission_Group'; + +CREATE TABLE IF NOT EXISTS Shop_Permission_Group ( + id_group INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Permission_Group_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); \ No newline at end of file diff --git a/static/sql/154_tbl_Shop_Permission_Group_Audit.sql b/static/sql/154_tbl_Shop_Permission_Group_Audit.sql new file mode 100644 index 00000000..875a7464 --- /dev/null +++ b/static/sql/154_tbl_Shop_Permission_Group_Audit.sql @@ -0,0 +1,23 @@ + +# Permission Group Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Permission_Group_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Permission_Group_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_group INT NOT NULL, + CONSTRAINT FK_Shop_Permission_Group_Audit_id_group + FOREIGN KEY (id_group) + REFERENCES Shop_Permission_Group(id_group) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Permission_Group_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); \ No newline at end of file diff --git a/static/sql/155_tbl_Shop_Permission.sql b/static/sql/155_tbl_Shop_Permission.sql new file mode 100644 index 00000000..7bc82f3e --- /dev/null +++ b/static/sql/155_tbl_Shop_Permission.sql @@ -0,0 +1,29 @@ + +# Permissions + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Permission'; + +CREATE TABLE IF NOT EXISTS Shop_Permission ( + id_permission INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + id_permission_group INT NOT NULL, + CONSTRAINT FK_Shop_Permission_id_permission_group + FOREIGN KEY (id_permission_group) + REFERENCES Shop_Permission_Group(id_group) + ON UPDATE RESTRICT, + id_access_level_required INT NOT NULL, + CONSTRAINT FK_Shop_Permission_id_access_level_required + FOREIGN KEY (id_access_level_required) + REFERENCES Shop_Access_Level(id_access_level), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Permission_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/156_tbl_Shop_Permission_Audit.sql b/static/sql/156_tbl_Shop_Permission_Audit.sql new file mode 100644 index 00000000..81109f60 --- /dev/null +++ b/static/sql/156_tbl_Shop_Permission_Audit.sql @@ -0,0 +1,23 @@ + +# Permission Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Permission_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Permission_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_permission INT NOT NULL, + CONSTRAINT FK_Shop_Permission_Audit_id_permission + FOREIGN KEY (id_permission) + REFERENCES Shop_Permission(id_permission) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Permission_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); \ No newline at end of file diff --git a/static/sql/157_tbl_Shop_Role.sql b/static/sql/157_tbl_Shop_Role.sql new file mode 100644 index 00000000..afad6404 --- /dev/null +++ b/static/sql/157_tbl_Shop_Role.sql @@ -0,0 +1,20 @@ + +# Roles + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Role'; + +CREATE TABLE IF NOT EXISTS Shop_Role ( + id_role INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Role_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/158_tbl_Shop_Role_Audit.sql b/static/sql/158_tbl_Shop_Role_Audit.sql new file mode 100644 index 00000000..b9a1deff --- /dev/null +++ b/static/sql/158_tbl_Shop_Role_Audit.sql @@ -0,0 +1,23 @@ + +# Role Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Role_Audit'; + +CREATE TABLE Shop_Role_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_role INT NOT NULL, + CONSTRAINT FK_Shop_Role_Audit_id_role + FOREIGN KEY (id_role) + REFERENCES Shop_Role(id_role) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Role_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); \ No newline at end of file diff --git a/static/sql/159_tbl_Shop_Role_Permission_Link.sql b/static/sql/159_tbl_Shop_Role_Permission_Link.sql new file mode 100644 index 00000000..ab6a6432 --- /dev/null +++ b/static/sql/159_tbl_Shop_Role_Permission_Link.sql @@ -0,0 +1,31 @@ + +# Role Permission link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Role_Permission_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Role_Permission_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_role INT, + CONSTRAINT FK_Shop_Role_Permission_Link_id_role + FOREIGN KEY (id_role) + REFERENCES Shop_Role(id_role) + ON UPDATE RESTRICT, + id_permission INT, + CONSTRAINT FK_Shop_Role_Permission_Link_id_permission + FOREIGN KEY (id_permission) + REFERENCES Shop_Permission(id_permission) + ON UPDATE RESTRICT, + id_access_level INT, + CONSTRAINT FK_Shop_Role_Permission_Link_id_access_level + FOREIGN KEY (id_access_level) + REFERENCES Shop_Access_Level(id_access_level), + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Role_Permission_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/160_tbl_Shop_Role_Permission_Link_Audit.sql b/static/sql/160_tbl_Shop_Role_Permission_Link_Audit.sql new file mode 100644 index 00000000..2a858571 --- /dev/null +++ b/static/sql/160_tbl_Shop_Role_Permission_Link_Audit.sql @@ -0,0 +1,22 @@ + +# Role Permission link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Role_Permission_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Role_Permission_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Role_Permission_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Role_Permission_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Role_Permission_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/161_tbl_Shop_User.sql b/static/sql/161_tbl_Shop_User.sql new file mode 100644 index 00000000..9fcd7ccf --- /dev/null +++ b/static/sql/161_tbl_Shop_User.sql @@ -0,0 +1,21 @@ + +# Users + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User'; + +CREATE TABLE IF NOT EXISTS Shop_User ( + id_user VARCHAR(200) NOT NULL PRIMARY KEY, + name VARCHAR(255) NOT NULL, + email VARCHAR(254) NOT NULL, + email_verified BIT NOT NULL DEFAULT 0, + is_super_user BIT NOT NULL DEFAULT 0, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_User_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); diff --git a/static/sql/162_tbl_Shop_User_Audit.sql b/static/sql/162_tbl_Shop_User_Audit.sql new file mode 100644 index 00000000..fa92d53a --- /dev/null +++ b/static/sql/162_tbl_Shop_User_Audit.sql @@ -0,0 +1,23 @@ + +# User Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_User_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_Shop_User_Audit_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_User_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); \ No newline at end of file diff --git a/static/sql/163_tbl_Shop_User_Role_Link.sql b/static/sql/163_tbl_Shop_User_Role_Link.sql new file mode 100644 index 00000000..7988de44 --- /dev/null +++ b/static/sql/163_tbl_Shop_User_Role_Link.sql @@ -0,0 +1,26 @@ + +# User Role link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Role_Link'; + +CREATE TABLE IF NOT EXISTS Shop_User_Role_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_Shop_User_Role_Link_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user) + ON UPDATE RESTRICT, + id_role INT NOT NULL, + CONSTRAINT FK_Shop_User_Role_Link_id_role + FOREIGN KEY (id_role) + REFERENCES Shop_Role(id_role), + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_User_Role_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/164_tbl_Shop_User_Role_Link_Audit.sql b/static/sql/164_tbl_Shop_User_Role_Link_Audit.sql new file mode 100644 index 00000000..dd8afa4b --- /dev/null +++ b/static/sql/164_tbl_Shop_User_Role_Link_Audit.sql @@ -0,0 +1,22 @@ + +# User Role Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Role_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_User_Role_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_User_Role_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_User_Role_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_User_Role_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); diff --git a/static/sql/165_tbl_Shop_Address.sql b/static/sql/165_tbl_Shop_Address.sql new file mode 100644 index 00000000..9c8942a1 --- /dev/null +++ b/static/sql/165_tbl_Shop_Address.sql @@ -0,0 +1,31 @@ + +# Addresses + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Address'; + +CREATE TABLE Shop_Address ( + id_address INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_Shop_Address_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user) + ON UPDATE RESTRICT, + -- region VARCHAR(100) NOT NULL, + id_region INT NOT NULL, + name_full VARCHAR(255) NOT NULL, + phone_number VARCHAR(20) NOT NULL, + postcode VARCHAR(20) NOT NULL, + address_line_1 VARCHAR(100) NOT NULL, + address_line_2 VARCHAR(100) NOT NULL, + city VARCHAR(50) NOT NULL, + county VARCHAR(100) NOT NULL, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Address_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/166_tbl_Shop_Address_Audit.sql b/static/sql/166_tbl_Shop_Address_Audit.sql new file mode 100644 index 00000000..ee351e22 --- /dev/null +++ b/static/sql/166_tbl_Shop_Address_Audit.sql @@ -0,0 +1,23 @@ + +# Address Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Address_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Address_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_address INT NOT NULL, + CONSTRAINT FK_Shop_Address_Audit_id_address + FOREIGN KEY (id_address) + REFERENCES Shop_Address(id_address) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Address_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); \ No newline at end of file diff --git a/static/sql/167_tbl_Shop_User_Basket.sql b/static/sql/167_tbl_Shop_User_Basket.sql new file mode 100644 index 00000000..d91fad44 --- /dev/null +++ b/static/sql/167_tbl_Shop_User_Basket.sql @@ -0,0 +1,39 @@ + +# User Basket (Product Link) + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Basket'; + +CREATE TABLE IF NOT EXISTS Shop_User_Basket ( + id_item INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_Shop_User_Basket_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user) + ON UPDATE RESTRICT, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_User_Basket_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_permutation INT, + CONSTRAINT FK_Shop_User_Basket_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + quantity INT NOT NULL, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set_user INT, + CONSTRAINT FK_Shop_User_Basket_id_change_set_user + FOREIGN KEY (id_change_set_user) + REFERENCES Shop_User_Change_Set(id_change_set) + /* + id_change_set_product INT, + CONSTRAINT FK_Shop_User_Basket_id_change_set_product + FOREIGN KEY (id_change_set_product) + REFERENCES Shop_Product_Change_Set(id_change_set) + */ +); diff --git a/static/sql/168_tbl_Shop_User_Basket_Audit.sql b/static/sql/168_tbl_Shop_User_Basket_Audit.sql new file mode 100644 index 00000000..d1cf8aaa --- /dev/null +++ b/static/sql/168_tbl_Shop_User_Basket_Audit.sql @@ -0,0 +1,27 @@ + +# Product Basket Audits +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Basket_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_User_Basket_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_item INT NOT NULL, + CONSTRAINT FK_Shop_User_Basket_Audit_id_link + FOREIGN KEY (id_item) + REFERENCES Shop_User_Basket(id_item) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set_user INT, + CONSTRAINT FK_Shop_User_Basket_Audit_id_change_set_user + FOREIGN KEY (id_change_set_user) + REFERENCES Shop_User_Change_Set(id_change_set) + /* + id_change_set_product INT, + CONSTRAINT FK_Shop_User_Basket_Audit_id_change_set_product + FOREIGN KEY (id_change_set_product) + REFERENCES Shop_Product_Change_Set(id_change_set) + */ +); diff --git a/static/sql/169_tbl_Shop_User_Order_Status.sql b/static/sql/169_tbl_Shop_User_Order_Status.sql new file mode 100644 index 00000000..19f18180 --- /dev/null +++ b/static/sql/169_tbl_Shop_User_Order_Status.sql @@ -0,0 +1,21 @@ + +# User Order Types + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Order_Status'; + +CREATE TABLE IF NOT EXISTS Shop_User_Order_Status ( + id_status INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + name_plural VARCHAR(256), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_User_Order_Status_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); diff --git a/static/sql/170_tbl_Shop_User_Order_Status_Audit.sql b/static/sql/170_tbl_Shop_User_Order_Status_Audit.sql new file mode 100644 index 00000000..da03ea4a --- /dev/null +++ b/static/sql/170_tbl_Shop_User_Order_Status_Audit.sql @@ -0,0 +1,22 @@ + +# Order Type Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Order_Status_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_User_Order_Status_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_status INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Status_Audit_id_status + FOREIGN KEY (id_status) + REFERENCES Shop_User_Order_Status(id_status) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Status_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/171_tbl_Shop_User_Order.sql b/static/sql/171_tbl_Shop_User_Order.sql new file mode 100644 index 00000000..57d3a62a --- /dev/null +++ b/static/sql/171_tbl_Shop_User_Order.sql @@ -0,0 +1,39 @@ + +# User Order + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Order'; + +CREATE TABLE IF NOT EXISTS Shop_User_Order ( + id_order INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_Shop_User_Order_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user) + ON UPDATE RESTRICT, + value_total FLOAT, + id_order_status INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_id_order_status + FOREIGN KEY (id_order_status) + REFERENCES Shop_User_Order_Status(id_status), + id_checkout_session VARCHAR(200) NOT NULL, + id_currency INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency) + ON UPDATE RESTRICT, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set_user INT, + CONSTRAINT FK_Shop_User_Order_id_change_set_user + FOREIGN KEY (id_change_set_user) + REFERENCES Shop_User_Change_Set(id_change_set) + /* + id_change_set_product INT, + CONSTRAINT FK_Shop_User_Basket_id_change_set_product + FOREIGN KEY (id_change_set_product) + REFERENCES Shop_Product_Change_Set(id_change_set) + */ +); diff --git a/static/sql/172_tbl_Shop_User_Order_Audit.sql b/static/sql/172_tbl_Shop_User_Order_Audit.sql new file mode 100644 index 00000000..77961937 --- /dev/null +++ b/static/sql/172_tbl_Shop_User_Order_Audit.sql @@ -0,0 +1,27 @@ + +# User Order Audits +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Order_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_User_Order_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_order INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Audit_id_order + FOREIGN KEY (id_order) + REFERENCES Shop_User_Order(id_order) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set_user INT, + CONSTRAINT FK_Shop_User_Order_Audit_id_change_set_user + FOREIGN KEY (id_change_set_user) + REFERENCES Shop_User_Change_Set(id_change_set) + /* + id_change_set_product INT, + CONSTRAINT FK_Shop_User_Basket_Audit_id_change_set_product + FOREIGN KEY (id_change_set_product) + REFERENCES Shop_Product_Change_Set(id_change_set) + */ +); diff --git a/static/sql/173_tbl_Shop_User_Order_Product_Link.sql b/static/sql/173_tbl_Shop_User_Order_Product_Link.sql new file mode 100644 index 00000000..7fa9e178 --- /dev/null +++ b/static/sql/173_tbl_Shop_User_Order_Product_Link.sql @@ -0,0 +1,33 @@ + +# User Order Product link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Order_Product_Link'; + +CREATE TABLE IF NOT EXISTS Shop_User_Order_Product_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_order INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Product_Link_id_order + FOREIGN KEY (id_order) + REFERENCES Shop_User_Order(id_order) + ON UPDATE RESTRICT, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Product_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_permutation INT NULL, + CONSTRAINT FK_Shop_User_Order_Product_Link_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + quantity FLOAT NOT NULL, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_User_Order_Product_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/174_tbl_Shop_User_Order_Product_Link_Audit.sql b/static/sql/174_tbl_Shop_User_Order_Product_Link_Audit.sql new file mode 100644 index 00000000..23e87527 --- /dev/null +++ b/static/sql/174_tbl_Shop_User_Order_Product_Link_Audit.sql @@ -0,0 +1,22 @@ + +# User Order Product Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Order_Product_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_User_Order_Product_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Product_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_User_Order_Product_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_User_Order_Product_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); diff --git a/static/sql/301.1_tri_Shop_User_Change_Set.sql b/static/sql/301.1_tri_Shop_User_Change_Set.sql new file mode 100644 index 00000000..4001a148 --- /dev/null +++ b/static/sql/301.1_tri_Shop_User_Change_Set.sql @@ -0,0 +1,21 @@ + +# Shop User Change Set + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User_Change_Set; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Change_Set +BEFORE INSERT ON Shop_User_Change_Set +FOR EACH ROW +BEGIN + IF NEW.updated_last_on <=> NULL THEN + SET NEW.updated_last_on = NOW(); + END IF; + IF NEW.updated_last_by <=> NULL THEN + SET NEW.updated_last_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/301.2_tri_Shop_Access_Level.sql b/static/sql/301.2_tri_Shop_Access_Level.sql new file mode 100644 index 00000000..a00e9654 --- /dev/null +++ b/static/sql/301.2_tri_Shop_Access_Level.sql @@ -0,0 +1,63 @@ + +# Shop Access Level + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Access_Level; +DROP TRIGGER IF EXISTS before_update_Shop_Access_Level; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Access_Level +BEFORE INSERT ON Shop_Access_Level +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Access_Level +BEFORE UPDATE ON Shop_Access_Level +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Access_Level_Audit ( + id_access_level, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_access_level, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT (OLD.code <=> NEW.code) + UNION + # Changed name + SELECT NEW.id_access_level, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT (OLD.name <=> NEW.name) + UNION + # Changed priority + SELECT NEW.id_access_level, 'priority', CONVERT(OLD.priority, CHAR), CONVERT(NEW.priority, CHAR), NEW.id_change_set + WHERE NOT (OLD.priority <=> NEW.priority) + UNION + # Changed active + SELECT NEW.id_access_level, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_access_level, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; diff --git a/static/sql/301_tri_Shop_Product_Change_Set.sql b/static/sql/301_tri_Shop_Product_Change_Set.sql new file mode 100644 index 00000000..add05a34 --- /dev/null +++ b/static/sql/301_tri_Shop_Product_Change_Set.sql @@ -0,0 +1,20 @@ + +# Product Change Set + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Change_Set; + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Change_Set +BEFORE INSERT ON Shop_Product_Change_Set +FOR EACH ROW +BEGIN + IF NEW.updated_last_on <=> NULL THEN + SET NEW.updated_last_on = NOW(); + END IF; + IF NEW.updated_last_by <=> NULL THEN + SET NEW.updated_last_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; diff --git a/static/sql/302_tri_File_Type.sql b/static/sql/302_tri_File_Type.sql new file mode 100644 index 00000000..958db37d --- /dev/null +++ b/static/sql/302_tri_File_Type.sql @@ -0,0 +1,43 @@ + +# File Type + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_File_Type; +DROP TRIGGER IF EXISTS before_update_File_Type; + +DELIMITER // +CREATE TRIGGER before_insert_File_Type +BEFORE INSERT ON File_Type +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_File_Type +BEFORE UPDATE ON File_Type +FOR EACH ROW +BEGIN + INSERT INTO File_Type_Audit ( + id_type, + name_field, + value_prev, + value_new + ) + # Changed code + SELECT NEW.id_type, 'code', OLD.code, NEW.code + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_type, 'name', OLD.name, NEW.name + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed extension + SELECT NEW.id_type, 'extension', CONVERT(OLD.extension, CHAR), CONVERT(NEW.extension, CHAR) + WHERE NOT OLD.extension <=> NEW.extension + ; +END // +DELIMITER ; diff --git a/static/sql/303_tri_File_Type_Audit.sql b/static/sql/303_tri_File_Type_Audit.sql new file mode 100644 index 00000000..cadea862 --- /dev/null +++ b/static/sql/303_tri_File_Type_Audit.sql @@ -0,0 +1,28 @@ + +# File Type Audits + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_File_Type_Audit; +DROP TRIGGER IF EXISTS before_update_File_Type_Audit; + + +DELIMITER // +CREATE TRIGGER before_insert_File_Type_Audit +BEFORE INSERT ON File_Type_Audit +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_File_Type_Audit +BEFORE UPDATE ON File_Type_Audit +FOR EACH ROW +BEGIN + SET NEW.updated_last_on = NOW(); + SET NEW.updated_last_by = CURRENT_USER(); +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/304_tri_Shop_General.sql b/static/sql/304_tri_Shop_General.sql new file mode 100644 index 00000000..9829f428 --- /dev/null +++ b/static/sql/304_tri_Shop_General.sql @@ -0,0 +1,41 @@ + +# Shop General + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_General; +DROP TRIGGER IF EXISTS before_update_Shop_General; + +DELIMITER // +CREATE TRIGGER before_insert_Shop_General +BEFORE INSERT ON Shop_General +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_Shop_General +BEFORE UPDATE ON Shop_General +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_General_Audit ( + id_general, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed quantity max + SELECT NEW.id_general, 'quantity_max', CONVERT(OLD.quantity_max, CHAR), CONVERT(NEW.quantity_max, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/306_tri_Shop_Category.sql b/static/sql/306_tri_Shop_Category.sql new file mode 100644 index 00000000..b2a8f0ed --- /dev/null +++ b/static/sql/306_tri_Shop_Category.sql @@ -0,0 +1,57 @@ + +# Shop Category + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Category; +DROP TRIGGER IF EXISTS before_update_Shop_Category; + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Category +BEFORE INSERT ON Shop_Category +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_Shop_Category +BEFORE UPDATE ON Shop_Category +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Category_Audit ( + id_category, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_category, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_category, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed description + SELECT NEW.id_category, 'description', OLD.description, NEW.description, NEW.id_change_set + WHERE NOT OLD.description <=> NEW.description + UNION + # Changed active + SELECT NEW.id_category, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_category, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; diff --git a/static/sql/308_tri_Shop_Recurrence_Interval.sql b/static/sql/308_tri_Shop_Recurrence_Interval.sql new file mode 100644 index 00000000..32764a64 --- /dev/null +++ b/static/sql/308_tri_Shop_Recurrence_Interval.sql @@ -0,0 +1,56 @@ + +# Shop Recurrence Interval + +USE PARTS; + + +DROP TRIGGER IF EXISTS before_insert_Shop_Recurrence_Interval; +DROP TRIGGER IF EXISTS before_update_Shop_Recurrence_Interval; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Recurrence_Interval +BEFORE INSERT ON Shop_Recurrence_Interval +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Recurrence_Interval +BEFORE UPDATE ON Shop_Recurrence_Interval +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Recurrence_Interval_Audit ( + id_interval, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_interval, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_interval, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed name_plural + SELECT NEW.id_interval, 'name_plural', OLD.name_plural, NEW.name_plural, NEW.id_change_set + WHERE NOT OLD.name_plural <=> NEW.name_plural + UNION + # Changed name + SELECT NEW.id_interval, 'active', OLD.active, NEW.active, NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/310.0_tri_Shop_Region.sql b/static/sql/310.0_tri_Shop_Region.sql new file mode 100644 index 00000000..608be95e --- /dev/null +++ b/static/sql/310.0_tri_Shop_Region.sql @@ -0,0 +1,55 @@ + +# Shop Delivery Region + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Region; +DROP TRIGGER IF EXISTS before_update_Shop_Region; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Region +BEFORE INSERT ON Shop_Region +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Region +BEFORE UPDATE ON Shop_Region +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Region_Audit ( + id_region, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_region, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_region, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed active + SELECT NEW.id_region, 'active', CONVERT(OLD.active, CHAR), CONVERT(NEW.active, CHAR), NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + UNION + # Changed display_order + SELECT NEW.id_region, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; diff --git a/static/sql/310.2_tri_Shop_Region_Branch.sql b/static/sql/310.2_tri_Shop_Region_Branch.sql new file mode 100644 index 00000000..f81cfe72 --- /dev/null +++ b/static/sql/310.2_tri_Shop_Region_Branch.sql @@ -0,0 +1,53 @@ + +# Shop Region Branch + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Region_Branch; +DROP TRIGGER IF EXISTS before_update_Shop_Region_Branch; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Region_Branch +BEFORE INSERT ON Shop_Region_Branch +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Region_Branch +BEFORE UPDATE ON Shop_Region_Branch +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Region_Branch_Audit ( + id_branch, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed depth + SELECT NEW.id_branch, 'depth', CONVERT(OLD.depth, CHAR), CONVERT(NEW.depth, CHAR), NEW.id_change_set + WHERE NOT OLD.depth <=> NEW.depth + UNION + */ + # Changed active + SELECT NEW.id_branch, 'active', CONVERT(OLD.active, CHAR), CONVERT(NEW.active, CHAR), NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + UNION + # Changed display_order + SELECT NEW.id_branch, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; diff --git a/static/sql/310.4_tri_Shop_Currency.sql b/static/sql/310.4_tri_Shop_Currency.sql new file mode 100644 index 00000000..00d783d4 --- /dev/null +++ b/static/sql/310.4_tri_Shop_Currency.sql @@ -0,0 +1,67 @@ + +# Shop Currency + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Currency; +DROP TRIGGER IF EXISTS before_update_Shop_Currency; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Currency +BEFORE INSERT ON Shop_Currency +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Currency +BEFORE UPDATE ON Shop_Currency +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Currency_Audit ( + id_currency, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_currency, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_currency, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed symbol + SELECT NEW.id_currency, 'symbol', OLD.symbol, NEW.symbol, NEW.id_change_set + WHERE NOT OLD.symbol <=> NEW.symbol + UNION + # Changed ratio_2_GBP + SELECT NEW.id_currency, 'factor_from_GBP', OLD.factor_from_GBP, NEW.factor_from_GBP, NEW.id_change_set + WHERE NOT OLD.factor_from_GBP <=> NEW.factor_from_GBP + UNION + # Changed active + SELECT NEW.id_currency, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_currency, 'display_order', CONVERT(display_order, CHAR), CONVERT(display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/310.6_tri_Shop_Tax_Or_Surcharge.sql b/static/sql/310.6_tri_Shop_Tax_Or_Surcharge.sql new file mode 100644 index 00000000..cecf6e68 --- /dev/null +++ b/static/sql/310.6_tri_Shop_Tax_Or_Surcharge.sql @@ -0,0 +1,75 @@ + +# Shop Tax_Or_Surcharge + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Tax_Or_Surcharge; +DROP TRIGGER IF EXISTS before_update_Shop_Tax_Or_Surcharge; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Tax_Or_Surcharge +BEFORE INSERT ON Shop_Tax_Or_Surcharge +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_Shop_Tax_Or_Surcharge +BEFORE UPDATE ON Shop_Tax_Or_Surcharge +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Tax_Or_Surcharge_Audit ( + id_tax, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_tax, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_tax, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed fixed_fee + SELECT NEW.id_tax, 'fixed_fee', OLD.fixed_fee, NEW.fixed_fee, NEW.id_change_set + WHERE NOT OLD.fixed_fee <=> NEW.fixed_fee + UNION + # Changed multiplier + SELECT NEW.id_tax, 'multiplier', OLD.multiplier, NEW.multiplier, NEW.id_change_set + WHERE NOT OLD.multiplier <=> NEW.multiplier + UNION + # Changed apply_fixed_fee_before_multiplier + SELECT NEW.id_tax, 'apply_fixed_fee_before_multiplier', CONVERT(CONVERT(OLD.apply_fixed_fee_before_multiplier, SIGNED), CHAR), CONVERT(CONVERT(NEW.apply_fixed_fee_before_multiplier, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.apply_fixed_fee_before_multiplier <=> NEW.apply_fixed_fee_before_multiplier + UNION + # Changed quantity_min + SELECT NEW.id_tax, 'quantity_min', OLD.quantity_min, NEW.quantity_min, NEW.id_change_set + WHERE NOT OLD.quantity_min <=> NEW.quantity_min + UNION + # Changed quantity_max + SELECT NEW.id_tax, 'quantity_max', OLD.quantity_max, NEW.quantity_max, NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + UNION + # Changed display_order + SELECT NEW.id_tax, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + UNION + # Changed active + SELECT NEW.id_tax, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + ; +END // +DELIMITER ; + diff --git a/static/sql/310.8_tri_Shop_Product.sql b/static/sql/310.8_tri_Shop_Product.sql new file mode 100644 index 00000000..ec2b2d54 --- /dev/null +++ b/static/sql/310.8_tri_Shop_Product.sql @@ -0,0 +1,170 @@ + +# Shop Product + +USE PARTS; + + +DROP TRIGGER IF EXISTS before_insert_Shop_Product; +DROP TRIGGER IF EXISTS before_update_Shop_Product; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product +BEFORE INSERT ON Shop_Product +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product +BEFORE UPDATE ON Shop_Product +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + /* + IF NOT NEW.has_variations THEN + IF ISNULL(NEW.price_GBP_full) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have price or variations (with prices).'; + END IF; + IF ISNULL(NEW.price_GBP_min) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have minimum price or variations (with prices).'; + END IF; + IF ISNULL(NEW.latency_manuf) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have manufacturing latency or variations (with manufacturing latencies).'; + END IF; + IF ISNULL(NEW.quantity_min) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have minimum quantity or variations (with minimum quantities).'; + END IF; + IF ISNULL(NEW.quantity_max) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have maximum quantity or variations (with maximum quantities).'; + END IF; + IF ISNULL(NEW.quantity_step) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have increment of quantity or variations (with increments of quantities).'; + END IF; + IF ISNULL(NEW.quantity_stock) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have stock quantity or variations (with stock quantities).'; + END IF; + IF ISNULL(NEW.is_subscription) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have subscription status or variations (with subscription statuses).'; + END IF; + IF ISNULL(NEW.id_recurrence_interval) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have recurrence interval or variations (with recurrence intervals).'; + END IF; + IF ISNULL(NEW.count_recurrence_interval) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product must have recurrence interval count or variations (with recurrence interval counts).'; + END IF; + END IF; + */ + + INSERT INTO Shop_Product_Audit ( + id_product, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed name + SELECT NEW.id_product, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + /* + UNION + # Changed description + SELECT NEW.id_product, 'description', OLD.description, NEW.description, NEW.id_change_set + WHERE NOT OLD.description <=> NEW.description + UNION + # Changed price_GBP_full + SELECT NEW.id_product, 'price_GBP_full', CONVERT(OLD.price_GBP_full, CHAR), CONVERT(NEW.price_GBP_full, CHAR), NEW.id_change_set + WHERE NOT OLD.price_GBP_full <=> NEW.price_GBP_full + UNION + # Changed price_GBP_min + SELECT NEW.id_product, 'price_GBP_min', CONVERT(OLD.price_GBP_min, CHAR), CONVERT(NEW.price_GBP_min, CHAR), NEW.id_change_set + WHERE NOT OLD.price_GBP_min <=> NEW.price_GBP_min + UNION + # Changed has_variations + SELECT NEW.id_product, 'has_variations', CONVERT(CONVERT(NEW.has_variations, SIGNED), CHAR), CONVERT(CONVERT(NEW.has_variations, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.has_variations <=> NEW.has_variations + UNION + /* + # Changed discount + SELECT NEW.id_product, 'discount', CONVERT(OLD.discount, CHAR), CONVERT(NEW.discount, CHAR), NEW.id_change_set + WHERE NOT OLD.discount <=> NEW.discount + */ + UNION + # Changed id_category + SELECT NEW.id_product, 'id_category', CONVERT(OLD.id_category, CHAR), CONVERT(NEW.id_category, CHAR), NEW.id_change_set + WHERE NOT OLD.id_category <=> NEW.id_category + /* + UNION + # Changed latency_manuf + SELECT NEW.id_product, 'latency_manuf', CONVERT(OLD.latency_manuf, CHAR), CONVERT(NEW.latency_manuf, CHAR), NEW.id_change_set + WHERE NOT OLD.latency_manuf <=> NEW.latency_manuf + UNION + # Changed quantity_min + SELECT NEW.id_product, 'quantity_min', CONVERT(OLD.quantity_min, CHAR), CONVERT(NEW.quantity_min, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_min <=> NEW.quantity_min + UNION + # Changed quantity_max + SELECT NEW.id_product, 'quantity_max', CONVERT(OLD.quantity_max, CHAR), CONVERT(NEW.quantity_max, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + UNION + # Changed quantity_step + SELECT NEW.id_product, 'quantity_step', CONVERT(OLD.quantity_step, CHAR), CONVERT(NEW.quantity_step, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_step <=> NEW.quantity_step + UNION + # Changed quantity_stock + SELECT NEW.id_product, 'quantity_stock', CONVERT(OLD.quantity_stock, CHAR), CONVERT(NEW.quantity_stock, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_stock <=> NEW.quantity_stock + UNION + # Changed is_subscription + SELECT NEW.id_product, 'is_subscription', CONVERT(CONVERT(OLD.is_subscription, SIGNED), CHAR), CONVERT(CONVERT(NEW.is_subscription, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.is_subscription <=> NEW.is_subscription + UNION + # Changed id_recurrence_interval + SELECT NEW.id_product, 'id_recurrence_interval', CONVERT(OLD.id_recurrence_interval, CHAR), CONVERT(NEW.id_recurrence_interval, CHAR), NEW.id_change_set + WHERE NOT OLD.id_recurrence_interval <=> NEW.id_recurrence_interval + UNION + # Changed count_recurrence_interval + SELECT NEW.id_product, 'count_recurrence_interval', CONVERT(OLD.count_recurrence_interval, CHAR), CONVERT(NEW.count_recurrence_interval, CHAR), NEW.id_change_set + WHERE NOT OLD.count_recurrence_interval <=> NEW.count_recurrence_interval + UNION + # Changed id_access_level_required + SELECT NEW.id_product, 'id_access_level_required', CONVERT(OLD.id_access_level_required, CHAR), CONVERT(NEW.id_access_level_required, CHAR), NEW.id_change_set + WHERE NOT OLD.id_access_level_required <=> NEW.id_access_level_required + UNION + # Changed id_stripe_product + SELECT NEW.id_product, 'id_stripe_product', OLD.id_stripe_product, NEW.id_stripe_product, NEW.id_change_set + WHERE NOT OLD.id_stripe_product <=> NEW.id_stripe_product + /* + UNION + # Changed id_stripe_price + SELECT NEW.id_product, 'id_stripe_price', OLD.id_stripe_price, NEW.id_stripe_price, NEW.id_change_set + WHERE NOT OLD.id_stripe_price <=> NEW.id_stripe_price + */ + UNION + # Changed active + SELECT NEW.id_product, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_product, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; diff --git a/static/sql/312_tri_Shop_Variation_Type.sql b/static/sql/312_tri_Shop_Variation_Type.sql new file mode 100644 index 00000000..8a375991 --- /dev/null +++ b/static/sql/312_tri_Shop_Variation_Type.sql @@ -0,0 +1,60 @@ + +# Shop Variation Type + +USE PARTS; + + +DROP TRIGGER IF EXISTS before_insert_Shop_Variation_Type; +DROP TRIGGER IF EXISTS before_update_Shop_Variation_Type; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Variation_Type +BEFORE INSERT ON Shop_Variation_Type +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Variation_Type +BEFORE UPDATE ON Shop_Variation_Type +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Variation_Type_Audit ( + id_type, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_type, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_type, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed name_plural + SELECT NEW.id_type, 'name_plural', OLD.name_plural, NEW.name_plural, NEW.id_change_set + WHERE NOT OLD.name_plural <=> NEW.name_plural + UNION + # Changed active + SELECT NEW.id_type, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_type, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; diff --git a/static/sql/314_tri_Shop_Variation.sql b/static/sql/314_tri_Shop_Variation.sql new file mode 100644 index 00000000..197a7a8d --- /dev/null +++ b/static/sql/314_tri_Shop_Variation.sql @@ -0,0 +1,55 @@ + +# Shop Variation + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Variation; +DROP TRIGGER IF EXISTS before_update_Shop_Variation; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Variation +BEFORE INSERT ON Shop_Variation +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Variation +BEFORE UPDATE ON Shop_Variation +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Variation_Audit ( + id_variation, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_variation, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_variation, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed active + SELECT NEW.id_variation, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_variation, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; diff --git a/static/sql/317.1_tri_Shop_Product_Permutation.sql b/static/sql/317.1_tri_Shop_Product_Permutation.sql new file mode 100644 index 00000000..c89a46b1 --- /dev/null +++ b/static/sql/317.1_tri_Shop_Product_Permutation.sql @@ -0,0 +1,127 @@ + +# Shop Product Permutation + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Permutation; +DROP TRIGGER IF EXISTS before_update_Shop_Product_Permutation; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Permutation +BEFORE INSERT ON Shop_Product_Permutation +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Permutation +BEFORE UPDATE ON Shop_Product_Permutation +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Product_Permutation_Audit ( + id_permutation, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_product + SELECT NEW.id_permutation, 'id_product', OLD.id_product, NEW.id_product, NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_variation + SELECT NEW.id_permutation, 'id_variation', OLD.id_variation, NEW.id_variation, NEW.id_change_set + WHERE NOT OLD.id_variation <=> NEW.id_variation + UNION + # Changed name + SELECT NEW.id_permutation, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT (OLD.name <=> NEW.name) + UNION + */ + # Changed description + SELECT NEW.id_permutation, 'description', OLD.description, NEW.description, NEW.id_change_set + WHERE NOT (OLD.description <=> NEW.description) + UNION + # Changed cost_local_manufacturing + SELECT NEW.id_permutation, 'cost_local_manufacturing', CONVERT(OLD.cost_local_manufacturing, CHAR), CONVERT(NEW.cost_local_manufacturing, CHAR), NEW.id_change_set + WHERE NOT (OLD.cost_local_manufacturing <=> NEW.cost_local_manufacturing) + UNION + # Changed id_currency_cost_manufacturing + SELECT NEW.id_permutation, 'id_currency_cost_manufacturing', CONVERT(OLD.id_currency_cost_manufacturing, CHAR), CONVERT(NEW.id_currency_cost_manufacturing, CHAR), NEW.id_change_set + WHERE NOT (OLD.id_currency_cost_manufacturing <=> NEW.id_currency_cost_manufacturing) + UNION + # Changed profit_local_min + SELECT NEW.id_permutation, 'profit_local_min', CONVERT(OLD.profit_local_min, CHAR), CONVERT(NEW.profit_local_min, CHAR), NEW.id_change_set + WHERE NOT (OLD.profit_local_min <=> NEW.profit_local_min) + UNION + # Changed id_currency_profit_min + SELECT NEW.id_permutation, 'id_currency_profit_min', CONVERT(OLD.id_currency_profit_min, CHAR), CONVERT(NEW.id_currency_profit_min, CHAR), NEW.id_change_set + WHERE NOT (OLD.id_currency_profit_min <=> NEW.id_currency_profit_min) + UNION + /* + # Changed price_GBP_min + SELECT NEW.id_permutation, 'price_GBP_min', CONVERT(OLD.price_GBP_min, CHAR), CONVERT(NEW.price_GBP_min, CHAR), NEW.id_change_set + WHERE NOT (OLD.price_GBP_min <=> NEW.price_GBP_min) + UNION + */ + # Changed latency_manufacture + SELECT NEW.id_product, 'latency_manufacture', CONVERT(OLD.latency_manufacture, CHAR), CONVERT(NEW.latency_manufacture, CHAR), NEW.id_change_set + WHERE NOT OLD.latency_manufacture <=> NEW.latency_manufacture + UNION + # Changed quantity_min + SELECT NEW.id_product, 'quantity_min', CONVERT(OLD.quantity_min, CHAR), CONVERT(NEW.quantity_min, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_min <=> NEW.quantity_min + UNION + # Changed quantity_max + SELECT NEW.id_product, 'quantity_max', CONVERT(OLD.quantity_max, CHAR), CONVERT(NEW.quantity_max, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + UNION + # Changed quantity_step + SELECT NEW.id_product, 'quantity_step', CONVERT(OLD.quantity_step, CHAR), CONVERT(NEW.quantity_step, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_step <=> NEW.quantity_step + UNION + # Changed quantity_stock + SELECT NEW.id_product, 'quantity_stock', CONVERT(OLD.quantity_stock, CHAR), CONVERT(NEW.quantity_stock, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_stock <=> NEW.quantity_stock + UNION + # Changed is_subscription + SELECT NEW.id_product, 'is_subscription', CONVERT(CONVERT(OLD.is_subscription, SIGNED), CHAR), CONVERT(CONVERT(NEW.is_subscription, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.is_subscription <=> NEW.is_subscription + UNION + # Changed id_recurrence_interval + SELECT NEW.id_product, 'id_recurrence_interval', CONVERT(OLD.id_recurrence_interval, CHAR), CONVERT(NEW.id_recurrence_interval, CHAR), NEW.id_change_set + WHERE NOT OLD.id_recurrence_interval <=> NEW.id_recurrence_interval + UNION + # Changed count_recurrence_interval + SELECT NEW.id_product, 'count_recurrence_interval', CONVERT(OLD.count_recurrence_interval, CHAR), CONVERT(NEW.count_recurrence_interval, CHAR), NEW.id_change_set + WHERE NOT OLD.count_recurrence_interval <=> NEW.count_recurrence_interval + UNION + # Changed id_stripe_product + SELECT NEW.id_permutation, 'id_stripe_product', OLD.id_stripe_product, NEW.id_stripe_product, NEW.id_change_set + WHERE NOT (OLD.id_stripe_product <=> NEW.id_stripe_product) + UNION + # Changed active + SELECT NEW.id_permutation, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_permutation, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/317.3_tri_Shop_Product_Permutation_Variation_Link.sql b/static/sql/317.3_tri_Shop_Product_Permutation_Variation_Link.sql new file mode 100644 index 00000000..8be8a50d --- /dev/null +++ b/static/sql/317.3_tri_Shop_Product_Permutation_Variation_Link.sql @@ -0,0 +1,61 @@ + +# Shop Product Permutation Variation Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Permutation_Variation_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Product_Permutation_Variation_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Permutation_Variation_Link +BEFORE INSERT ON Shop_Product_Permutation_Variation_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Permutation_Variation_Link +BEFORE UPDATE ON Shop_Product_Permutation_Variation_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Product_Permutation_Variation_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_product + SELECT NEW.id_link, 'id_product', OLD.id_product, NEW.id_product, NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_variation + SELECT NEW.id_link, 'id_variation', OLD.id_variation, NEW.id_variation, NEW.id_change_set + WHERE NOT OLD.id_variation <=> NEW.id_variation + UNION + */ + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_link, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/317.5_tri_Shop_Product_Currency_Link.sql b/static/sql/317.5_tri_Shop_Product_Currency_Link.sql new file mode 100644 index 00000000..3cb026de --- /dev/null +++ b/static/sql/317.5_tri_Shop_Product_Currency_Link.sql @@ -0,0 +1,93 @@ + +# Shop Product Currency Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Currency_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Product_Currency_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Currency_Link +BEFORE INSERT ON Shop_Product_Currency_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; + /* + SET NEW.price_local = ( + SELECT PP.price_GBP_full * C.factor_from_GBP + FROM Shop_Product_Permutation PP + INNER JOIN Shop_Product P ON PP.id_product = P.id_product + INNER JOIN Shop_Currency C ON NEW.id_currency = C.id_currency + WHERE NEW.id_product = P.id_product + LIMIT 1 + ); + */ +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Currency_Link +BEFORE UPDATE ON Shop_Product_Currency_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + /* + SET NEW.price_local = ( + SELECT P.price_GBP_full * C.factor_from_GBP + FROM Shop_Product P + INNER JOIN Shop_Currency C ON NEW.id_currency = C.id_currency + WHERE NEW.id_product = P.id_product + LIMIT 1 + ); + */ + + INSERT INTO Shop_Product_Currency_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_product + SELECT NEW.id_link, 'id_product', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_currency + SELECT NEW.id_link, 'id_currency', CONVERT(OLD.id_currency, CHAR), CONVERT(NEW.id_currency, CHAR), NEW.id_change_set + WHERE NOT OLD.id_currency <=> NEW.id_currency + UNION + # Changed price_local + SELECT NEW.id_link, 'price_local', OLD.price_local, NEW.price_local, NEW.id_change_set + WHERE NOT OLD.price_local <=> NEW.price_local + UNION + */ + # Changed price_local_VAT_incl + SELECT NEW.id_link, 'price_local_VAT_incl', OLD.price_local_VAT_incl, NEW.price_local_VAT_incl, NEW.id_change_set + WHERE NOT OLD.price_local_VAT_incl <=> NEW.price_local_VAT_incl + UNION + # Changed price_local_VAT_excl + SELECT NEW.id_link, 'price_local_VAT_excl', OLD.price_local_VAT_excl, NEW.price_local_VAT_excl, NEW.id_change_set + WHERE NOT OLD.price_local_VAT_excl <=> NEW.price_local_VAT_excl + UNION + # Changed id_stripe_price + SELECT NEW.id_link, 'id_stripe_price', OLD.id_stripe_price, NEW.id_stripe_price, NEW.id_change_set + WHERE NOT OLD.id_stripe_price <=> NEW.id_stripe_price + UNION + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; diff --git a/static/sql/317.5_tri_Shop_Product_Currency_Region_Link.sql b/static/sql/317.5_tri_Shop_Product_Currency_Region_Link.sql new file mode 100644 index 00000000..e4e68667 --- /dev/null +++ b/static/sql/317.5_tri_Shop_Product_Currency_Region_Link.sql @@ -0,0 +1,93 @@ + +# Shop Product Currency Region Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Currency_Region_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Product_Currency_Region_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Currency_Region_Link +BEFORE INSERT ON Shop_Product_Currency_Region_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; + /* + SET NEW.price_local = ( + SELECT PP.price_GBP_full * C.factor_from_GBP + FROM Shop_Product_Permutation PP + INNER JOIN Shop_Product P ON PP.id_product = P.id_product + INNER JOIN Shop_Currency C ON NEW.id_currency = C.id_currency + WHERE NEW.id_product = P.id_product + LIMIT 1 + ); + */ +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Currency_Region_Link +BEFORE UPDATE ON Shop_Product_Currency_Region_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + /* + SET NEW.price_local = ( + SELECT P.price_GBP_full * C.factor_from_GBP + FROM Shop_Product P + INNER JOIN Shop_Currency C ON NEW.id_currency = C.id_currency + WHERE NEW.id_product = P.id_product + LIMIT 1 + ); + */ + + INSERT INTO Shop_Product_Currency_Region_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_product + SELECT NEW.id_link, 'id_product', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_currency + SELECT NEW.id_link, 'id_currency', CONVERT(OLD.id_currency, CHAR), CONVERT(NEW.id_currency, CHAR), NEW.id_change_set + WHERE NOT OLD.id_currency <=> NEW.id_currency + UNION + # Changed price_local + SELECT NEW.id_link, 'price_local', OLD.price_local, NEW.price_local, NEW.id_change_set + WHERE NOT OLD.price_local <=> NEW.price_local + UNION + */ + # Changed price_local_VAT_incl + SELECT NEW.id_link, 'price_local_VAT_incl', OLD.price_local_VAT_incl, NEW.price_local_VAT_incl, NEW.id_change_set + WHERE NOT OLD.price_local_VAT_incl <=> NEW.price_local_VAT_incl + UNION + # Changed price_local_VAT_excl + SELECT NEW.id_link, 'price_local_VAT_excl', OLD.price_local_VAT_excl, NEW.price_local_VAT_excl, NEW.id_change_set + WHERE NOT OLD.price_local_VAT_excl <=> NEW.price_local_VAT_excl + UNION + # Changed id_stripe_price + SELECT NEW.id_link, 'id_stripe_price', OLD.id_stripe_price, NEW.id_stripe_price, NEW.id_change_set + WHERE NOT OLD.id_stripe_price <=> NEW.id_stripe_price + UNION + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; diff --git a/static/sql/318_tri_Shop_Image_Type.sql b/static/sql/318_tri_Shop_Image_Type.sql new file mode 100644 index 00000000..07f6e50f --- /dev/null +++ b/static/sql/318_tri_Shop_Image_Type.sql @@ -0,0 +1,59 @@ + +# Shop Image Type + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Image_Type; +DROP TRIGGER IF EXISTS before_update_Shop_Image_Type; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Image_Type +BEFORE INSERT ON Shop_Image_Type +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Image_Type +BEFORE UPDATE ON Shop_Image_Type +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Image_Type_Audit ( + id_type, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_type, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_type, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed name_plural + SELECT NEW.id_type, 'name_plural', OLD.name_plural, NEW.name_plural, NEW.id_change_set + WHERE NOT OLD.name_plural <=> NEW.name_plural + UNION + # Changed active + SELECT NEW.id_type, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_type, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/320_tri_Shop_Image.sql b/static/sql/320_tri_Shop_Image.sql new file mode 100644 index 00000000..7a48f301 --- /dev/null +++ b/static/sql/320_tri_Shop_Image.sql @@ -0,0 +1,71 @@ + +# Shop Image + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Image; +DROP TRIGGER IF EXISTS before_update_Shop_Image; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Image +BEFORE INSERT ON Shop_Image +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Image +BEFORE UPDATE ON Shop_Image +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change set ID must be provided.'; + END IF; + IF ISNULL(NEW.id_product) AND ISNULL(NEW.id_permutation) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Image must NOT have ID for product AND product permutation.'; + END IF; + + INSERT INTO Shop_Image_Audit ( + id_image, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed id_type_image + SELECT NEW.id_image, 'id_type_image', CONVERT(OLD.id_type_image, CHAR), CONVERT(NEW.id_type_image, CHAR), NEW.id_change_set + WHERE NOT OLD.id_type_image <=> NEW.id_type_image + UNION + # Changed id_type_file + SELECT NEW.id_image, 'id_type_file', CONVERT(OLD.id_type_file, CHAR), CONVERT(NEW.id_type_file, CHAR), NEW.id_change_set + WHERE NOT OLD.id_type_file <=> NEW.id_type_file + UNION + # Changed id_product + SELECT NEW.id_image, 'id_product', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_permutation + SELECT NEW.id_image, 'id_permutation', CONVERT(OLD.id_permutation, CHAR), CONVERT(NEW.id_permutation, CHAR), NEW.id_change_set + WHERE NOT OLD.id_permutation <=> NEW.id_permutation + UNION + # Changed url + SELECT NEW.id_image, 'url', OLD.url, NEW.url, NEW.id_change_set + WHERE NOT OLD.url <=> NEW.url + UNION + # Changed active + SELECT NEW.id_image, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_image, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/322_tri_Shop_Delivery_Option.sql b/static/sql/322_tri_Shop_Delivery_Option.sql new file mode 100644 index 00000000..08865c26 --- /dev/null +++ b/static/sql/322_tri_Shop_Delivery_Option.sql @@ -0,0 +1,71 @@ + +# Shop Delivery Option Type + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Delivery_Option; +DROP TRIGGER IF EXISTS before_update_Shop_Delivery_Option; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Delivery_Option +BEFORE INSERT ON Shop_Delivery_Option +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Delivery_Option +BEFORE UPDATE ON Shop_Delivery_Option +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Delivery_Option_Audit ( + id_option, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_option, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_option, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed latency_delivery_min + SELECT NEW.id_option, 'latency_delivery_min', CONVERT(OLD.latency_delivery_min, CHAR), CONVERT(NEW.latency_delivery_min, CHAR), NEW.id_change_set + WHERE NOT OLD.latency_delivery_min <=> NEW.latency_delivery_min + UNION + # Changed latency_delivery_max + SELECT NEW.id_option, 'latency_delivery_max', CONVERT(OLD.latency_delivery_max, CHAR), CONVERT(NEW.latency_delivery_max, CHAR), NEW.id_change_set + WHERE NOT OLD.latency_delivery_max <=> NEW.latency_delivery_max + UNION + # Changed quantity_min + SELECT NEW.id_option, 'quantity_min', CONVERT(OLD.quantity_min, CHAR), CONVERT(NEW.quantity_min, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_min <=> NEW.quantity_min + UNION + # Changed quantity_max + SELECT NEW.id_option, 'quantity_max', CONVERT(OLD.quantity_max, CHAR), CONVERT(NEW.quantity_max, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + UNION + # Changed active + SELECT NEW.id_option, 'active', CONVERT(OLD.active, CHAR), CONVERT(NEW.active, CHAR), NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + UNION + # Changed display_order + SELECT NEW.id_option, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/324_tri_Shop_Product_Delivery_Option_Link.sql b/static/sql/324_tri_Shop_Product_Delivery_Option_Link.sql new file mode 100644 index 00000000..166e0206 --- /dev/null +++ b/static/sql/324_tri_Shop_Product_Delivery_Option_Link.sql @@ -0,0 +1,73 @@ + +# Shop Product Delivery Option Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Delivery_Option_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Product_Delivery_Option_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Delivery_Option_Link +BEFORE INSERT ON Shop_Product_Delivery_Option_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Delivery_Option_Link +BEFORE UPDATE ON Shop_Product_Delivery_Option_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Product_Delivery_Option_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_product + SELECT NEW.id_link, 'id_product', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_permutation + SELECT NEW.id_link, 'id_permutation', CONVERT(OLD.id_permutation, CHAR), CONVERT(NEW.id_permutation, CHAR), NEW.id_change_set + WHERE NOT OLD.id_permutation <=> NEW.id_permutation + UNION + # Changed id_option + SELECT NEW.id_link, 'id_option', CONVERT(OLD.id_option, CHAR), CONVERT(NEW.id_option, CHAR), NEW.id_change_set + WHERE NOT OLD.id_option <=> NEW.id_option + UNION + # Changed id_region + SELECT NEW.id_link, 'id_region', CONVERT(OLD.id_region, CHAR), CONVERT(NEW.id_region, CHAR), NEW.id_change_set + WHERE NOT OLD.id_region <=> NEW.id_region + UNION + */ + # Changed price_local + SELECT NEW.id_link, 'price_local', CONVERT(OLD.price_local, CHAR), CONVERT(NEW.price_local, CHAR), NEW.id_change_set + WHERE NOT OLD.price_local <=> NEW.price_local + UNION + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_link, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/330_tri_Shop_Discount.sql b/static/sql/330_tri_Shop_Discount.sql new file mode 100644 index 00000000..2e8fe2da --- /dev/null +++ b/static/sql/330_tri_Shop_Discount.sql @@ -0,0 +1,83 @@ + +# Shop Discount + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Discount; +DROP TRIGGER IF EXISTS before_update_Shop_Discount; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Discount +BEFORE INSERT ON Shop_Discount +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_Shop_Discount +BEFORE UPDATE ON Shop_Discount +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Discount_Audit ( + id_discount, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_discount, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_discount, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed multiplier + SELECT NEW.id_discount, 'multiplier', OLD.multiplier, NEW.multiplier, NEW.id_change_set + WHERE NOT OLD.multiplier <=> NEW.multiplier + UNION + # Changed subtractor + SELECT NEW.id_discount, 'subtractor', OLD.subtractor, NEW.subtractor, NEW.id_change_set + WHERE NOT OLD.subtractor <=> NEW.subtractor + UNION + # Changed apply_multiplier_first + SELECT NEW.id_discount, 'apply_multiplier_first', CONVERT(CONVERT(OLD.apply_multiplier_first, SIGNED), CHAR), CONVERT(CONVERT(NEW.apply_multiplier_first, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.apply_multiplier_first <=> NEW.apply_multiplier_first + UNION + # Changed quantity_min + SELECT NEW.id_discount, 'quantity_min', OLD.quantity_min, NEW.quantity_min, NEW.id_change_set + WHERE NOT OLD.quantity_min <=> NEW.quantity_min + UNION + # Changed quantity_max + SELECT NEW.id_discount, 'quantity_max', OLD.quantity_max, NEW.quantity_max, NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + UNION + # Changed date_start + SELECT NEW.id_discount, 'date_start', OLD.date_start, NEW.date_start, NEW.id_change_set + WHERE NOT OLD.date_start <=> NEW.date_start + UNION + # Changed date_end + SELECT NEW.id_discount, 'date_end', OLD.date_end, NEW.date_end, NEW.id_change_set + WHERE NOT OLD.date_end <=> NEW.date_end + UNION + # Changed display_order + SELECT NEW.id_discount, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + UNION + # Changed active + SELECT NEW.id_discount, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + ; +END // +DELIMITER ; + diff --git a/static/sql/332_tri_Shop_Discount_Region_Currency_Link.sql b/static/sql/332_tri_Shop_Discount_Region_Currency_Link.sql new file mode 100644 index 00000000..eb204a39 --- /dev/null +++ b/static/sql/332_tri_Shop_Discount_Region_Currency_Link.sql @@ -0,0 +1,57 @@ + +# Shop Discount Region Currency Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Discount_Region_Currency_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Discount_Region_Currency_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Discount_Region_Currency_Link +BEFORE INSERT ON Shop_Discount_Region_Currency_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Discount_Region_Currency_Link +BEFORE UPDATE ON Shop_Discount_Region_Currency_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Discount_Region_Currency_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_discount + SELECT NEW.id_link, 'id_discount', CONVERT(OLD.id_discount, CHAR), CONVERT(NEW.id_discount, CHAR), NEW.id_change_set + WHERE NOT OLD.id_discount <=> NEW.id_discount + UNION + # Changed id_region + SELECT NEW.id_link, 'id_region', CONVERT(OLD.id_region, CHAR), CONVERT(NEW.id_region, CHAR), NEW.id_change_set + WHERE NOT OLD.id_region <=> NEW.id_region + UNION + */ + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/353_tri_Shop_Permission_Group.sql b/static/sql/353_tri_Shop_Permission_Group.sql new file mode 100644 index 00000000..a11a617b --- /dev/null +++ b/static/sql/353_tri_Shop_Permission_Group.sql @@ -0,0 +1,59 @@ + +# Shop Permission Group + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Permission_Group; +DROP TRIGGER IF EXISTS before_update_Shop_Permission_Group; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Permission_Group +BEFORE INSERT ON Shop_Permission_Group +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Permission_Group +BEFORE UPDATE ON Shop_Permission_Group +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Permission_Group_Audit ( + id_group, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_group, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_group, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed active + SELECT NEW.id_group, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_group, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/355_tri_Shop_Permission.sql b/static/sql/355_tri_Shop_Permission.sql new file mode 100644 index 00000000..1f5ec558 --- /dev/null +++ b/static/sql/355_tri_Shop_Permission.sql @@ -0,0 +1,67 @@ + +# Shop Permission + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Permission; +DROP TRIGGER IF EXISTS before_update_Shop_Permission; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Permission +BEFORE INSERT ON Shop_Permission +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Permission +BEFORE UPDATE ON Shop_Permission +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Permission_Audit ( + id_permission, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_permission, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_permission, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed id_permission_group + SELECT NEW.id_permission, 'id_permission_group', CONVERT(OLD.id_permission_group, CHAR), CONVERT(NEW.id_permission_group, CHAR), NEW.id_change_set + WHERE NOT OLD.id_permission_group <=> NEW.id_permission_group + UNION + # Changed Id_access_level_required + SELECT NEW.id_permission, 'Id_access_level_required', CONVERT(OLD.Id_access_level_required, CHAR), CONVERT(NEW.Id_access_level_required, CHAR), NEW.id_change_set + WHERE NOT OLD.Id_access_level_required <=> NEW.Id_access_level_required + UNION + # Changed active + SELECT NEW.id_permission, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_permission, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/357_tri_Shop_Role.sql b/static/sql/357_tri_Shop_Role.sql new file mode 100644 index 00000000..1246abb2 --- /dev/null +++ b/static/sql/357_tri_Shop_Role.sql @@ -0,0 +1,59 @@ + +# Shop Role + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Role; +DROP TRIGGER IF EXISTS before_update_Shop_Role; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Role +BEFORE INSERT ON Shop_Role +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Role +BEFORE UPDATE ON Shop_Role +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Role_Audit ( + id_role, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_role, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_role, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed active + SELECT NEW.id_role, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_role, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; diff --git a/static/sql/359_tri_Shop_Role_Permission_Link.sql b/static/sql/359_tri_Shop_Role_Permission_Link.sql new file mode 100644 index 00000000..b8cff528 --- /dev/null +++ b/static/sql/359_tri_Shop_Role_Permission_Link.sql @@ -0,0 +1,61 @@ + +# Shop Role Permission Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Role_Permission_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Role_Permission_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Role_Permission_Link +BEFORE INSERT ON Shop_Role_Permission_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Role_Permission_Link +BEFORE UPDATE ON Shop_Role_Permission_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Role_Permission_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_role + SELECT NEW.id_link, 'id_role', CONVERT(OLD.id_role, CHAR), CONVERT(NEW.id_role, CHAR), NEW.id_change_set + WHERE NOT OLD.id_role <=> NEW.id_role + UNION + # Changed id_permission + SELECT NEW.id_link, 'id_permission', CONVERT(OLD.id_permission, CHAR), CONVERT(NEW.id_permission, CHAR), NEW.id_change_set + WHERE NOT OLD.id_permission <=> NEW.id_permission + UNION + */ + # Changed id_access_level + SELECT NEW.id_link, 'id_access_level', CONVERT(OLD.id_access_level, CHAR), CONVERT(NEW.id_access_level, CHAR), NEW.id_change_set + WHERE NOT OLD.id_access_level <=> NEW.id_access_level + UNION + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; diff --git a/static/sql/361_tri_Shop_User.sql b/static/sql/361_tri_Shop_User.sql new file mode 100644 index 00000000..025fb10a --- /dev/null +++ b/static/sql/361_tri_Shop_User.sql @@ -0,0 +1,55 @@ + +# Shop User + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User; +DROP TRIGGER IF EXISTS before_update_Shop_User; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User +BEFORE INSERT ON Shop_User +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_User +BEFORE UPDATE ON Shop_User +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_User_Audit ( + id_user, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed name + SELECT NEW.id_user, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT (OLD.name <=> NEW.name) + UNION + # Changed is_super_user + SELECT NEW.id_user, 'is_super_user', CONVERT(CONVERT(OLD.is_super_user, SIGNED), CHAR), CONVERT(CONVERT(NEW.is_super_user, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.is_super_user <=> NEW.is_super_user) + UNION + # Changed active + SELECT NEW.id_user, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/363_tri_Shop_User_Role_Link.sql b/static/sql/363_tri_Shop_User_Role_Link.sql new file mode 100644 index 00000000..7508a424 --- /dev/null +++ b/static/sql/363_tri_Shop_User_Role_Link.sql @@ -0,0 +1,47 @@ + +# Shop User Role Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User_Role_Link; +DROP TRIGGER IF EXISTS before_update_Shop_User_Role_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Role_Link +BEFORE INSERT ON Shop_User_Role_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_User_Role_Link +BEFORE UPDATE ON Shop_User_Role_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_User_Role_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/365_tri_Shop_Address.sql b/static/sql/365_tri_Shop_Address.sql new file mode 100644 index 00000000..581a52cc --- /dev/null +++ b/static/sql/365_tri_Shop_Address.sql @@ -0,0 +1,79 @@ + +# Shop Address + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Address; +DROP TRIGGER IF EXISTS before_update_Shop_Address; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Address +BEFORE INSERT ON Shop_Address +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Address +BEFORE UPDATE ON Shop_Address +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Address_Audit ( + id_address, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed region + SELECT NEW.id_address, 'id_region', OLD.id_region, NEW.id_region, NEW.id_change_set + WHERE NOT OLD.id_region <=> NEW.id_region + UNION + # Changed name_full + SELECT NEW.id_address, 'name_full', OLD.name_full, NEW.name_full, NEW.id_change_set + WHERE NOT OLD.name_full <=> NEW.name_full + UNION + # Changed phone_number + SELECT NEW.id_address, 'phone_number', OLD.phone_number, NEW.phone_number, NEW.id_change_set + WHERE NOT OLD.phone_number <=> NEW.phone_number + UNION + # Changed postcode + SELECT NEW.id_address, 'postcode', OLD.postcode, NEW.postcode, NEW.id_change_set + WHERE NOT OLD.postcode <=> NEW.postcode + UNION + # Changed address_line_1 + SELECT NEW.id_address, 'address_line_1', OLD.address_line_1, NEW.address_line_1, NEW.id_change_set + WHERE NOT OLD.address_line_1 <=> NEW.address_line_1 + UNION + # Changed address_line_2 + SELECT NEW.id_address, 'address_line_2', OLD.address_line_2, NEW.address_line_2, NEW.id_change_set + WHERE NOT OLD.address_line_2 <=> NEW.address_line_2 + UNION + # Changed city + SELECT NEW.id_address, 'city', OLD.city, NEW.city, NEW.id_change_set + WHERE NOT OLD.city <=> NEW.city + UNION + # Changed county + SELECT NEW.id_address, 'county', OLD.county, NEW.county, NEW.id_change_set + WHERE NOT OLD.county <=> NEW.county + UNION + # Changed active + SELECT NEW.id_address, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/367_tri_Shop_User_Basket.sql b/static/sql/367_tri_Shop_User_Basket.sql new file mode 100644 index 00000000..a0c61738 --- /dev/null +++ b/static/sql/367_tri_Shop_User_Basket.sql @@ -0,0 +1,59 @@ + +# Shop Product Variation Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User_Basket; +DROP TRIGGER IF EXISTS before_update_Shop_User_Basket; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Basket +BEFORE INSERT ON Shop_User_Basket +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_User_Basket +BEFORE UPDATE ON Shop_User_Basket +FOR EACH ROW +BEGIN + IF NEW.id_change_set_user <=> OLD.id_change_set_user THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_User_Basket_Audit ( + id_item, + name_field, + value_prev, + value_new, + id_change_set_user + ) + # Changed id_user + SELECT NEW.id_item, 'id_user', OLD.id_user, NEW.id_user, NEW.id_change_set_user + WHERE NOT OLD.id_user <=> NEW.id_user + UNION + # Changed id_product + SELECT NEW.id_item, 'id_product', OLD.id_product, NEW.id_product, NEW.id_change_set_user + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed quantity + SELECT NEW.id_item, 'quantity', CONVERT(OLD.quantity, CHAR), CONVERT(NEW.quantity, CHAR), NEW.id_change_set_user + WHERE NOT (OLD.quantity <=> NEW.quantity) + UNION + # Changed active + SELECT NEW.id_item, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set_user + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/369_tri_Shop_User_Order_Status.sql b/static/sql/369_tri_Shop_User_Order_Status.sql new file mode 100644 index 00000000..7aa18b14 --- /dev/null +++ b/static/sql/369_tri_Shop_User_Order_Status.sql @@ -0,0 +1,59 @@ + +# Shop User Order Type + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User_Order_Status; +DROP TRIGGER IF EXISTS before_update_Shop_User_Order_Status; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Order_Status +BEFORE INSERT ON Shop_User_Order_Status +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_User_Order_Status +BEFORE UPDATE ON Shop_User_Order_Status +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_User_Order_Status_Audit ( + id_Status, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_Status, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_Status, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed name_plural + SELECT NEW.id_Status, 'name_plural', OLD.name_plural, NEW.name_plural, NEW.id_change_set + WHERE NOT OLD.name_plural <=> NEW.name_plural + UNION + # Changed active + SELECT NEW.id_Status, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_Status, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/371_tri_Shop_User_Order.sql b/static/sql/371_tri_Shop_User_Order.sql new file mode 100644 index 00000000..7e18b982 --- /dev/null +++ b/static/sql/371_tri_Shop_User_Order.sql @@ -0,0 +1,67 @@ + +# Shop Product Variation Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User_Order; +DROP TRIGGER IF EXISTS before_update_Shop_User_Order; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Order +BEFORE INSERT ON Shop_User_Order +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_User_Order +BEFORE UPDATE ON Shop_User_Order +FOR EACH ROW +BEGIN + IF OLD.id_change_set_user <=> NEW.id_change_set_user THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + IF NOT (NEW.id_checkout_session <=> OLD.id_checkout_session) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Checkout session ID must not change.'; + END IF; + + INSERT INTO Shop_User_Order_Audit ( + id_order, + name_field, + value_prev, + value_new, + id_change_set_user + ) + # Changed id_user + SELECT NEW.id_order, 'id_user', OLD.id_user, NEW.id_user, NEW.id_change_set_user + WHERE NOT OLD.id_user <=> NEW.id_user + UNION + # Changed value_total + SELECT NEW.id_order, 'value_total', CONVERT(OLD.value_total, CHAR), CONVERT(NEW.value_total, CHAR), NEW.id_change_set_user + WHERE NOT (OLD.value_total <=> NEW.value_total) + UNION + # Changed id_order_status + SELECT NEW.id_order, 'id_order_status', CONVERT(OLD.id_order_status, CHAR), CONVERT(NEW.id_order_status, CHAR), NEW.id_change_set_user + WHERE NOT (OLD.id_order_status <=> NEW.id_order_status) + UNION + # Changed id_checkout_session + SELECT NEW.id_order, 'id_checkout_session', OLD.id_checkout_session, NEW.id_checkout_session, NEW.id_change_set_user + WHERE NOT (OLD.id_checkout_session <=> NEW.id_checkout_session) + UNION + # Changed active + SELECT NEW.id_order, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set_user + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/373_tri_Shop_User_Order_Product_Link.sql b/static/sql/373_tri_Shop_User_Order_Product_Link.sql new file mode 100644 index 00000000..cd6ba57f --- /dev/null +++ b/static/sql/373_tri_Shop_User_Order_Product_Link.sql @@ -0,0 +1,55 @@ + +# Shop User Order Product Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_User_Order_Product_Link; +DROP TRIGGER IF EXISTS before_update_Shop_User_Order_Product_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Order_Product_Link +BEFORE INSERT ON Shop_User_Order_Product_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_User_Order_Product_Link +BEFORE UPDATE ON Shop_User_Order_Product_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_User_Order_Product_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed id_product + SELECT NEW.id_link, 'active', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT (OLD.id_product <=> NEW.id_product) + UNION + # Changed quantity + SELECT NEW.id_link, 'quantity', CONVERT(OLD.quantity, CHAR), CONVERT(NEW.quantity, CHAR), NEW.id_change_set + WHERE NOT (OLD.quantity <=> NEW.quantity) + UNION + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/600_p_shop_save_product.sql b/static/sql/600_p_shop_save_product.sql new file mode 100644 index 00000000..b42ce519 --- /dev/null +++ b/static/sql/600_p_shop_save_product.sql @@ -0,0 +1,246 @@ + +USE PARTS; + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_save_product; + + +DELIMITER // +CREATE PROCEDURE p_save_product ( + IN a_guid VARCHAR(500), + +) +BEGIN + + -- Argument default values + IF a_ids_category IS NULL THEN + SET a_ids_category = ''; + END IF; + IF a_get_inactive_categories IS NULL THEN + SET a_get_inactive_categories = 0; + END IF; + /* + IF a_get_all_categories IS NULL THEN + SET a_get_all_categories = 0; + END IF; + */ + IF a_ids_product IS NULL THEN + SET a_ids_product = ''; + END IF; + IF a_get_inactive_products IS NULL THEN + SET a_get_inactive_products = 0; + END IF; + IF a_get_first_product_only IS NULL THEN + SET a_get_first_product_only = 1; + END IF; + IF a_get_all_products IS NULL THEN + SET a_get_all_products = 0; + END IF; + IF a_ids_image IS NULL THEN + SET a_ids_image = ''; + END IF; + IF a_get_inactive_images IS NULL THEN + SET a_get_inactive_images = 0; + END IF; + IF a_get_first_image_only IS NULL THEN + SET a_get_first_image_only = 1; + END IF; + IF a_get_all_images IS NULL THEN + SET a_get_all_images = 0; + END IF; + + + -- Temporary tables + CREATE TABLE tmp_Shop_Category ( + id_category INT NOT NULL, + active BIT NOT NULL, + display_order INT NOT NULL, + can_view BIT NOT NULL, + can_edit BIT NOT NULL, + can_admin BIT NOT NULL + ); + + CREATE TABLE tmp_Shop_Product ( + id_category INT NOT NULL, + id_product INT NOT NULL, + active BIT NOT NULL, + display_order INT NOT NULL, + can_view BIT NOT NULL, + can_edit BIT NOT NULL, + can_admin BIT NOT NULL + ); + + CREATE TABLE tmp_Shop_Variation ( + id_variation INT NOT NULL, + id_product INT NOT NULL, + display_order INT NOT NULL + ); + + CREATE TABLE tmp_Shop_Image ( + id_product INT NOT NULL, + id_image INT NOT NULL, + active BIT NOT NULL, + display_order INT NOT NULL + ); + + + -- Parse filters + SET a_ids_category = REPLACE(a_ids_category, ',', '|'); + SET a_ids_product = REPLACE(a_ids_product, ',', '|'); + SET v_has_filter_category = CASE WHEN a_ids_category = '' THEN 0 ELSE 1 END; + SET v_has_filter_product = CASE WHEN a_ids_product = '' THEN 0 ELSE 1 END; + + INSERT INTO tmp_Shop_Category ( + id_category, active, display_order + ) + SELECT C.id_category, C.active, C.display_order + FROM Shop_Category C + WHERE (NOT v_has_filter_category OR C.id_category LIKE '%' || a_ids_category || '%') + AND (a_get_inactive_categories OR C.active); + + INSERT INTO tmp_Shop_Product ( + id_category, id_product, active, display_order + ) + SELECT P.id_category, P.id_product, P.active, P.display_order + FROM Shop_Product P + INNER JOIN tmp_Shop_Category tC + ON P.id_category = tC.id_category + WHERE (a_get_all_products OR P.id_product LIKE '%' || a_ids_product || '%') + AND (a_get_inactive_products OR P.active); + + IF a_get_first_product_only THEN + DELETE FROM tmp_Shop_Product + WHERE display_order > (SELECT display_order FROM tmp_Shop_Product ORDER BY display_order ASC LIMIT 1); + END IF; + + IF v_has_filter_product THEN + DELETE FROM tmp_Shop_Category + WHERE id_category NOT IN (SELECT DISTINCT id_category FROM tmp_Shop_Product); + END IF; + + INSERT INTO tmp_Shop_Variation ( + id_variation, id_product # , display_order + ) + SELECT P.id_variation, P.id_product # , P.display_order + FROM Shop_Variation V + INNER JOIN tmp_Shop_Product tP + ON V.id_product = tP.id_product + WHERE V.active; + + INSERT INTO tmp_Shop_Image ( + id_product, id_image, active, display_order + ) + SELECT I.id_product, I.id_image, I.active, I.display_order + FROM Shop_Image I + INNER JOIN tmp_Shop_Product tP + ON I.id_image = tP.id_image + WHERE (a_get_all_images OR I.id_image LIKE '%' || a_ids_image || '%') + AND (a_get_inactive_images OR I.active); + + IF a_get_first_image_only THEN + DELETE FROM tmp_Shop_Image + WHERE display_order > (SELECT display_order FROM tmp_Shop_Image ORDER BY display_order ASC LIMIT 1); + END IF; + + IF v_has_filter_image THEN + DELETE FROM tmp_Shop_Product + WHERE id_product NOT IN (SELECT DISTINCT id_product FROM tmp_Shop_Image); + DELETE FROM tmp_Shop_Category + WHERE id_category NOT IN (SELECT DISTINCT id_category FROM tmp_Shop_Product); + END IF; + + + -- Permissions + IF EXISTS (SELECT * FROM tmp_Shop_Category LIMIT 1) THEN + SET v_guid_permission = UUID(); + SET v_id_user = CURRENT_USER(); + SET v_id_permission_product = (SELECT id_permission FROM Shop_Permission WHERE code = 'STORE_PRODUCT' LIMIT 1); + SET v_ids_product_permission = (SELECT GROUP_CONCAT(item SEPARATOR '|') FROM tmp_Shop_Product); + + CALL p_shop_user_eval(v_guid_permission, v_id_user, v_id_permission_product, v_ids_product_permission); + + UPDATE tmp_Shop_Product tP + INNER JOIN Shop_User_Eval_Temp TP + ON tP.id_product = TP.id_product + AND TP.GUID = v_guid_permission + SET tP.can_view = TP.can_view, + tP.can_edit = TP.can_edit, + tP.can_admin = TP.can_admin; + + CALL p_shop_user_eval_clear_temp(v_guid_permission); + END IF; + + + -- Returns + SET v_now = NOW(); + + # Categories + SELECT ( + tC.id_category, + C.name, + C.description, + tC.can_view, + tC.can_edit, + tC.can_admin + ) + FROM tmp_Shop_Category tC + INNER JOIN Shop_Category C + ON tC.id_category = C.id_category + ; + + # Products + SELECT + tP.id_product, + P.name, + P.price, + P.description, + C.id_category, + P.lead_time, + P.id_stripe_product, + P.id_stripe_price, + P.is_subscription, + RI.name AS name_recurrence_interval, + RI.name_plural AS name_plural_recurrence_interval, + P.count_recurrence_interval, + tP.can_view, + tP.can_edit, + tP.can_admin + FROM tmp_Shop_Product tP + INNER JOIN Shop_Product P + ON tP.id_product = P.id_product + INNER JOIN Shop_Recurrence_Interval RI + ON P.id_recurrence_interval = RI.id_interval + ; + + # Variations + SELECT + PVL.id_variation, + tV.id_product, + V.code, + V.name, + PVL.display_order + FROM tmp_Shop_Product tV + INNER JOIN Shop_Product_Variation_Link PVL + ON tV.id_product = PVL.id_product + INNER JOIN Shop_Variation V + ON PVL.id_variation = V.id_variation + WHERE V.active + AND PVL.active + ; + + # Images + SELECT + tI.id_image, + tI.id_product, + I.url, + PIL.display_order + FROM tmp_Shop_Image tI + INNER JOIN Shop_Product_Image_Link PIL + ON tI.id_product = PIL.id_product + WHERE I.active + AND PIL.active + ; +END // +DELIMITER ; + diff --git a/static/sql/600_p_shop_user_eval.sql b/static/sql/600_p_shop_user_eval.sql new file mode 100644 index 00000000..3959accc --- /dev/null +++ b/static/sql/600_p_shop_user_eval.sql @@ -0,0 +1,537 @@ + +USE PARTS; + + +/* + +CALL p_shop_user_eval ( + UUID(), # a_guid + '', # a_id_user + 0, # a_get_inactive_users + '1', # a_ids_permission + '', # a_ids_access_level + '1' # a_ids_product +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_user_eval; + +DELIMITER // +CREATE PROCEDURE p_shop_user_eval ( + IN a_guid VARCHAR(36), + IN a_id_user VARCHAR(200), + IN a_get_inactive_users BIT, + IN a_ids_permission VARCHAR(500), + IN a_ids_access_level VARCHAR(100), + IN a_ids_permutation VARCHAR(4000) +) +BEGIN + -- Variable declaration + DECLARE v_has_filter_permission BIT; + DECLARE v_has_filter_user BIT; + DECLARE v_has_filter_access_level BIT; + DECLARE v_has_filter_permutation BIT; + DECLARE v_id_permission_product INT; + DECLARE v_id_permission INT; + -- DECLARE v_ids_product VARCHAR(500); + DECLARE v_id_access_level_view INT; + # DECLARE v_id_access_level_product_required INT; + DECLARE v_priority_access_level_view INT; + DECLARE v_priority_access_level_edit INT; + DECLARE v_priority_access_level_admin INT; + DECLARE v_id_access_level INT; + DECLARE v_priority_access_level INT; + DECLARE v_now DATETIME; + DECLARE v_ids_row_delete VARCHAR(500); + DECLARE v_code_error_data VARCHAR(200); + DECLARE v_id_error_data INT; + DECLARE v_code_error_permission VARCHAR(200); + + SET v_id_error_data = 1; + SET v_code_error_data := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = v_id_error_data); + + SET v_code_error_permission := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 2); + + -- Clear previous proc results + # DROP TABLE IF EXISTS tmp_User_Role_Link; + # DROP TEMPORARY TABLE IF EXISTS tmp_User_Role_Link; + DROP TABLE IF EXISTS tmp_Shop_Product_p_Shop_User_Eval; + # DROP TABLE IF EXISTS Shop_User_Eval_Temp; + + + -- Parse arguments + get default values + /* + IF a_guid IS NULL THEN + SET a_guid = UUID(); + END IF; + */ + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + IF a_get_inactive_users IS NULL THEN + SET a_get_inactive_users = 0; + END IF; + /* + IF a_get_user_permissions IS NULL THEN + SET a_get_user_permissions = 0; + END IF; + */ + IF a_ids_permission IS NULL THEN + SET a_ids_permission = ''; + ELSE + SET a_ids_permission = TRIM(a_ids_permission); + END IF; + IF a_ids_access_level IS NULL THEN + SET a_ids_access_level = ''; + ELSE + SET a_ids_access_level = TRIM(a_ids_access_level); + END IF; + IF a_ids_permutation IS NULL THEN + SET a_ids_permutation = ''; + ELSE + SET a_ids_permutation = TRIM(a_ids_permutation); + END IF; + + -- Permanent Table + CREATE TABLE IF NOT EXISTS Shop_User_Eval_Temp ( + id_row INT PRIMARY KEY AUTO_INCREMENT NOT NULL, + guid VARCHAR(36) NOT NULL, + id_user VARCHAR(200), + id_permission_required INT NOT NULL, + CONSTRAINT FK_Shop_User_Eval_Temp_id_permission_required + FOREIGN KEY (id_permission_required) + REFERENCES Shop_Permission (id_permission), + /* + id_access_level_required INT NOT NULL, + CONSTRAINT FK_Shop_User_Eval_Temp_id_access_level_required + FOREIGN KEY (id_access_level_required) + REFERENCES Shop_Access_Level (id_access_level), + */ + priority_access_level_required INT NOT NULL, + /* + CONSTRAINT FK_Shop_User_Eval_Temp_priority_access_level_required + FOREIGN KEY (priority_access_level_required) + REFERENCES Shop_Access_Level (priority), + */ + id_product INT NULL, + CONSTRAINT FK_Shop_User_Eval_Temp_id_product + FOREIGN KEY (id_product) + REFERENCES parts.Shop_Product (id_product), + id_permutation INT NULL, + CONSTRAINT FK_Shop_User_Eval_Temp_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES parts.Shop_Product_Permutation (id_permutation), + is_super_user BIT NULL, + priority_access_level_user INT NULL, + /* + CONSTRAINT FK_Shop_User_Eval_Temp_priority_access_level_minimum + FOREIGN KEY (priority_access_level_minimum) + REFERENCES Shop_Access_Level (priority) + */ + can_view BIT, + can_edit BIT, + can_admin BIT -- DEFAULT 0 + ); + + CREATE TABLE IF NOT EXISTS tmp_Shop_Product_p_Shop_User_Eval ( + id_row INT PRIMARY KEY AUTO_INCREMENT NOT NULL, + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_p_Shop_User_Eval_id_product FOREIGN KEY (id_product) + REFERENCES parts.Shop_Product (id_product), + id_permutation INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_p_Shop_User_Eval_id_permutation FOREIGN KEY (id_permutation) + REFERENCES parts.Shop_Product_Permutation (id_permutation), + id_access_level_required INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_p_Shop_User_Eval_id_access_level_required FOREIGN KEY (id_access_level_required) + REFERENCES Shop_Access_Level (id_access_level), + guid VARCHAR(36) NOT NULL, + rank_permutation INT NOT NULL + ); + + CREATE TABLE IF NOT EXISTS tmp_Msg_Error ( + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + guid VARCHAR(36) NOT NULL, + id_type INT NOT NULL, + CONSTRAINT FK_tmp_Msg_Error_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Msg_Error_Type (id_type), + code VARCHAR(50), + msg VARCHAR(4000) NOT NULL + ); + + # select * from Shop_Msg_Error_Type; + + -- Parse filters + IF a_guid IS NULL OR EXISTS (SELECT * FROM Shop_User_Eval_Temp WHERE a_guid = guid) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + a_guid, + v_code_error_data, + 'Invalid guid argument.' + ) + ; + END IF; + SET v_has_filter_user = CASE WHEN a_id_user = '' THEN 0 ELSE 1 END; + SET a_ids_permission = REPLACE(a_ids_permission, '|', ','); + SET v_has_filter_permission = CASE WHEN a_ids_permission = '' THEN 0 ELSE 1 END; + SET a_ids_access_level = REPLACE(a_ids_access_level, '|', ','); + SET v_has_filter_access_level = CASE WHEN a_ids_access_level = '' THEN 0 ELSE 1 END; + SET a_ids_permutation = REPLACE(a_ids_permutation, '|', ','); + SET v_has_filter_permutation = CASE WHEN a_ids_permutation = '' THEN 0 ELSE 1 END; + SET v_id_access_level_view = (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'VIEW' LIMIT 1); + SET v_priority_access_level_view = (SELECT priority FROM Shop_Access_Level WHERE id_access_level = v_id_access_level_view); + SET v_priority_access_level_edit = (SELECT priority FROM Shop_Access_Level WHERE code = 'EDIT' LIMIT 1); + SET v_priority_access_level_admin = (SELECT priority FROM Shop_Access_Level WHERE code = 'ADMIN' LIMIT 1); + + /* + select v_priority_access_level_view, + v_priority_access_level_edit, + v_priority_access_level_admin + ; + */ + + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE GUID = a_guid) THEN + IF v_has_filter_access_level THEN + CALL p_split(a_ids_access_level, ','); + SET v_id_access_level := ( + SELECT AL.id_access_level + FROM Split_Temp ST + INNER JOIN Shop_Access_Level AL + ON CONVERT(ST.substring, DECIMAL(10,0)) = AL.id_access_level + AND AL.active + ORDER BY AL.priority ASC + LIMIT 1 + ); + DROP TABLE Split_Temp; + IF 0 = v_id_access_level OR v_id_access_level <=> NULL THEN + # SET v_has_filter_access_level = 0; + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + a_guid, + v_code_error_data, + 'Access level ID not found.' + ) + ; + END IF; + /* + END IF; + IF NOT v_has_filter_access_level THEN + */ + ELSE + SET v_id_access_level = v_id_access_level_view; + END IF; + END IF; + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE GUID = a_guid) THEN + IF v_has_filter_permutation THEN + INSERT INTO tmp_Shop_Product_p_Shop_User_Eval ( + id_product, + id_permutation, + id_access_level_required, + guid, + rank_permutation + ) + SELECT + PP.id_product, + PP.id_permutation, + PP.id_access_level_required, + a_guid, + RANK() OVER (ORDER BY PP.id_product, PP.id_permutation, AL.priority) AS rank_permutation + FROM Shop_Product_Permutation PP + INNER JOIN Shop_Access_Level AL + ON PP.id_access_level_required = AL.id_access_level + AND AL.active + WHERE FIND_IN_SET(PP.id_permutation, a_ids_permutation) > 0 + # AND P.active # not worried as we want users to be able to see their order history + ; + /* + DELETE FROM tmp_Shop_Product_p_Shop_User_Eval + WHERE rank_permutation > 1 + ; + */ + SET v_has_filter_permutation = EXISTS (SELECT * FROM tmp_Shop_Product_p_Shop_User_Eval WHERE a_guid = guid); + END IF; + + IF v_has_filter_permission THEN + # Invalid permission IDs + IF EXISTS (SELECT id_permission FROM Shop_Permission WHERE FIND_IN_SET(id_permission, a_ids_permission) > 0 AND NOT active) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + a_guid, + v_code_error_data, + CONCAT('The following permissions are no longer active: ', (SELECT GROUP_CONCAT(name SEPARATOR ', ') FROM Shop_Permission WHERE FIND_IN_SET(id_permission, a_ids_permission) > 0 AND NOT active)) + ) + ; + END IF; + END IF; + END IF; + + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE GUID = a_guid) THEN + IF v_has_filter_user THEN + SET a_id_user := (SELECT id_user FROM Shop_User WHERE id_user LIKE a_id_user AND active); + SET v_has_filter_user = NOT (a_id_user <=> NULL); + IF NOT v_has_filter_user THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + a_guid, + v_code_error_data, + 'User ID not found.' + ) + ; + END IF; + END IF; + END IF; + + -- Get users + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE GUID = a_guid) THEN + INSERT INTO Shop_User_Eval_Temp ( + guid, + id_user, + id_permission_required, + priority_access_level_required + /* + priority_access_level_user, + is_super_user, + can_view, + can_edit, + can_admin + */ + ) + SELECT a_guid, + a_id_user, + P.id_permission, + AL.priority + FROM parts.Shop_Permission P + INNER JOIN Shop_Access_Level AL + ON P.id_access_level_required = AL.id_access_level + AND AL.active + WHERE FIND_IN_SET(P.id_permission, a_ids_permission) > 0 + ; + + IF v_has_filter_permutation THEN + SET v_ids_row_delete := (SELECT GROUP_CONCAT(id_row SEPARATOR ',') FROM Shop_User_Eval_Temp WHERE a_guid = guid); + + INSERT INTO Shop_User_Eval_Temp ( + guid, + id_user, + id_permission_required, + id_product, + id_permutation, + priority_access_level_required + ) + SELECT UE_T.guid, + UE_T.id_user, + UE_T.id_permission_required, + t_P.id_product, + t_P.id_permutation, + CASE WHEN UE_T.priority_access_level_required < AL.priority THEN UE_T.priority_access_level_required ELSE AL.priority END -- UE_T.priority_access_level_required + FROM tmp_Shop_Product_p_Shop_User_Eval t_P + INNER JOIN Shop_Access_Level AL + ON t_P.id_access_leveL_required = AL.id_access_level + AND AL.active + CROSS JOIN Shop_User_Eval_Temp UE_T + ON a_id_user = UE_T.id_user + WHERE a_guid = t_P.guid + ; + + DELETE FROM Shop_User_Eval_Temp + WHERE FIND_IN_SET(id_row, v_ids_row_delete) > 0 + ; + END IF; + + /* + INSERT INTO Shop_User_Eval_Temp ( + guid, + id_user, + id_permission_required, + # id_access_level_required, + priority_access_level_required, + priority_access_level_user, + is_super_user + /* + can_view, + can_edit, + can_admin + * + ) + SELECT a_guid, + U.id_user, + P.id_permission, + AL.priority, + /* + v_id_permission, + v_id_access_level, + * + MIN(AL.priority), + U.is_super_user + /* + CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN priority_access_level_minimum <= v_priority_access_level_view THEN 1 ELSE 0 END END, + CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN priority_access_level_minimum <= v_priority_access_level_edit THEN 1 ELSE 0 END END, + CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN priority_access_level_minimum <= v_priority_access_level_admin THEN 1 ELSE 0 END END + * + FROM parts.Shop_User U + INNER JOIN Shop_User_Role_Link URL + ON U.id_user = URL.id_user + AND URL.active + INNER JOIN Shop_Role_Permission_Link RPL + ON URL.id_role = RPL.id_role + AND RPL.active + INNER JOIN Shop_Permission P + ON RPL.id_permission = P.id_permission + AND P.active + INNER JOIN Shop_Access_Level AL + ON RPL.id_access_level = AL.id_access_level + AND AL.active + WHERE U.id_user = a_id_user + AND (a_get_inactive_users OR U.active) + AND FIND_IN_SET(P.id_permission, a_ids_permission) > 0 + # AND v_id_permission = P.id_permission + # AND v_id_access_level = AL.id_access_leveld + GROUP BY U.id_user, P.id_permission # , is_super_user + ; + */ + + IF v_has_filter_user THEN + UPDATE Shop_User_Eval_Temp UE_T + INNER JOIN Shop_User U + ON UE_T.id_user = U.id_user + AND U.active + INNER JOIN Shop_User_Role_Link URL + ON U.id_user = URL.id_user + AND URL.active + INNER JOIN Shop_Role_Permission_Link RPL + ON URL.id_role = RPL.id_role + AND RPL.active + INNER JOIN Shop_Access_Level AL + ON RPL.id_access_level = AL.id_access_level + AND AL.active + SET UE_T.priority_access_level_user = AL.priority, + UE_T.is_super_user = U.is_super_user, + UE_T.can_view = CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN ISNULL(AL.priority) THEN 1 ELSE CASE WHEN AL.priority <= v_priority_access_level_view AND AL.priority <= UE_T.priority_access_level_required THEN 1 ELSE 0 END END END, + UE_T.can_edit = CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN NOT ISNULL(AL.priority) AND AL.priority <= v_priority_access_level_edit AND AL.priority <= UE_T.priority_access_level_required THEN 1 ELSE 0 END END, + UE_T.can_admin = CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN NOT ISNULL(AL.priority) AND AL.priority <= v_priority_access_level_admin AND AL.priority <= UE_T.priority_access_level_required THEN 1 ELSE 0 END END + WHERE UE_T.guid = a_guid + AND UE_T.id_user = a_id_user + AND RPL.id_permission = UE_T.id_permission_required + # GROUP BY UE_T.id_user + ; + ELSE + UPDATE Shop_User_Eval_Temp UE_T + SET UE_T.priority_access_level_user = v_priority_access_level_view, + UE_T.is_super_user = 0, + UE_T.can_view = (v_priority_access_level_view <= UE_T.priority_access_level_required), + UE_T.can_edit = 0, + UE_T.can_admin = 0 + WHERE UE_T.guid = a_guid + AND UE_T.id_user = a_id_user + # GROUP BY UE_T.id_user + ; + END IF; + END IF; + + -- Clean up + DROP TABLE IF EXISTS tmp_Shop_Product_p_Shop_User_Eval; + # DROP TEMPORARY TABLE IF EXISTS tmp_User_Role_Link; + # DROP TABLE IF EXISTS tmp_Msg_Error; +END // +DELIMITER ; + + +-- DROP TABLE IF EXISTS Shop_User_Eval_Temp; + + +/* +CALL p_shop_user_eval ( + '56c9dfc1-e22f-11ee-aab4-b42e9986184a', # a_guid + '', # a_id_user # 'auth0|6582b95c895d09a70ba10fef', + false, # a_get_inactive_users + 2, # a_ids_permission + 1, # a_ids_access_level + -- null, # a_ids_product + '1,2,3' # a_ids_permutation +); + + +SELECT * +FROM Shop_User_Eval_Temp +; + +DROP TABLE Shop_User_Eval_Temp; + + +SELECT * +FROM Shop_Permission +; + +SELECT * +FROM Shop_Access_Level +; + +SELECT * +FROM Shop_Product +; + +SELECT * +FROM Shop_Product_Permutation +; + + +*/ + +/* +SELECT 'NOODS' AS guid, + U.id_user AS id_user, + P.id_permission AS id_permission_required, + AL.id_access_level AS id_access_level_required, + /* + v_id_permission, + v_id_access_level, + * + AL.priority, # MIN(AL.priority), + U.is_super_user + /* + CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN priority_access_level_minimum <= v_priority_access_level_view THEN 1 ELSE 0 END END, + CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN priority_access_level_minimum <= v_priority_access_level_edit THEN 1 ELSE 0 END END, + CASE WHEN U.is_super_user THEN 1 ELSE CASE WHEN priority_access_level_minimum <= v_priority_access_level_admin THEN 1 ELSE 0 END END + * +FROM parts.Shop_User U +INNER JOIN Shop_User_Role_Link URL + ON U.id_user = URL.id_user + AND URL.active +INNER JOIN Shop_Role_Permission_Link RPL + ON URL.id_role = RPL.id_role + AND RPL.active +INNER JOIN Shop_Permission P + ON RPL.id_permission = P.id_permission + AND P.active +inner JOIN Shop_Access_Level AL + # ON P.id_access_level_required = AL.id_access_level + ON RPL.id_access_level = AL.id_access_level + AND AL.active +WHERE U.id_user = 'auth0|6582b95c895d09a70ba10fef' + AND U.active + AND FIND_IN_SET(P.id_permission, '1,2') > 0 + # AND v_id_access_level = AL.id_access_leveld +# GROUP BY U.id_user, P.id_permission, AL.id_access_level # , is_super_user + +*/ diff --git a/static/sql/700_p_shop_get_many_product.sql b/static/sql/700_p_shop_get_many_product.sql new file mode 100644 index 00000000..e0ca4462 --- /dev/null +++ b/static/sql/700_p_shop_get_many_product.sql @@ -0,0 +1,1088 @@ + +USE PARTS; + +/* + +CALL p_shop_get_many_product ( + '', # a_id_user + 1, # a_get_all_category + '', # a_ids_category + 0, # a_get_inactive_category + 1, # a_get_all_product + '', # a_ids_product + 0, # a_get_inactive_product + 0, # a_get_first_product_only + 1, # a_get_all_product_permutation + '', # a_ids_permutation + 0, # a_get_inactive_permutation + 0, # a_get_all_image + '', # a_ids_image + 0, # a_get_inactive_image + 1, # a_get_first_image_only + 1, # a_get_all_delivery_region + '', # a_ids_delivery_region + 0, # a_get_inactive_delivery_region + 1, # a_get_all_currency + '', # a_ids_currency + 0, # a_get_inactive_currency + 1, # a_get_all_discount + '', # a_ids_discount + 0 # a_get_inactive_discount +); + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_many_product; + + +DELIMITER // +CREATE PROCEDURE p_shop_get_many_product ( + IN a_id_user VARCHAR(200), + IN a_get_all_category BIT, + IN a_ids_category VARCHAR(500), + IN a_get_inactive_category BIT, + IN a_get_all_product BIT, + IN a_ids_product VARCHAR(500), + IN a_get_inactive_product BIT, + IN a_get_first_product_only BIT, + IN a_get_all_product_permutation BIT, + IN a_ids_permutation VARCHAR(4000), + IN a_get_inactive_permutation BIT, + IN a_get_all_image BIT, + IN a_ids_image VARCHAR(4000), + IN a_get_inactive_image BIT, + IN a_get_first_image_only BIT, + IN a_get_all_delivery_region BIT, + IN a_ids_delivery_region VARCHAR(4000), + IN a_get_inactive_delivery_region BIT, + IN a_get_all_currency BIT, + IN a_ids_currency VARCHAR(4000), + IN a_get_inactive_currency BIT, + IN a_get_all_discount BIT, + IN a_ids_discount VARCHAR(4000), + IN a_get_inactive_discount BIT +) +BEGIN + -- Argument redeclaration + -- Variable declaration + DECLARE v_has_filter_category BIT; + DECLARE v_has_filter_product BIT; + DECLARE v_has_filter_permutation BIT; + DECLARE v_has_filter_image BIT; + DECLARE v_has_filter_delivery_region BIT; + DECLARE v_has_filter_currency BIT; + DECLARE v_has_filter_discount BIT; + DECLARE v_guid VARCHAR(36); + # DECLARE v_id_user VARCHAR(100); + DECLARE v_ids_permutation_unavailable VARCHAR(4000); + DECLARE v_id_permission_product INT; + DECLARE v_ids_product_permission VARCHAR(4000); + DECLARE v_ids_permutation_permission VARCHAR(4000); + DECLARE v_id_access_level_view INT; + DECLARE v_now DATETIME; + DECLARE v_id_minimum INT; + + SET v_guid := UUID(); + SET v_id_access_level_view := (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'VIEW'); + + + -- Argument validation + default values + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + IF a_get_all_category IS NULL THEN + SET a_get_all_category = 0; + END IF; + IF a_ids_category IS NULL THEN + SET a_ids_category = ''; + ELSE + SET a_ids_category = REPLACE(TRIM(a_ids_category), '|', ','); + END IF; + IF a_get_inactive_category IS NULL THEN + SET a_get_inactive_category = 0; + END IF; + IF a_ids_product IS NULL THEN + SET a_ids_product = ''; + ELSE + SET a_ids_product = REPLACE(TRIM(a_ids_product), '|', ','); + END IF; + IF a_get_inactive_product IS NULL THEN + SET a_get_inactive_product = 0; + END IF; + IF a_get_first_product_only IS NULL THEN + SET a_get_first_product_only = 1; + END IF; + IF a_get_all_product IS NULL THEN + SET a_get_all_product = 0; + END IF; + IF a_ids_permutation IS NULL THEN + SET a_ids_permutation = ''; + ELSE + SET a_ids_permutation = REPLACE(TRIM(a_ids_permutation), '|', ','); + END IF; + IF a_get_inactive_permutation IS NULL THEN + SET a_get_inactive_permutation = 0; + END IF; + IF a_get_all_image IS NULL THEN + SET a_get_all_image = 1; + END IF; + IF a_ids_image IS NULL THEN + SET a_ids_image = ''; + ELSE + SET a_ids_image = REPLACE(TRIM(a_ids_image), '|', ','); + END IF; + IF a_get_inactive_image IS NULL THEN + SET a_get_inactive_image = 0; + END IF; + IF a_get_first_image_only IS NULL THEN + SET a_get_first_image_only = 0; + END IF; + IF a_get_inactive_image IS NULL THEN + SET a_get_inactive_image = 0; + END IF; + IF a_get_all_delivery_region IS NULL THEN + SET a_get_all_delivery_region = 1; + END IF; + IF a_ids_delivery_region IS NULL THEN + SET a_ids_delivery_region = ''; + ELSE + SET a_ids_delivery_region = REPLACE(TRIM(a_ids_delivery_region), '|', ','); + END IF; + IF a_get_inactive_delivery_region IS NULL THEN + SET a_get_inactive_delivery_region = 0; + END IF; + IF a_get_all_currency IS NULL THEN + SET a_get_all_currency = 1; + END IF; + IF a_ids_currency IS NULL THEN + SET a_ids_currency = ''; + ELSE + SET a_ids_currency = REPLACE(TRIM(a_ids_currency), '|', ','); + END IF; + IF a_get_inactive_currency IS NULL THEN + SET a_get_inactive_currency = 0; + END IF; + IF a_get_all_discount IS NULL THEN + SET a_get_all_discount = 1; + END IF; + IF a_ids_discount IS NULL THEN + SET a_ids_discount = ''; + ELSE + SET a_ids_discount = REPLACE(TRIM(a_ids_discount), '|', ','); + END IF; + IF a_get_inactive_discount IS NULL THEN + SET a_get_inactive_discount = 0; + END IF; + + + -- Temporary tables + DROP TABLE IF EXISTS tmp_Discount; + DROP TABLE IF EXISTS tmp_Currency; + DROP TABLE IF EXISTS tmp_Delivery_Region; + DROP TABLE IF EXISTS tmp_Shop_Image; + DROP TABLE IF EXISTS tmp_Shop_Variation; + DROP TABLE IF EXISTS tmp_Shop_Product; + DROP TABLE IF EXISTS tmp_Shop_Category; + + CREATE TABLE tmp_Shop_Category ( + id_category INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Category_id_category + FOREIGN KEY (id_category) + REFERENCES Shop_Category(id_category), + active BIT NOT NULL, + display_order INT NOT NULL, + can_view BIT, + can_edit BIT, + can_admin BIT + ); + + CREATE TABLE tmp_Shop_Product ( + id_category INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_category + FOREIGN KEY (id_category) + REFERENCES Shop_Category(id_category), + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + -- product_has_variations BIT NOT NULL, + id_permutation INT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + active_category BIT NOT NULL, + active_product BIT NOT NULL, + active_permutation BIT NULL, + display_order_category INT NOT NULL, + display_order_product INT NOT NULL, + display_order_permutation INT NULL, + rank_permutation INT NOT NULL, # _in_category + name VARCHAR(255) NOT NULL, + description VARCHAR(4000) NOT NULL, + /* + price_GBP_full FLOAT NOT NULL, + price_GBP_min FLOAT NOT NULL, + */ + latency_manufacture INT NOT NULL, + quantity_min FLOAT NOT NULL, + quantity_max FLOAT NOT NULL, + quantity_step FLOAT NOT NULL, + quantity_stock FLOAT NOT NULL, + is_subscription BIT NOT NULL, + id_recurrence_interval INT, + CONSTRAINT FK_tmp_Shop_Product_id_recurrence_interval + FOREIGN KEY (id_recurrence_interval) + REFERENCES Shop_Recurrence_Interval(id_interval), + count_recurrence_interval INT, + id_stripe_product VARCHAR(100), + product_has_variations INT NOT NULL, + can_view BIT, + can_edit BIT, + can_admin BIT + ); + + /* + CREATE TEMPORARY TABLE tmp_Shop_Variation ( + id_variation INT NOT NULL, + id_product INT NOT NULL, + display_order INT NOT NULL + ); + */ + + CREATE TABLE tmp_Shop_Image ( + id_image INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Image_id_image + FOREIGN KEY (id_image) + REFERENCES Shop_Image(id_image), + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Image_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NULL, + CONSTRAINT FK_tmp_Shop_Image_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + active BIT NOT NULL, + display_order INT NOT NULL, + rank_in_product_permutation INT NOT NULL + ); + + CREATE TABLE tmp_Delivery_Region ( + id_region INT NOT NULL, + CONSTRAINT FK_tmp_Delivery_Region_id_region + FOREIGN KEY (id_region) + REFERENCES Shop_Region(id_region), + active BIT NOT NULL, + display_order INT NOT NULL + ); + + CREATE TABLE tmp_Currency ( + id_currency INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Currency_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency), + active BIT NOT NULL, + display_order INT NOT NULL + ); + + CREATE TABLE tmp_Discount ( + id_discount INT NOT NULL, + CONSTRAINT FK_tmp_Discount_id_discount + FOREIGN KEY (id_discount) + REFERENCES Shop_Discount(id_discount), + active BIT NOT NULL, + display_order INT NOT NULL + ); + + CREATE TABLE IF NOT EXISTS tmp_Msg_Error ( # IF NOT EXISTS + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + guid VARCHAR(36) NOT NULL, + # code VARCHAR(50) NOT NULL, + # CONSTRAINT chk_tmp_Msg_Error_code CHECK (code IN (SELECT code FROM Shop_Msg_Error_Type)), + id_type INT NOT NULL, + CONSTRAINT FK_tmp_Msg_Error_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Msg_Error_Type(id_type), + msg VARCHAR(4000) NOT NULL + ); + + + -- Parse filters + SET v_has_filter_category = CASE WHEN a_ids_category = '' THEN 0 ELSE 1 END; + SET v_has_filter_product = CASE WHEN a_ids_product = '' THEN 0 ELSE 1 END; + SET v_has_filter_permutation = CASE WHEN a_ids_permutation = '' THEN 0 ELSE 1 END; + SET v_has_filter_image = CASE WHEN a_ids_image = '' THEN 0 ELSE 1 END; + SET v_has_filter_delivery_region = CASE WHEN a_ids_delivery_region = '' THEN 0 ELSE 1 END; + SET v_has_filter_currency = CASE WHEN a_ids_currency = '' THEN 0 ELSE 1 END; + SET v_has_filter_discount = CASE WHEN a_ids_discount = '' THEN 0 ELSE 1 END; + + -- select v_has_filter_product, v_has_filter_permutation; + + INSERT INTO tmp_Shop_Product ( + id_category, + id_product, + id_permutation, + active_category, + active_product, + active_permutation, + display_order_category, + display_order_product, + display_order_permutation, + rank_permutation, + name, + description, + /* + price_GBP_VAT_incl, + price_GBP_VAT_excl, + price_GBP_min, + */ + latency_manufacture, + quantity_min, + quantity_max, + quantity_step, + quantity_stock, + is_subscription, + id_recurrence_interval, + count_recurrence_interval, + id_stripe_product, + product_has_variations + ) + SELECT + P.id_category, + P.id_product, + -- P.has_variations AS product_has_variations, + PP.id_permutation, + C.active AS active_category, + P.active AS active_product, + PP.active AS active_permutation, + C.display_order AS display_order_category, + P.display_order AS display_order_product, + PP.display_order AS display_order_permutation, + RANK() OVER (ORDER BY C.display_order, P.display_order, PP.display_order) AS rank_permutation, #PARTITION BY P.id_category # _in_category + P.name, + PP.description, + /* + PP.price_GBP_VAT_incl, + PP.price_GBP_VAT_excl, + PP.price_GBP_min, + */ + PP.latency_manufacture, + PP.quantity_min, + PP.quantity_max, + PP.quantity_step, + PP.quantity_stock, + PP.is_subscription, + PP.id_recurrence_interval, + PP.count_recurrence_interval, + PP.id_stripe_product, + P.has_variations + FROM Shop_Product P + INNER JOIN Shop_Product_Permutation PP + ON P.id_product = PP.id_product + INNER JOIN Shop_Category C + ON P.id_category = C.id_category + WHERE + # permutations + ( + ( + a_get_all_product_permutation + OR v_has_filter_permutation AND FIND_IN_SET(PP.id_permutation, a_ids_permutation) > 0 + ) + AND (a_get_inactive_permutation OR PP.active) + ) + # categories + AND ( + ( + a_get_all_category + OR v_has_filter_category AND FIND_IN_SET(P.id_category, a_ids_category) > 0 + ) + AND (a_get_inactive_category OR C.active) + ) + # products + AND ( + ( + a_get_all_product + OR v_has_filter_product AND FIND_IN_SET(P.id_product, a_ids_product) > 0 + ) + AND (a_get_inactive_product OR P.active) + ) + ; + + -- select * from tmp_Shop_Product; + + IF a_get_first_product_only THEN + DELETE FROM tmp_Shop_Product t_P + WHERE t_P.rank_permutation > 1 + ; + END IF; + + INSERT INTO tmp_Shop_Category ( + id_category, + active, + display_order + ) + SELECT DISTINCT C.id_category, + C.active, + C.display_order + FROM tmp_Shop_Product t_P + INNER JOIN Shop_Category C + ON t_P.id_category = C.id_category + ORDER BY C.display_order + ; + + /* + INSERT INTO tmp_Shop_Variation ( + id_variation, id_product # , display_order + ) + SELECT P.id_variation, P.id_product # , P.display_order + FROM Shop_Variation V + INNER JOIN tmp_Shop_Product t_P + ON V.id_product = t_P.id_product + WHERE V.active; + */ + + # Product Images + INSERT INTO tmp_Shop_Image ( + id_product, + id_permutation, + id_image, + active, + display_order, + rank_in_product_permutation + ) + SELECT id_product, + id_permutation, + id_image, + active, + ROW_NUMBER() OVER (ORDER BY display_order_product_temp, display_order_image), + RANK() OVER (PARTITION BY id_product, id_permutation ORDER BY display_order_product_temp, display_order_image) + FROM ( + SELECT t_P.id_product, + I.id_permutation, + I.id_image, + I.active, + I.display_order AS display_order_image, + t_P.rank_permutation AS display_order_product_temp + FROM Shop_Image I + INNER JOIN tmp_Shop_Product t_P + ON I.id_product = t_P.id_product + AND NOT t_P.product_has_variations + UNION + SELECT t_P.id_product, + I.id_permutation, + I.id_image, + I.active, + I.display_order AS display_order_image, + t_P.rank_permutation AS display_order_product_temp + FROM Shop_Image I + INNER JOIN tmp_Shop_Product t_P + ON I.id_permutation = t_P.id_permutation + AND t_P.product_has_variations + ) IPP + WHERE (a_get_all_image OR a_get_first_image_only OR FIND_IN_SET(id_image, a_ids_image) > 0) + AND (a_get_inactive_image OR IPP.active) + ; + + IF a_get_first_image_only THEN + DELETE FROM tmp_Shop_Image + WHERE rank_in_product_permutation > 1 + ; + END IF; + + /* + IF v_has_filter_image THEN + DELETE FROM tmp_Shop_Product + WHERE id_product NOT IN (SELECT DISTINCT id_product FROM tmp_Shop_Image); + DELETE FROM tmp_Shop_Category + WHERE id_category NOT IN (SELECT DISTINCT id_category FROM tmp_Shop_Product); + END IF; + */ + + # Delivery Regions + INSERT INTO tmp_Delivery_Region ( + id_region, + active, + display_order + ) + WITH RECURSIVE Recursive_CTE_Delivery_Region AS ( + SELECT + DR.id_region AS id_region_parent, + NULL AS id_region_child + FROM Shop_Region DR + INNER JOIN Shop_Product_Delivery_Option_Link PDOL + ON DR.id_region = PDOL.id_region + INNER JOIN tmp_Shop_Product t_P + ON PDOL.id_product = t_P.id_product + AND PDOL.id_permutation <=> t_P.id_permutation + WHERE + ( + a_get_all_delivery_region + OR FIND_IN_SET(DR.id_region, a_ids_delivery_region) > 0 + ) + AND ( + a_get_inactive_delivery_region + OR DR.active + ) + UNION + SELECT + DRB.id_region_parent, + DRB.id_region_child + FROM Shop_Region_Branch DRB + INNER JOIN Recursive_CTE_Delivery_Region r_DR + ON DRB.id_region_parent = r_DR.id_region_child + AND ( + a_get_inactive_delivery_region + OR DRB.active + ) + ) + SELECT + DR.id_region, + DR.active, + DR.display_order + FROM Shop_Region DR + INNER JOIN Recursive_CTE_Delivery_Region r_DR + ON DR.id_region = r_DR.id_region_parent + OR DR.id_region = r_DR.id_region_child + ; + + IF v_has_filter_delivery_region THEN + SET v_ids_permutation_unavailable = ( + SELECT GROUP_CONCAT(t_P.id_permutation SEPARATOR ', ') + FROM tmp_Shop_Product t_P + INNER JOIN Shop_Product_Currency_Region_Link PCRL + ON t_P.id_permutation = PCRL.id_permutation + LEFT JOIN tmp_Delivery_Region t_DR + ON PCRL.id_region_purchase = t_DR.id_region + WHERE ISNULL(t_DR.id_region) + ); + IF NOT ISNULL(v_ids_permutation_unavailable) THEN + INSERT INTO tmp_Msg_Error ( + guid, + id_type, + msg + ) + VALUES ( + v_guid, + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'PRODUCT_AVAILABILITY' LIMIT 1), + CONCAT('Error: The following permutation IDs are not available in this region: ', v_ids_permutation_unavailable) + ); + END IF; + /* + DELETE FROM tmp_Shop_Product t_P + WHERE t_P.id_permutation NOT IN ( + SELECT + id_permutation + FROM Shop_Product_Currency_Region_Link PCL + INNER JOIN tmp_Delivery_Region t_DR + ON PCRL.id_region_purchase = t_DR.id_region + ); + */ + END IF; + + -- select * from tmp_Shop_Product; + + # Currencies + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN + INSERT INTO tmp_Currency ( + id_currency, + active, + display_order + ) + SELECT + C.id_currency, + C.active, + C.display_order + FROM Shop_Product_Currency_Region_Link PCRL + INNER JOIN Shop_Currency C ON PCRL.id_currency = C.id_currency + INNER JOIN tmp_Shop_Product t_P + ON PCRL.id_product <=> t_P.id_product + AND PCRL.id_permutation <=> t_P.id_permutation + INNER JOIN tmp_Delivery_Region t_DR ON PCRL.id_region_purchase = t_DR.id_region + WHERE + ( + a_get_all_currency + OR FIND_IN_SET(C.id_currency, a_ids_currency) > 0 + ) + AND ( + a_get_inactive_currency + OR ( + C.active + AND PCRL.active + ) + ) + ; + + -- select * from tmp_Currency; + + IF v_has_filter_currency THEN + SET v_ids_permutation_unavailable = ( + SELECT GROUP_CONCAT(t_P.id_permutation SEPARATOR ', ') + FROM ( + SELECT * + FROM tmp_Shop_Product t_P + WHERE + ( + a_get_all_category + OR a_get_all_product + OR a_get_all_product_permutation + ) + AND FIND_IN_SET(t_P.id_category, a_ids_category) = 0 + AND FIND_IN_SET(t_P.id_product, a_ids_product) = 0 + AND FIND_IN_SET(t_P.id_permutation, a_ids_permutation) = 0 + ) t_P + INNER JOIN ( + SELECT * + FROM Shop_Product_Currency_Region_Link PCRL + WHERE + ( + a_get_all_currency + OR FIND_IN_SET(PCRL.id_currency, a_ids_currency) > 0 + ) + ) PCRL + ON t_P.id_permutation = PCRL.id_permutation + LEFT JOIN tmp_Currency t_C + ON PCRL.id_currency = t_C.id_currency + WHERE ISNULL(t_C.id_currency) + ); + IF NOT ISNULL(v_ids_permutation_unavailable) THEN + INSERT INTO tmp_Msg_Error ( + guid, + id_type, + msg + ) + VALUES ( + v_guid, + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'PRODUCT_AVAILABILITY' LIMIT 1), + CONCAT('Error: The following permutation IDs are not available in this currency: ', v_ids_permutation_unavailable) + ); + END IF; + /* + DELETE FROM tmp_Shop_Product t_P + WHERE t_P.id_permutation NOT IN ( + SELECT + id_permutation + FROM Shop_Product_Currency_Region_Link PCL + INNER JOIN tmp_Currency t_C + ON PCRL.id_currency = t_C.id_currency + ); + */ + END IF; + END IF; + + # Discounts + INSERT INTO tmp_Discount ( + id_discount, + active, + display_order + ) + SELECT + D.id_discount, + D.active, + D.display_order + FROM Shop_Discount D + INNER JOIN tmp_Shop_Product t_P + ON D.id_product = t_P.id_product + AND D.id_permutation <=> t_P.id_permutation + WHERE + ( + a_get_all_discount + OR FIND_IN_SET(D.id_discount, a_ids_discount) > 0 + ) + AND ( + a_get_inactive_discount + OR D.active + ) + ; + + # select 'pre-permission results'; + # select * from tmp_Shop_Product; + + -- Permissions + IF EXISTS (SELECT * FROM tmp_Shop_Category LIMIT 1) THEN + # SET v_id_user := (SELECT id_user FROM Shop_User WHERE name = CURRENT_USER()); + SET v_id_permission_product := (SELECT id_permission FROM Shop_Permission WHERE code = 'STORE_PRODUCT' LIMIT 1); + -- SET v_ids_product_permission := (SELECT GROUP_CONCAT(id_product SEPARATOR ',') FROM tmp_Shop_Product); + SET v_ids_permutation_permission := (SELECT GROUP_CONCAT(id_permutation SEPARATOR ',') FROM tmp_Shop_Product WHERE NOT ISNULL(id_permutation)); + + -- SELECT v_guid, a_id_user, false, v_id_permission_product, v_id_access_level_view, v_ids_permutation_permission; + -- select * from Shop_User_Eval_Temp; + + CALL p_shop_user_eval(v_guid, a_id_user, false, v_id_permission_product, v_id_access_level_view, v_ids_permutation_permission); + + -- select * from Shop_User_Eval_Temp; + + UPDATE tmp_Shop_Product t_P + INNER JOIN Shop_User_Eval_Temp UE_T + ON t_P.id_permutation = UE_T.id_permutation + AND UE_T.GUID = v_guid + SET t_P.can_view = UE_T.can_view, + t_P.can_edit = UE_T.can_edit, + t_P.can_admin = UE_T.can_admin; + + DELETE FROM tmp_Shop_Product t_P + WHERE + FIND_IN_SET(t_P.id_product, (SELECT GROUP_CONCAT(UET.id_product SEPARATOR ',') FROM Shop_User_Eval_Temp UET)) = 0 # id_product NOT LIKE CONCAT('%', (SELECT GROUP_CONCAT(id_product SEPARATOR '|') FROM Shop_User_Eval_Temp), '%'); + OR ( + ISNULL(t_P.can_view) + AND ( + NOT v_has_filter_category + OR FIND_IN_SET(t_P.id_category, a_ids_category) = 0 + ) + AND ( + NOT v_has_filter_product + OR FIND_IN_SET(t_P.id_product, a_ids_product) = 0 + ) + AND ( + NOT v_has_filter_permutation + OR FIND_IN_SET(t_P.id_permutation, a_ids_permutation) = 0 + ) + ) + ; + + # CALL p_shop_user_eval_clear_temp(v_guid); + # DROP TABLE IF EXISTS Shop_User_Eval_Temp; + DELETE FROM Shop_User_Eval_Temp + WHERE GUID = v_guid + ; + END IF; + + + -- select * from tmp_Shop_Product; + + -- Returns + SET v_now := NOW(); + + # Categories + SELECT + DISTINCT t_C.id_category, + C.name, + C.description, + C.display_order + FROM tmp_Shop_Category t_C + INNER JOIN Shop_Category C + ON t_C.id_category = C.id_category + INNER JOIN tmp_Shop_Product t_P + ON t_C.id_category = t_P.id_category + ORDER BY C.display_order + ; + + # Products + SELECT + t_P.id_product, + t_P.id_permutation, + t_P.name, + t_P.description, + P.has_variations, + P.id_category, + t_P.latency_manufacture, + t_P.quantity_min, + t_P.quantity_max, + t_P.quantity_step, + t_P.quantity_stock, + t_P.id_stripe_product, + t_P.is_subscription, + RI.name AS name_recurrence_interval, + RI.name_plural AS name_plural_recurrence_interval, + t_P.count_recurrence_interval, + t_P.display_order_category, + t_P.display_order_product, + t_P.display_order_permutation, + IFNULL(t_P.can_view, 0), + IFNULL(t_P.can_edit, 0), + IFNULL(t_P.can_admin, 0) + FROM tmp_Shop_Product t_P + INNER JOIN Shop_Product P + ON t_P.id_product = P.id_product + LEFT JOIN Shop_Recurrence_Interval RI + ON t_P.id_recurrence_interval = RI.id_interval + ORDER BY t_P.rank_permutation + ; + + # Variations + SELECT + V.id_variation, + t_P.id_product, + t_P.id_permutation, + t_P.id_category, + VT.code AS code_variation_type, + VT.name AS name_variation_type, + V.code AS code_variation, + V.name AS name_variation, + RANK() OVER (ORDER BY t_P.rank_permutation, PPVL.display_order) AS display_order + FROM Shop_Variation V + INNER JOIN Shop_Variation_Type VT + ON V.id_type = VT.id_type + INNER JOIN Shop_Product_Permutation_Variation_Link PPVL ON V.id_variation = PPVL.id_variation + INNER JOIN tmp_Shop_Product t_P ON PPVL.id_permutation <=> t_P.id_permutation + WHERE V.active + AND PPVL.active + ; + + /* + # Permutation variations output + SELECT t_P.id_permutation, + t_P.id_product, + t_P.id_category, + id_variation + FROM Shop_Product_Permutation_Variation_Link PPVL + INNER JOIN tmp_Shop_Product t_P + ON t_P.id_permutation = PPVL.id_permutation + ORDER BY t_P.display_order + ; + */ + + # Product Price + SELECT + PCRL.id_link AS id_price, + t_P.id_permutation, + t_P.id_product, + t_P.id_category, + t_C.id_currency, + C.code AS code_currency, + C.name AS name_currency, + C.symbol AS symbol_currency, + t_DR.id_region, + PCRL.price_local_VAT_incl, + PCRL.price_local_VAT_excl, + ROW_NUMBER() OVER(ORDER BY t_P.rank_permutation, C.display_order) AS display_order + FROM Shop_Product_Currency_Region_Link PCRL + INNER JOIN tmp_Shop_Product t_P + ON t_P.id_product = PCRL.id_product + AND t_P.id_permutation <=> PCRL.id_permutation + -- INNER JOIN Shop_Product P ON PCRL.id_product = P.id_product + INNER JOIN tmp_Currency t_C ON PCRL.id_currency = t_C.id_currency + INNER JOIN Shop_Currency C ON t_C.id_currency = C.id_currency + INNER JOIN tmp_Delivery_Region t_DR ON PCRL.id_region_purchase = t_DR.id_region + WHERE ( + a_get_inactive_product + AND a_get_inactive_permutation + AND a_get_inactive_currency + AND a_get_inactive_delivery_region + OR PCRL.active + ) + ORDER BY t_P.rank_permutation + ; + + /* + # Currency + SELECT + DISTINCT C.id_currency, + C.code, + C.name, + C.factor_from_GBP, + t_C.display_order + FROM Shop_Currency C + INNER JOIN tmp_Currency t_C ON C.id_currency = t_C.id_currency + GROUP BY C.id_currency, t_C.display_order + ORDER BY t_C.display_order + ; + */ + + # Images + SELECT + t_I.id_image, + t_I.id_product, + t_I.id_permutation, + t_P.id_category, + I.url, + I.active, + I.display_order + FROM tmp_Shop_Image t_I + INNER JOIN Shop_Image I + ON t_I.id_image = I.id_image + INNER JOIN tmp_Shop_Product t_P + ON t_I.id_product = t_P.id_product + AND t_I.id_permutation <=> t_P.id_permutation + ORDER BY t_P.rank_permutation, I.display_order + ; + + # Delivery options + SELECT + _DO.id_option, + PDOL.id_product, + PDOL.id_permutation, + t_P.id_category, + _DO.code, + _DO.name, + _DO.latency_delivery_min, + _DO.latency_delivery_max, + _DO.quantity_min, + _DO.quantity_max, + GROUP_CONCAT(DR.code SEPARATOR ',') AS codes_region, + GROUP_CONCAT(DR.name SEPARATOR ',') AS names_region, + PDOL.price_local, + PDOL.display_order + FROM Shop_Delivery_Option _DO + INNER JOIN Shop_Product_Delivery_Option_Link PDOL + ON _DO.id_option = PDOL.id_delivery_option + AND ( + a_get_inactive_delivery_region + OR PDOL.active + ) + INNER JOIN tmp_Shop_Product t_P + ON PDOL.id_product = t_P.id_product + AND PDOL.id_permutation <=> t_P.id_permutation + INNER JOIN tmp_Delivery_Region t_DR ON PDOL.id_region = t_DR.id_region + INNER JOIN Shop_Region DR ON t_DR.id_region = DR.id_region + WHERE ( + a_get_inactive_delivery_region + OR _DO.active + ) + GROUP BY t_P.id_category, t_P.id_product, PDOL.id_permutation, t_P.rank_permutation, DR.id_region, _DO.id_option, PDOL.id_link + ORDER BY t_P.rank_permutation, PDOL.display_order + ; + + # Discounts + SELECT + D.id_discount, + P.id_category, + D.id_product, + D.id_permutation, + DR.id_region, + C.id_currency, + D.code AS code_discount, + D.name AS name_discount, + D.multiplier, + D.subtractor, + D.apply_multiplier_first, + D.quantity_min, + D.quantity_max, + D.date_start, + D.date_end, + GROUP_CONCAT(DR.code) AS codes_region, + GROUP_CONCAT(DR.name) AS names_region, + GROUP_CONCAT(C.code) AS codes_currency, + GROUP_CONCAT(C.name) AS names_currency, + ROW_NUMBER() OVER(ORDER BY D.display_order) AS display_order + FROM tmp_Discount t_D + INNER JOIN Shop_Discount D ON t_D.id_discount = D.id_discount + INNER JOIN Shop_Product P ON D.id_product = P.id_product + INNER JOIN tmp_Shop_Product t_P + ON D.id_product = t_P.id_product + -- AND D.id_permutation <=> t_P.id_permutation + INNER JOIN Shop_Discount_Region_Currency_Link DRCL + ON D.id_discount = DRCL.id_discount + INNER JOIN tmp_Delivery_Region t_DR ON DRCL.id_region = t_DR.id_region + INNER JOIN Shop_Region DR ON t_DR.id_region = DR.id_region + INNER JOIN tmp_Currency t_C ON DRCL.id_currency = t_C.id_currency + INNER JOIN Shop_Currency C ON t_C.id_currency = C.id_currency + GROUP BY D.id_discount, DR.id_region, C.id_currency + ORDER BY D.display_order, DR.display_order, C.display_order + ; + + /* + # Delivery Regions + SELECT + t_DR.id_region, + t_P.id_category, + t_P.id_product, + t_P.id_permutation, + DR.code, + DR.name + FROM tmp_Delivery_Region t_DR + INNER JOIN Shop_Delivery_Region DR ON t_DR.id_region = DR.id_region + INNER JOIN Shop_Product_Region_Currency_Link PDRL + ON DR.id_region = PDRL.id_region + AND ( + a_get_inactive_delivery_region + OR PDRL.active + ) + INNER JOIN tmp_Shop_Product t_P + ON PDRL.id_product = t_P.id_product + AND PDRL.id_permutation <=> t_P.id_permutation + INNER JOIN tmp_Currency t_C ON PDRL.id_currency = t_C.id_currency + ORDER BY t_DR.display_order + ; + */ + + # Errors + SELECT + t_ME.display_order, + t_ME.guid, + t_ME.id_type, + t_ME.msg, + MET.code, + MET.name, + MET.description + FROM tmp_Msg_Error t_ME + INNER JOIN Shop_Msg_Error_Type MET + ON t_ME.id_type = MET.id_type + WHERE guid = v_guid + ; + + /* + # Return arguments for test + SELECT + a_ids_category, + a_get_inactive_category, + a_ids_product, + a_get_inactive_product, + a_get_first_product_only, + a_get_all_product, + a_ids_image, + a_get_inactive_image, + a_get_first_image_only, + a_get_all_image + ; + */ + + # select 'other outputs'; + # select * from tmp_Shop_Product; + + -- Clean up + DROP TABLE IF EXISTS tmp_Discount; + DROP TABLE IF EXISTS tmp_Currency; + DROP TABLE IF EXISTS tmp_Delivery_Region; + DROP TABLE IF EXISTS tmp_Shop_Image; + DROP TABLE IF EXISTS tmp_Shop_Variation; + DROP TABLE IF EXISTS tmp_Shop_Product; + DROP TABLE IF EXISTS tmp_Shop_Category; +END // +DELIMITER ; + + + +CALL p_shop_get_many_product ( + '', # a_id_user + 1, # a_get_all_category + '', # a_ids_category + 0, # a_get_inactive_category + 1, # a_get_all_product + '', # a_ids_product + 0, # a_get_inactive_product + 0, # a_get_first_product_only + 1, # a_get_all_product_permutation + '', # a_ids_permutation + 0, # a_get_inactive_permutation + 0, # a_get_all_image + '', # a_ids_image + 0, # a_get_inactive_image + 1, # a_get_first_image_only + 0, # a_get_all_delivery_region + '1', # a_ids_delivery_region + 0, # a_get_inactive_delivery_region + 0, # a_get_all_currency + '1', # a_ids_currency + 0, # a_get_inactive_currency + 1, # a_get_all_discount + '', # a_ids_discount + 0 # a_get_inactive_discount +); + +/* +select * from shop_image; +select * from shop_product; +select * from TMP_MSG_ERROR; +DROP TABLE TMP_MSG_ERROR; + +insert into shop_product_change_set (comment) + values ('set product not subscription - test bool output to python'); + update shop_product + set is_subscription = 0, + id_change_set = (select id_change_set from shop_product_change_set order by id_change_set desc limit 1) + where id_product = 1 +*/ diff --git a/static/sql/701_p_shop_edit_user.sql b/static/sql/701_p_shop_edit_user.sql new file mode 100644 index 00000000..b8ffecb9 --- /dev/null +++ b/static/sql/701_p_shop_edit_user.sql @@ -0,0 +1,180 @@ + +USE PARTS; + +/* + +CALL p_shop_edit_user ( + 'auth0|6582b95c895d09a70ba10fef', # a_id_user + '', # a_name + '', # a_email + 0 # a_email_verified +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_edit_user; + + +DELIMITER // +CREATE PROCEDURE p_shop_edit_user ( + IN a_id_user VARCHAR(200), + IN a_name VARCHAR(255), + IN a_email VARCHAR(254), + IN a_email_verified BIT +) +BEGIN + -- Argument redeclaration + -- Variable declaration + DECLARE v_has_filter_user BIT; + -- DECLARE v_now DATETIME; + + + -- Argument validation + default values + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + IF a_name IS NULL THEN + SET a_name = ''; + ELSE + SET a_name = TRIM(a_name); + END IF; + IF a_email IS NULL THEN + SET a_email = ''; + ELSE + SET a_email = TRIM(a_email); + END IF; + IF a_email_verified IS NULL THEN + SET a_email_verified = 0; + END IF; + + -- Temporary tables + DROP TABLE IF EXISTS tmp_Msg_Error; + DROP TABLE IF EXISTS tmp_Shop_User; + + CREATE TABLE tmp_Shop_User ( + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_tmp_Shop_User_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user), + active BIT NOT NULL + ); + + CREATE TABLE tmp_Msg_Error ( + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + id_type INT NOT NULL, + # code VARCHAR(50) NOT NULL, + # CONSTRAINT chk_tmp_Msg_Error_code CHECK (code IN (SELECT code FROM Shop_Msg_Error_Type)), + CONSTRAINT FK_tmp_Msg_Error_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Msg_Error_Type(id_type), + msg VARCHAR(4000) NOT NULL + ); + + + -- Parse filters + SET v_has_filter_user = CASE WHEN a_id_user = '' THEN 0 ELSE 1 END; + + + -- User + IF v_has_filter_user THEN + INSERT INTO tmp_Shop_User ( + id_user, + active + ) + SELECT id_user, + active + FROM Shop_User + WHERE id_user LIKE CONCAT('%', a_id_user, '%') + AND active + LIMIT 1 + ; + + IF NOT EXISTS (SELECT id_user FROM tmp_Shop_User LIMIT 1) THEN + INSERT INTO Shop_User ( + id_user, + name, + email, + email_verified + ) + VALUES ( + a_id_user, + a_name, + a_email, + a_email_verified + ); + + INSERT INTO tmp_Shop_User ( + id_user, + active + ) + SELECT id_user, + active + FROM Shop_User + WHERE id_user LIKE CONCAT('%', a_id_user, '%') + AND active + LIMIT 1 + ; + END IF; + + SET a_id_user := (SELECT id_user FROM tmp_Shop_User LIMIT 1); + ELSE + INSERT INTO tmp_Msg_Error ( + id_type, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + 'No user ID provided.' + ) + ; + END IF; + + + /* + IF NOT EXISTS (SELECT msg FROM tmp_Msg_Error LIMIT 1) THEN + END IF; + */ + + + -- Returns + # User + SELECT * + FROM tmp_Shop_User + ; + + # Errors + SELECT * + FROM tmp_Msg_Error + ; + + /* + # Return arguments for test + SELECT a_id_user, + a_name, + a_email, + a_email_verified + ; + */ + + -- Clean up + DROP TABLE IF EXISTS tmp_Msg_Error; + DROP TABLE IF EXISTS tmp_Shop_User; +END // +DELIMITER ; + + + +/* + +CALL p_shop_edit_user ( + '', + '', + '', + 0 +) + +*/ diff --git a/static/sql/701_p_shop_get_many_role_permission.sql b/static/sql/701_p_shop_get_many_role_permission.sql new file mode 100644 index 00000000..720f1bcf --- /dev/null +++ b/static/sql/701_p_shop_get_many_role_permission.sql @@ -0,0 +1,127 @@ + +USE PARTS; + +/* +THIS STRUCTURE DOES NOT WORK WITH MYSQL ?? + +CALL p_shop_get_many_role_permission ( + '', + 0, + '', + 0, + 0, + 1, + '', + 0, + 0, + 1 +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_many_role_permission; +/* +DROP TABLE IF EXISTS tmp_Shop_Image; +DROP TABLE IF EXISTS tmp_Shop_Product; +DROP TABLE IF EXISTS tmp_Shop_Variation; +DROP TABLE IF EXISTS tmp_Shop_Category; +*/ + +DELIMITER // +CREATE PROCEDURE p_shop_get_many_role_permission ( + a_ids_role NVARCHAR(500), + a_get_inactive_roles BIT +) +BEGIN + -- Variable declaration + DECLARE v_has_filter_role BIT; + DECLARE v_priority_view INT; + DECLARE v_priority_edit INT; + DECLARE v_priority_admin INT; + /* + DECLARE v_ids_product_permission VARCHAR(500); + DECLARE v_now DATETIME; + */ + + -- Parse arguments + get default values + IF a_ids_role IS NULL THEN + SET a_ids_role = ''; + ELSE + SET a_ids_role = TRIM(a_ids_role); + END IF; + IF a_get_inactive_roles IS NULL THEN + SET a_get_inactive_roles = 0; + END IF; + + + -- Temporary tables + CREATE TABLE tmp_Permission ( + id_role INT NOT NULL, + CONSTRAINT FK_tmp_User_Permission_id_role + FOREIGN KEY (id_role) + REFERENCES Shop_Role(id_role), + id_permission INT, + CONSTRAINT FK_tmp_User_Permission_id_permission + FOREIGN KEY (id_permission) + REFERENCES Shop_Permission(id_permission), + id_access_level INT, + CONSTRAINT FK_tmp_User_Permission_id_access_level + FOREIGN KEY (id_user) + REFERENCES Shop_Access_Level(id_user), + can_view BIT, + can_edit BIT, + can_admin BIT + ); + + + -- Parse filters + SET a_ids_role = REPLACE(a_ids_role, ',', '|'); + SET v_has_filter_role = CASE WHEN a_ids_role = '' THEN 0 ELSE 1 END; + + INSERT INTO tmp_User_Permission ( + id_role, + id_permission, + id_access_level, + can_view, + can_edit, + can_admin + ) + SELECT U.id_user, + U.is_super_user, + U.is_super_user, + U.is_super_user, + U.is_super_user + FROM Shop_Role R + INNER JOIN Shop_Role_Permission_Link RPL + ON R.id_role = RPL.id_role + AND RPL.active + INNER JOIN Shop_Permission PERM + ON RPL.id_permission = PERM.id_permission + AND PERM.active + INNER JOIN Shop_Permission_Group PG + ON PERM.id_permission_group = PG.id_group + AND PG.active + LEFT JOIN Shop_Access_Level AL + ON RPL.id_access_level = AL.id_access_level + AND AL.active + WHERE R.id_role LIKE CONCAT('%', a_ids_role, '%') + AND PERM.required_access_level = 0 OR AL. + ; + + UPDATE tmp_User_Permission t_UP + INNER JOIN Shop_Access_Level AL + ON AL.code = 'ADMIN' + SET t_UP.id_access_level = AL.id_access_level + WHERE t_UP.is_super_user + ; + + + -- Clean up + DROP TABLE IF EXISTS tmp_Shop_Category; + DROP TABLE IF EXISTS tmp_Shop_Product; + DROP TABLE IF EXISTS tmp_Shop_Image; +END // +DELIMITER ; + diff --git a/static/sql/702.1_p_shop_get_many_currency.sql b/static/sql/702.1_p_shop_get_many_currency.sql new file mode 100644 index 00000000..bc42012d --- /dev/null +++ b/static/sql/702.1_p_shop_get_many_currency.sql @@ -0,0 +1,44 @@ + +USE PARTS; + +/* + +CALL p_shop_get_many_currency ( + 0 # a_get_inactive_currency +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_many_currency; + + +DELIMITER // +CREATE PROCEDURE p_shop_get_many_currency ( + IN a_get_inactive_currency BIT +) +BEGIN + IF a_get_inactive_currency IS NULL THEN + SET a_get_inactive_currency = 0; + END IF; + + SELECT + C.id_currency, + C.code, + C.name, + C.factor_from_GBP, + C.active, + C.display_order + FROM Shop_Currency C + WHERE a_get_inactive_currency + OR C.active + ORDER BY C.display_order + ; +END // +DELIMITER ; + + +CALL p_shop_get_many_currency ( + 0 # a_get_inactive_currency +); diff --git a/static/sql/702.2_p_shop_get_many_region.sql b/static/sql/702.2_p_shop_get_many_region.sql new file mode 100644 index 00000000..a45a8510 --- /dev/null +++ b/static/sql/702.2_p_shop_get_many_region.sql @@ -0,0 +1,42 @@ + +USE PARTS; + +/* + +CALL p_shop_get_many_region ( + 0 # a_get_inactive_region +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_many_region; + + +DELIMITER // +CREATE PROCEDURE p_shop_get_many_region ( + IN a_get_inactive_region BIT +) +BEGIN + IF a_get_inactive_region IS NULL THEN + SET a_get_inactive_region = 0; + END IF; + + SELECT + R.id_region, + R.code, + R.name, + R.active, + R.display_order + FROM Shop_Region R + WHERE a_get_inactive_region + OR R.active + ORDER BY R.display_order + ; +END // +DELIMITER ; + +CALL p_shop_get_many_region ( + 0 # a_get_inactive_region +); diff --git a/static/sql/702_p_shop_edit_user_basket.sql b/static/sql/702_p_shop_edit_user_basket.sql new file mode 100644 index 00000000..156d11aa --- /dev/null +++ b/static/sql/702_p_shop_edit_user_basket.sql @@ -0,0 +1,830 @@ + +USE PARTS; + +/* + +CALL p_shop_edit_user_basket ( + '', # a_id_user + '', # a_ids_permutation_basket + '', # a_quantities_permutation_basket + 1, # a_id_permutation_edit + NULL, # a_quantity_permutation_edit + 1, # a_sum_not_edit + 1, # a_id_currency_edit + 1 # a_id_region_purchase +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_edit_user_basket; + + +DELIMITER // +CREATE PROCEDURE p_shop_edit_user_basket ( + IN a_id_user VARCHAR(200), + IN a_ids_permutation_basket VARCHAR(4000), + IN a_quantities_permutation_basket VARCHAR(4000), + IN a_id_permutation_edit INT, + IN a_quantity_permutation_edit INT, + IN a_sum_not_edit BIT, + IN a_id_currency INT, + IN a_id_region_purchase INT +) +BEGIN + -- Argument redeclaration + -- Variable declaration + DECLARE v_has_filter_user BIT; + DECLARE v_has_filter_permutation_basket BIT; + DECLARE v_has_filter_permutation_edit BIT; + DECLARE v_has_filter_region BIT; + DECLARE v_has_filter_currency BIT; + DECLARE v_n_id_permutation_basket INT; + DECLARE v_n_quantity_permutation_basket INT; + DECLARE v_row_number INT; + DECLARE v_guid VARCHAR(36); + # DECLARE v_id_user VARCHAR(100); + DECLARE v_id_permission_product INT; + DECLARE v_ids_permutation_permission VARCHAR(4000); + DECLARE v_now DATETIME; + # DECLARE v_quantity_new INT; + DECLARE v_change_set_used BIT; + DECLARE v_id_change_set INT; + + SET v_guid = UUID(); + + -- Argument validation + default values + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + IF a_ids_permutation_basket IS NULL THEN + SET a_ids_permutation_basket = ''; + ELSE + SET a_ids_permutation_basket = TRIM(a_ids_permutation_basket); + END IF; + IF a_quantities_permutation_basket IS NULL THEN + SET a_quantities_permutation_basket = ''; + ELSE + SET a_quantities_permutation_basket = TRIM(a_quantities_permutation_basket); + END IF; + IF a_sum_not_edit IS NULL THEN + SET a_sum_not_edit = 1; + END IF; + + -- Temporary tables + DROP TABLE IF EXISTS tmp_Msg_Error; + DROP TABLE IF EXISTS tmp_Shop_Basket; + DROP TEMPORARY TABLE IF EXISTS tmp_Shop_Quantity; + DROP TABLE IF EXISTS tmp_Shop_Product; + DROP TABLE IF EXISTS tmp_Shop_User; + + CREATE TABLE tmp_Shop_User ( + id_user VARCHAR(200) NOT NULL, + CONSTRAINT FK_tmp_Shop_User_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user), + active BIT NOT NULL + ); + + CREATE TABLE tmp_Shop_Product ( + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + display_order INT NOT NULL, + active INT NOT NULL DEFAULT 1 + ); + + CREATE TEMPORARY TABLE tmp_Shop_Quantity( + quantity INT NOT NULL, + display_order INT NOT NULL, + active INT NOT NULL DEFAULT 1 + ); + + CREATE TABLE tmp_Shop_Basket ( + id_category INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Basket_id_category + FOREIGN KEY (id_category) + REFERENCES Shop_Category(id_category), + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Basket_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Basket_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + id_region_purchase INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Basket_id_region_purchase + FOREIGN KEY (id_region_purchase) + REFERENCES Shop_Region(id_region), + id_currency INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Basket_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency), + quantity INT NOT NULL, + active BIT NOT NULL DEFAULT 1 + /* + display_order_category INT NOT NULL, + display_order_product INT NOT NULL + */ + ); + + CREATE TABLE IF NOT EXISTS tmp_Msg_Error ( + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + guid VARCHAR(36) NOT NULL, + id_type INT NOT NULL, + # code VARCHAR(50) NOT NULL, + # CONSTRAINT chk_tmp_Msg_Error_code CHECK (code IN (SELECT code FROM Shop_Msg_Error_Type)), + CONSTRAINT FK_tmp_Msg_Error_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Msg_Error_Type(id_type), + msg VARCHAR(4000) NOT NULL + ); + + + -- Parse filters + SET v_has_filter_user = NOT (a_id_user = ''); + SET v_has_filter_permutation_basket = NOT (a_ids_permutation_basket = ''); + SET v_has_filter_permutation_edit = NOT ISNULL(a_id_permutation_edit); + SET v_has_filter_currency = NOT ISNULL(a_id_currency); + SET v_has_filter_region = NOT ISNULL(a_id_region_purchase); + # SET v_quantity_new = CASE WHEN a_sum_not_edit THEN quantity + a_quantity_product_edit ELSE a_quantity_product_edit END; + /* + SELECT v_has_filter_user, v_has_filter_basket + ; + + */ + + -- Currency + IF NOT v_has_filter_currency THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + 'Currency ID not provided.' + ) + ; + END IF; + IF v_has_filter_currency AND NOT EXISTS ( SELECT * FROM Shop_Currency WHERE id_currency = a_id_currency) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('Currency ID not found: ', a_id_currency, '.') + ) + ; + END IF; + + -- Region + IF NOT v_has_filter_region THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + 'Region ID not provided.' + ) + ; + END IF; + IF v_has_filter_region AND NOT EXISTS ( SELECT * FROM Shop_Region WHERE id_region = a_id_region_purchase) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('Region ID not found: ', a_id_region_purchase, '.') + ) + ; + END IF; + + -- User + IF v_has_filter_user THEN + INSERT INTO tmp_Shop_User ( + id_user, + active + ) + SELECT id_user, + active + FROM Shop_User + WHERE id_user LIKE CONCAT('%', a_id_user, '%') + AND active + LIMIT 1 + ; + + IF NOT EXISTS (SELECT id_user FROM tmp_Shop_User LIMIT 1) THEN + SET v_has_filter_user = 0; + + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('User ID not found: ', a_id_user, '.') + ) + ; + END IF; + + SET a_id_user := (SELECT id_user FROM tmp_Shop_User LIMIT 1); + END IF; + + IF v_has_filter_user AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + SET v_change_set_used = 0; + INSERT INTO Shop_User_Change_Set ( + comment + ) + VALUES ( + 'edit basket' + ); + SET v_id_change_set := (SELECT id_change_set FROM Shop_User_Change_Set ORDER BY id_change_set DESC LIMIT 1); + END IF; + + -- Get basket + -- User + IF v_has_filter_user AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + INSERT INTO tmp_Shop_Basket ( + id_category, + id_product, + id_permutation, + id_region_purchase, + id_currency, + quantity, + active + /* + display_order_category, + display_order_product + */ + ) + SELECT + C.id_category, + UB.id_product, + UB.id_permutation, + UB.id_region_purchase, + UB.id_currency, + UB.quantity, + UB.active + /* + C.display_order, + P.display_order + */ + FROM Shop_User_Basket UB + /* + INNER JOIN tmp_Shop_User t_U + ON UB.id_user = t_U.id_user + */ + INNER JOIN Shop_Product_Permutation PP + ON UB.id_product = PP.id_product + AND PP.active + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + AND P.active + INNER JOIN Shop_Category C + ON P.id_category = C.id_category + AND C.active + WHERE UB.id_user = a_id_user + ; + END IF; + + -- Currency + IF EXISTS (SELECT * FROM tmp_Shop_Basket WHERE active LIMIT 1) + AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + IF EXISTS (SELECT * FROM tmp_Shop_Basket WHERE active AND id_currency != a_id_currency) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT( + 'Currency ID does not match currency of other items in basket. Basket currency: ', + (SELECT code FROM Shop_Currency WHERE id_currency = ( + SELECT + id_currency + FROM tmp_Shop_Basket + WHERE active + AND id_currency != a_id_currency + LIMIT 1 + )), + ', new currency: ', + (SELECT code FROM Shop_Currency WHERE id_currency = a_id_currency), + '.' + ) + ) + ; + END IF; + END IF; + + -- Region + IF EXISTS (SELECT * FROM tmp_Shop_Basket WHERE active LIMIT 1) + AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + IF EXISTS ( + SELECT * + FROM tmp_Shop_Basket + WHERE + active + AND id_region_purchase != a_id_region_purchase + ) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('Purchase region ID does not match region of other items in basket. Basket currency: ', + (SELECT code FROM Shop_Region WHERE id_region = ( + SELECT + id_region_purchase + FROM tmp_Shop_Basket + WHERE active + AND id_region != a_id_region_purchase + LIMIT 1 + )), + ', new currency: ', + (SELECT code FROM Shop_Region WHERE id_region = a_id_region_purchase), + '.' + ) + ) + ; + END IF; + END IF; + + -- String product id, permutation id, quantity list + IF NOT EXISTS (SELECT * FROM tmp_Shop_Basket WHERE active LIMIT 1) AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN -- NOT v_has_filter_user AND + # Get product ids + CALL p_split(a_ids_permutation_basket, ','); + INSERT INTO tmp_Shop_Product ( + id_product, id_permutation, display_order + ) + SELECT PP.id_product, ST.substring, ST.display_order + FROM Split_Temp ST + INNER JOIN Shop_Product_Permutation PP + ON ST.substring = PP.id_permutation + -- AND PP.active + ; + /* + SELECT substring as id_product, display_order + FROM Split_Temp + ; + */ + DROP TABLE Split_Temp; + + # Get product quantities + CALL p_split(a_quantities_permutation_basket, ','); + INSERT INTO tmp_Shop_Quantity ( + quantity, display_order + ) + SELECT substring, display_order + FROM Split_Temp + ; + /* + SELECT substring AS quantity_product, display_order + FROM Split_Temp + ; + */ + DROP TABLE Split_Temp; + + # Compare number of product ids to number of quantities + SET v_n_id_permutation_basket := (SELECT display_order FROM tmp_Shop_Product ORDER BY display_order DESC LIMIT 1); + SET v_n_quantity_permutation_basket := (SELECT display_order FROM tmp_Shop_Quantity ORDER BY display_order DESC LIMIT 1); + IF NOT v_n_id_permutation_basket = v_n_quantity_permutation_basket THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('Number of permutations (', v_n_id_permutation_basket, ') does not equal number of quantities (', v_n_quantity_permutation_basket, ') for basket.') + ) + ; + ELSE + INSERT INTO tmp_Shop_Basket ( + id_category, + id_product, + id_permutation, + id_region_purchase, + id_currency, + quantity + ) + SELECT + C.id_category, + P.id_product, + t_P.id_permutation, + a_id_region_purchase, + a_id_currency, + t_Q.quantity + FROM tmp_Shop_Product t_P + INNER JOIN tmp_Shop_Quantity t_Q + ON t_P.display_order = t_Q.display_order + INNER JOIN Shop_Product_Permutation PP + ON t_P.id_permutation = PP.id_permutation + AND PP.active + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + AND P.active + INNER JOIN Shop_Category C + ON P.id_category = C.id_category + AND C.active + -- RIGHT JOIN tmp_Shop_Basket t_UB ON ISNULL(t_UB.id_product) + -- WHERE t_P.id_product NOT IN (SELECT id_product FROM tmp_Shop_Basket) + ; + + /* + IF EXISTS( + SELECT * + FROM Shop_Product P + INNER JOIN Shop_Category C + ON P.id_category = C.id_category + INNER JOIN tmp_Shop_Basket t_B + ON P.id_product = t_B.id_product + WHERE C.active = 0 OR P.active = 0 LIMIT 1 + ) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('No valid product IDs in list: ', a_ids_permutation_basket, '.') + ) + ; + END IF; + */ + END IF; + END IF; + + /* + select v_has_filter_edit; + select * from tmp_Shop_Basket; + select * from tmp_Msg_Error; + */ + + + # Edit basket product + IF v_has_filter_permutation_edit AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + IF EXISTS ( + SELECT * + FROM Shop_Product_Permutation PP + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + INNER JOIN Shop_Category C + ON P.id_category = C.id_category + WHERE + ( + C.active = 0 + OR P.active = 0 + OR PP.active = 0 + ) + AND PP.id_permutation = a_id_permutation_edit + LIMIT 1 + ) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + CONCAT('Invalid product ID to edit: ', a_id_product_edit, '.') + ) + ; + END IF; + END IF; + IF v_has_filter_permutation_edit AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + IF EXISTS ( + SELECT * + FROM tmp_Shop_Basket + WHERE + id_permutation = a_id_permutation_edit + ) THEN + UPDATE tmp_Shop_Basket + SET quantity = CASE WHEN a_sum_not_edit = 1 THEN IFNULL(quantity, 0) + a_quantity_permutation_edit ELSE a_quantity_permutation_edit END, + active = CASE WHEN CASE WHEN a_sum_not_edit = 1 THEN IFNULL(quantity, 0) + a_quantity_permutation_edit ELSE a_quantity_permutation_edit END = 0 THEN 0 ELSE 1 END + WHERE id_permutation = a_id_permutation_edit + ; + + IF EXISTS ( + SELECT * + FROM tmp_Shop_Basket t_B + WHERE t_B.quantity < 0 + ) THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + 'Invalid basket quantity.' + ) + ; + END IF; + + IF v_has_filter_user AND NOT EXISTS (SELECT msg FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + SET v_change_set_used = 1; + + UPDATE Shop_User_Basket UB + INNER JOIN tmp_Shop_Basket t_UB + ON UB.id_permutation = a_id_permutation_edit + SET UB.quantity = t_UB.quantity, + UB.active = t_UB.active, + UB.id_change_set_user = v_id_change_set + WHERE UB.id_permutation = a_id_permutation_edit + AND id_user = a_id_user + ; + END IF; + ELSE + IF a_quantity_permutation_edit < 0 THEN + INSERT INTO tmp_Msg_Error ( + id_type, + guid, + msg + ) + VALUES ( + (SELECT id_type FROM Shop_Msg_Error_Type WHERE code = 'BAD_DATA' LIMIT 1), + v_guid, + 'Invalid basket quantity.' + ) + ; + ELSE + INSERT INTO tmp_Shop_Basket ( + id_category, + id_product, + id_permutation, + id_region_purchase, + id_currency, + quantity, + active + ) + SELECT + P.id_category, + P.id_product, + PP.id_permutation, + a_id_region_purchase, + a_id_currency, + a_quantity_permutation_edit, + CASE WHEN a_quantity_permutation_edit > 0 THEN 1 ELSE 0 END + FROM Shop_Product_Permutation PP + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + WHERE id_permutation = a_id_permutation_edit + ; + IF v_has_filter_user THEN + IF EXISTS ( + SELECT * + FROM Shop_User_Basket UB + WHERE + UB.id_permutation = a_id_permutation_edit + ) THEN + SET v_change_set_used = 1; + + UPDATE Shop_User_Basket + INNER JOIN tmp_Shop_Basket t_UB ON UB.id_permutation = t_UB.id_permutation + SET UB.quantity = t_UB.quantity, + UB.active = t_UB.active, + UB.id_change_set_user = v_id_change_set + WHERE UB.id_permutation = a_id_permutation_edit + AND id_user = a_id_user + ; + ELSE + INSERT INTO Shop_User_Basket ( + id_user, + id_product, + id_permutation, + id_region_purchase, + id_currency, + quantity, + active + ) + SELECT a_id_user, + t_UB.id_product, + t_UB.id_permutation, + t_UB.id_region_purchase, + t_UB.id_currency, + t_UB.quantity, + t_UB.active + FROM tmp_Shop_Basket t_UB + WHERE id_permutation = a_id_permutation_edit + ; + END IF; + END IF; + END IF; + END IF; + END IF; + + + -- Checks + /* + SELECT * FROM tmp_Shop_Basket; + SELECT + GROUP_CONCAT(t_UB.id_product SEPARATOR ',') AS basket_product_ids + FROM tmp_Shop_Basket t_UB + -- WHERE ISNULL(t_UB.id_permutation) + ; + SELECT + GROUP_CONCAT(t_UB.id_permutation SEPARATOR ',') AS basket_permutation_ids + FROM tmp_Shop_Basket t_UB + WHERE NOT ISNULL(t_UB.id_permutation) + ; + */ + -- Returns + CALL p_shop_get_many_product ( + a_id_user, # a_id_user + 1, # a_get_all_categories + '', # a_ids_category + 0, # a_get_inactive_categories + 0, # a_get_all_products + ( + SELECT + GROUP_CONCAT(t_B.id_product SEPARATOR ',') + FROM tmp_Shop_Basket t_B + WHERE active = 1 + ), # a_ids_product + 0, # a_get_inactive_products + 0, # a_get_first_product_only + 0, # a_get_all_product_permutations + ( + SELECT + GROUP_CONCAT(t_B.id_permutation SEPARATOR ',') + FROM tmp_Shop_Basket t_B + WHERE NOT ISNULL(t_B.id_permutation) + AND active = 1 + ), # a_ids_permutation + 0, # a_get_inactive_permutations + 0, # a_get_all_images + '', # a_ids_image + 0, # a_get_inactive_images + 1, # a_get_first_image_only + 0, # a_get_all_delivery_region + a_id_region_purchase, # a_ids_delivery_region + 0, # a_get_inactive_delivery_region + 0, # a_get_all_currency + a_id_currency, # a_ids_currency + 0, # a_get_inactive_currency + 1, # a_get_all_discount + '', # a_ids_discount + 0 # a_get_inactive_discount + ); + + # Basket + SELECT t_UB.id_category, + t_UB.id_product, + t_UB.id_permutation, + P.name, + PCL.price_local_VAT_incl, + PCL.price_local_VAT_excl, + PCL.id_currency, + t_UB.quantity + FROM tmp_Shop_Basket t_UB + INNER JOIN Shop_Product_Permutation PP + ON t_UB.id_permutation = PP.id_permutation + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + INNER JOIN Shop_Category C + ON P.id_category = C.id_category + INNER JOIN Shop_Product_Currency_Link PCL + ON PP.id_permutation = PCL.id_permutation + AND PCL.id_region_purchase = a_id_region_purchase + AND PCL.id_currency = a_id_currency + WHERE t_UB.active = 1 + ORDER BY C.display_order, P.display_order + ; + + # Errors + /* Completed by product get many */ + SELECT + t_ME.display_order, + t_ME.guid, + t_ME.id_type, + t_ME.msg, + MET.code, + MET.name, + MET.description + FROM tmp_Msg_Error t_ME + INNER JOIN Shop_Msg_Error_Type MET + ON t_ME.id_type = MET.id_type + WHERE GUID = v_guid + ; + + /* + # Return arguments for test + SELECT + a_ids_category, + a_get_inactive_categories, + a_ids_product, + a_get_inactive_products, + a_get_first_product_only, + a_get_all_products, + a_ids_image, + a_get_inactive_images, + a_get_first_image_only, + a_get_all_images + ; + */ + + -- Clean up + IF NOT v_change_set_used THEN + DELETE FROM Shop_User_Change_Set + WHERE id_change_set = v_id_change_set + ; + END IF; + + # DROP TABLE IF EXISTS tmp_Msg_Error; + DELETE FROM tmp_Msg_Error WHERE guid = v_guid; + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error) THEN + DROP TABLE tmp_Msg_Error; + END IF; + DROP TABLE IF EXISTS tmp_Shop_Basket; + DROP TEMPORARY TABLE IF EXISTS tmp_Shop_Quantity; + DROP TABLE IF EXISTS tmp_Shop_Product; + DROP TABLE IF EXISTS tmp_Shop_User; +END // +DELIMITER ; + + +/* + +CALL p_shop_edit_user_basket ( + '', # a_id_user + '', # a_ids_permutation_basket + '', # a_quantities_permutation_basket + 2, # a_id_permutation_edit + 1, # a_quantity_permutation_edit + 1, # a_sum_not_edit + 2, # a_id_currency_edit + 1 # a_id_region_purchase +); + +CALL p_shop_edit_user_basket ( + '', # a_id_user + '1', # a_ids_permutation_basket + '9', # a_quantities_permutation_basket + 1, # a_id_permutation_edit + 69, # a_quantity_permutation_edit + 1, # a_sum_not_edit + 1, # a_id_currency_edit + 1 # a_id_region_purchase +); +CALL p_shop_edit_user_basket ( + 'auth0|6582b95c895d09a70ba10feF', # a_id_user + '2', # a_ids_permutation_basket + '7', # a_quantities_permutation_basket + 2, # a_id_permutation_edit + NULL, # a_quantity_permutation_edit + 1, # a_sum_not_edit + 1, # a_id_currency_edit + 1 # a_id_region_purchase +); + + + {'a_id_user': 'auth0|6582b95c895d09a70ba10fef', + 'a_ids_permutation_basket': '1', + '7', # a_quantities_permutation_basket + 'a_id_permutation_edit': 1, + 'a_quantity_permutation_edit': 1, + 'a_sum_not_edit': 1} + + select * from shop_user_basket; + insert into shop_user_change_set (comment) + values( 'deactivate duplicates'); + update SHOP_USER_BASKET + set active = 0, + id_change_set_user = (select id_change_set from shop_user_change_set order by id_change_set desc limit 1) + where id_user = 'auth0|6582b95c895d09a70ba10fef' + and id_product = 1 + ; + select * from shop_user_basket; +*/ diff --git a/static/sql/703_p_shop_get_many_user_order.sql b/static/sql/703_p_shop_get_many_user_order.sql new file mode 100644 index 00000000..b9ba34ba --- /dev/null +++ b/static/sql/703_p_shop_get_many_user_order.sql @@ -0,0 +1,285 @@ + +USE PARTS; + +/* + +CALL p_shop_get_many_user_order ( + '', + '', + 1, + '' +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_many_user_order; + + +DELIMITER // +CREATE PROCEDURE p_shop_get_many_user_order ( + IN a_id_user VARCHAR(200), + IN a_ids_order VARCHAR(4000), + IN a_n_order_max INT, + IN a_id_checkout_session VARCHAR(200) +) +BEGIN + -- Argument redeclaration + -- Variable declaration + DECLARE v_has_filter_user BIT; + DECLARE v_has_filter_order BIT; + DECLARE v_has_filter_session BIT; + DECLARE v_code_error_data VARCHAR(200); + DECLARE v_code_error_permission VARCHAR(200); + DECLARE v_guid VARCHAR(36); + + SET v_code_error_data := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 1); + SET v_code_error_permission := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 2); + SET v_guid = UUID(); + + -- Argument validation + default values + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + IF a_ids_order IS NULL THEN + SET a_ids_order = ''; + ELSE + SET a_ids_order = TRIM(a_ids_order); + END IF; + IF a_n_order_max IS NULL THEN + SET a_n_order_max = 1; + END IF; + IF a_id_checkout_session IS NULL THEN + SET a_id_checkout_session = ''; + ELSE + SET a_id_checkout_session = TRIM(a_id_checkout_session); + END IF; + + + + -- Temporary tables + DROP TABLE IF EXISTS tmp_Shop_User; + DROP TABLE IF EXISTS tmp_Shop_Order; + + CREATE TABLE tmp_Shop_User( + id_user VARCHAR(200) NOT NULL PRIMARY KEY, + CONSTRAINT FK_tmp_Shop_User_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user), + active BIT NOT NULL + ); + + CREATE TABLE tmp_Shop_Order ( + id_order INT NOT NULL PRIMARY KEY, + CONSTRAINT FK_tmp_Shop_Order_id_order + FOREIGN KEY (id_order) + REFERENCES Shop_User_Order(id_order), + active BIT NOT NULL + ); + + CREATE TABLE IF NOT EXISTS tmp_Msg_Error ( + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + guid VARCHAR(36) NOT NULL, + # id_type INT NOT NULL, + # CONSTRAINT FK_tmp_Msg_Error_id_type FOREIGN KEY (id_type) + # REFERENCES Shop_Msg_Error_Type (id_type), + code VARCHAR(50), + msg VARCHAR(4000) NOT NULL + ); + + + -- Parse filters + SET v_has_filter_user = CASE WHEN a_id_user = '' THEN 0 ELSE 1 END; + SET a_ids_order = REPLACE(a_ids_order, '|', ','); + SET v_has_filter_order = CASE WHEN a_ids_order = '' THEN 0 ELSE 1 END; + SET v_has_filter_session = CASE WHEN a_id_checkout_session = '' THEN 0 ELSE 1 END; + + -- User + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error LIMIT 1) THEN + IF v_has_filter_user THEN + INSERT INTO tmp_Shop_User ( + id_user, + active + ) + SELECT id_user, + active + FROM Shop_User + WHERE id_user LIKE CONCAT('%', a_id_user, '%') + AND active + LIMIT 1 + ; + + SET v_has_filter_user = EXISTS (SELECT id_user FROM tmp_Shop_User LIMIT 1); + SET a_id_user := (SELECT id_user FROM tmp_Shop_User LIMIT 1); + END IF; + END IF; + IF NOT v_has_filter_user THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_data, + 'User ID not valid.' + ) + ; + END IF; + + -- Permissions + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + CALL p_shop_user_eval ( + v_guid, # a_guid + a_id_user, # a_id_user + 0, # a_get_inactive_users + CONVERT((SELECT id_permission FROM Shop_Permission WHERE 'STORE_USER' = code), CHAR), # a_ids_permission + (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'VIEW' AND active), # a_ids_access_level + '', # a_ids_product + '' # a_ids_permutation + ); + + IF NOT (SELECT can_edit FROM Shop_User_Eval_Temp WHERE guid = v_guid) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_permission, + 'User ID does not have permission to access orders.' + ) + ; + END IF; + + DELETE FROM Shop_User_Eval_Temp + WHERE guid = v_guid + ; + END IF; + + -- Invalid Orders + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + # Invalid Order IDs + IF EXISTS (SELECT * FROM Shop_User_Order WHERE NOT (id_user = a_id_user) AND v_has_filter_order AND FIND_IN_SET(id_order, a_ids_order) > 0) THEN # id_order LIKE CONCAT('%', a_ids_order, '%') LIMIT 1) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_data, + CONCAT('You do not have access to the following order IDs: ', (SELECT GROUP_CONCAT(id_order SEPARATOR ', ') FROM Shop_User_Order WHERE NOT (id_user = a_id_user) AND FIND_IN_SET(id_order, a_ids_order) > 0)) # id_order LIKE CONCAT('%', a_ids_order, '%'))) # AND v_has_filter_order # filtered by parent condition + ) + ; + END IF; + # Invalid Checkout Session IDs + IF EXISTS (SELECT * FROM Shop_User_Order WHERE NOT (id_user = a_id_user) AND v_has_filter_session AND id_checkout_session = a_id_checkout_session) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_data, + CONCAT('You do not have access to the following checkout session IDs: ', (SELECT GROUP_CONCAT(id_order SEPARATOR ', ') FROM Shop_User_Order WHERE NOT (id_user = a_id_user) AND id_checkout_session = a_id_checkout_session)) # AND v_has_filter_order # filtered by parent condition + ) + ; + END IF; + END IF; + + -- Valid Orders + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + + INSERT INTO tmp_Shop_Order ( + id_order, + active + ) + SELECT UO.id_order, + UO.active + FROM Shop_User_Order UO + INNER JOIN tmp_Shop_User t_U + ON UO.id_user = t_U.id_user + AND t_U.active + WHERE ((NOT v_has_filter_order OR FIND_IN_SET(UO.id_order, a_ids_order) > 0) # UO.id_order LIKE CONCAT('%', a_ids_order, '%')) + OR (NOT v_has_filter_session OR UO.id_checkout_session = a_id_checkout_session)) + AND UO.active + ; + END IF; + + + + -- Returns + /* + SELECT * + FROM tmp_Shop_User + ; + */ + + SELECT t_O.id_order, + UOPL.id_product, + UOPL.id_permutation, + UOPL.quantity + FROM tmp_Shop_Order t_O + INNER JOIN Shop_User_Order UO + ON t_O.id_order = UO.id_order + INNER JOIN Shop_User_Order_Product_Link UOPL + ON UO.id_order = UOPL.id_order + WHERE t_O.active + ; + + + # Errors + SELECT * + FROM tmp_Msg_Error + WHERE guid = v_guid + ; + + + /* + # Return arguments for test + SELECT + a_id_user, + a_ids_order, + a_n_order_max, + a_id_checkout_session + ; + */ + + -- Clean up + DROP TABLE IF EXISTS tmp_Shop_User; + DROP TABLE IF EXISTS tmp_Shop_Order; +END // +DELIMITER ; + + +/* + +CALL p_shop_get_many_user_order ( + 'auth0|6582b95c895d09a70ba10fef', + '1', + 0, + '' +); + +CALL p_shop_get_many_user_order ( + '', + '1', + 0, + '' +); + +insert into shop_product_change_set (comment) + values ('set product not subscription - test bool output to python'); + update shop_product + set is_subscription = 0, + id_change_set = (select id_change_set from shop_product_change_set order by id_change_set desc limit 1) + where id_product = 1 +select * from shop_User; +select * from shop_User_oRDER; +*/ diff --git a/static/sql/704_p_shop_get_many_stripe_product_new.sql b/static/sql/704_p_shop_get_many_stripe_product_new.sql new file mode 100644 index 00000000..c1adf3b5 --- /dev/null +++ b/static/sql/704_p_shop_get_many_stripe_product_new.sql @@ -0,0 +1,307 @@ + +USE PARTS; + +/* + +CALL p_shop_get_many_stripe_product_new ( + '' +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_many_stripe_product_new; + + +DELIMITER // +CREATE PROCEDURE p_shop_get_many_stripe_product_new ( + IN a_id_user VARCHAR(200) +) +BEGIN + DECLARE v_has_filter_user BIT; + DECLARE v_code_error_data VARCHAR(200); + DECLARE v_code_error_permission VARCHAR(200); + DECLARE v_guid VARCHAR(36); + + SET v_code_error_data := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 1); + SET v_code_error_permission := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 2); + SET v_guid = UUID(); + + + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + + + + -- Temporary tables + DROP TABLE IF EXISTS tmp_Shop_Product; + DROP TABLE IF EXISTS tmp_Shop_User; + + CREATE TABLE tmp_Shop_User( + id_user VARCHAR(200) NOT NULL PRIMARY KEY, + CONSTRAINT FK_tmp_Shop_User_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user), + active BIT NOT NULL + ); + + CREATE TABLE tmp_Shop_Product ( + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + active BIT NOT NULL, + display_order_product INT NOT NULL, + display_order_permutation INT NOT NULL, + name VARCHAR(200) NOT NULL, + description VARCHAR(4000) NOT NULL + ); + + CREATE TABLE IF NOT EXISTS tmp_Msg_Error ( # IF NOT EXISTS + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + guid VARCHAR(36) NOT NULL, + code VARCHAR(50) NOT NULL, + # CONSTRAINT chk_tmp_Msg_Error_code CHECK (code IN (SELECT code FROM Shop_Msg_Error_Type)), + /* + id_type INT NOT NULL, + CONSTRAINT FK_tmp_Msg_Error_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Msg_Error_Type(id_type), + */ + msg VARCHAR(4000) NOT NULL + ); + + + + -- Parse filters + SET v_has_filter_user = CASE WHEN a_id_user = '' THEN 0 ELSE 1 END; + + + + -- User + IF v_has_filter_user THEN + INSERT INTO tmp_Shop_User ( + id_user, + active + ) + SELECT id_user, + active + FROM Shop_User + WHERE id_user LIKE CONCAT('%', a_id_user, '%') + AND active + LIMIT 1 + ; + + SET v_has_filter_user = EXISTS (SELECT id_user FROM tmp_Shop_User LIMIT 1); + SET a_id_user := (SELECT id_user FROM tmp_Shop_User LIMIT 1); + END IF; + + IF NOT v_has_filter_user THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_data, + 'User ID not valid.' + ) + ; + END IF; + + -- Get products + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + INSERT INTO tmp_Shop_Product ( + id_product, + id_permutation, + active, + display_order_product, + display_order_permutation, + name, + description + ) + SELECT id_product, + id_permutation, + active, + display_order_product, + display_order_permutation, + name, + description + FROM ( + SELECT id_product, + NULL AS id_permutation, + active, + display_order AS display_order_product, + NULL AS display_order_permutation, + name, + description, + id_stripe_product + FROM Shop_Product P + UNION + SELECT t_PPPV.id_product, + id_permutation, + t_PPPV.active, + display_order_product, + display_order_permutation, + CONCAT(P.name, ': ', names_variation) AS name, + CONCAT(P.description, ' With variations: ', type_name_pairs_variation) AS description, + t_PPPV.id_stripe_product + FROM ( + SELECT P.id_product, + PP.id_permutation, + PP.active, + P.display_order AS display_order_product, + PP.display_order AS display_order_permutation, + GROUP_CONCAT(V.name SEPARATOR ' ') AS names_variation, + GROUP_CONCAT(CONCAT(VT.name, ': ', V.name) SEPARATOR ', ') AS type_name_pairs_variation, + PP.id_stripe_product + FROM Shop_Product_Permutation PP + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + AND P.active + INNER JOIN Shop_Product_Permutation_Variation_Link PPVL + ON PP.id_permutation = PPVL.id_permutation + AND PPVL.active + INNER JOIN Shop_Variation V + ON PPVL.id_variation = V.id_variation + AND V.active + INNER JOIN Shop_Variation_Type VT + ON V.id_type = VT.id_type + AND VT.active + GROUP BY id_product, id_permutation -- , VT.id_type, V.id_variation + ) t_PPPV + INNER JOIN Shop_Product P + ON t_PPPV.id_product = P.id_product + ) t_PPP + WHERE ISNULL(id_stripe_product) + AND active + ; + END IF; + + -- Permissions + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + CALL p_shop_user_eval ( + v_guid, # a_guid + a_id_user, # a_id_user + 0, # a_get_inactive_users + CONVERT((SELECT id_permission FROM Shop_Permission WHERE 'STORE_ADMIN' = code), CHAR), # a_ids_permission + (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'ADMIN' AND active), # a_ids_access_level + (SELECT GROUP_CONCAT(id_product SEPARATOR ',') From tmp_Shop_Product), # a_ids_product + (SELECT GROUP_CONCAT(id_permutation SEPARATOR ',') From tmp_Shop_Product) # a_ids_permutation -- WHERE NOT ISNULL(id_permutation) + ); + + IF EXISTS (SELECT can_admin FROM Shop_User_Eval_Temp WHERE guid = v_guid AND NOT can_admin) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_permission, + 'User ID does not have permission to get all new stripe products.' + ) + ; + END IF; + + DELETE FROM Shop_User_Eval_Temp + WHERE guid = v_guid + ; + END IF; + + + + + -- Returns + /* + SELECT * + FROM tmp_Shop_User + ; + */ + + IF EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + DELETE FROM tmp_Shop_Product; + END IF; + + SELECT id_product, + id_permutation, + name, + description + FROM tmp_Shop_Product + ORDER BY display_order_product, display_order_permutation + ; + SELECT PP.id_permutation, + V.id_variation, + V.name AS name_variation, + VT.id_type AS id_type_variation, + VT.name as name_variation_type + FROM tmp_Shop_Product t_P + INNER JOIN Shop_Product_Permutation PP + ON t_P.id_permutation = PP.id_permutation + INNER JOIN Shop_Product_Permutation_Variation_Link PPVL + ON PP.id_permutation = PPVL.id_permutation + AND PPVL.active + INNER JOIN Shop_Variation V + ON PPVL.id_variation = V.id_variation + AND V.active + INNER JOIN Shop_Variation_Type VT + ON V.id_type = VT.id_type + AND VT.active + ; + + + # Errors + SELECT * + FROM tmp_Msg_Error + WHERE guid = v_guid + ; + + + /* + # Return arguments for test + SELECT + a_id_user + ; + */ + + -- Clean up + DROP TABLE IF EXISTS tmp_Shop_Product; + DROP TABLE IF EXISTS tmp_Shop_User; +END // +DELIMITER ; + + +/* +CALL p_shop_get_many_stripe_product_new ( + '' +); + +CALL p_shop_get_many_stripe_product_new ( + 'auth0|6582b95c895d09a70ba10fef' +); + + + +select * from shop_product; +select * from shop_product_permutation_variation_link; + +CALL p_shop_user_eval ( + 'ead789a1-c7ac-11ee-a256-b42e9986184a', # a_guid + 'auth0|6582b95c895d09a70ba10fef', # a_id_user + 0, # a_get_inactive_users + '4', # a_ids_permission + '3', # a_ids_access_level + '1', # a_ids_product + '1' # a_ids_permutation -- WHERE NOT ISNULL(id_permutation) + ); + +*/ diff --git a/static/sql/705_p_shop_get_many_stripe_price_new.sql b/static/sql/705_p_shop_get_many_stripe_price_new.sql new file mode 100644 index 00000000..4bca254e --- /dev/null +++ b/static/sql/705_p_shop_get_many_stripe_price_new.sql @@ -0,0 +1,243 @@ + +USE PARTS; + +/* + +CALL p_shop_get_many_stripe_price_new ( + '' +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_many_stripe_price_new; + + +DELIMITER // +CREATE PROCEDURE p_shop_get_many_stripe_price_new ( + IN a_id_user VARCHAR(200) +) +BEGIN + DECLARE v_has_filter_user BIT; + DECLARE v_code_error_data VARCHAR(200); + DECLARE v_code_error_permission VARCHAR(200); + DECLARE v_guid VARCHAR(36); + + SET v_code_error_data := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 1); + SET v_code_error_permission := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 2); + SET v_guid = UUID(); + + + + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + + + + -- Temporary tables + DROP TABLE IF EXISTS tmp_Shop_Product_Currency_Link; + DROP TABLE IF EXISTS tmp_Shop_User; + + CREATE TABLE tmp_Shop_User( + id_user VARCHAR(200) NOT NULL PRIMARY KEY, + CONSTRAINT FK_tmp_Shop_User_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user), + active BIT NOT NULL + ); + + CREATE TABLE tmp_Shop_Product_Currency_Link ( + id_link INT NOT NULL PRIMARY KEY, + CONSTRAINT FK_tmp_Shop_Product_Currency_Link_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Currency_Link(id_link), + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_Currency_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NULL, + CONSTRAINT FK_tmp_Shop_Product_Currency_Link_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + id_currency INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_Currency_Link_id_currency + FOREIGN KEY (id_currency) + REFERENCES Shop_Currency(id_currency), + active BIT NOT NULL + ); + + CREATE TABLE IF NOT EXISTS tmp_Msg_Error ( # IF NOT EXISTS + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + guid VARCHAR(36) NOT NULL, + code VARCHAR(50) NOT NULL, + # CONSTRAINT chk_tmp_Msg_Error_code CHECK (code IN (SELECT code FROM Shop_Msg_Error_Type)), + /* + id_type INT NOT NULL, + CONSTRAINT FK_tmp_Msg_Error_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Msg_Error_Type(id_type), + */ + msg VARCHAR(4000) NOT NULL + ); + + + + -- Parse filters + SET v_has_filter_user = CASE WHEN a_id_user = '' THEN 0 ELSE 1 END; + + + + -- User permissions + IF v_has_filter_user THEN + INSERT INTO tmp_Shop_User ( + id_user, + active + ) + SELECT id_user, + active + FROM Shop_User + WHERE id_user LIKE CONCAT('%', a_id_user, '%') + AND active + LIMIT 1 + ; + + SET v_has_filter_user = EXISTS (SELECT id_user FROM tmp_Shop_User LIMIT 1); + SET a_id_user := (SELECT id_user FROM tmp_Shop_User LIMIT 1); + END IF; + IF NOT v_has_filter_user THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_data, + 'Valid user ID not provided.' + ) + ; + END IF; + + -- Get products + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + INSERT INTO tmp_Shop_Product_Currency_Link ( + id_link, + id_product, + id_permutation, + id_currency, + active + ) + SELECT id_link, + id_product, + id_permutation, + id_currency, + active + FROM Shop_Product_Currency_Link + WHERE ISNULL(id_stripe_price) + AND active + ; + END IF; + + -- Permissions + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + # SELECT * FROM tmp_Msg_Error LIMIT 1; + CALL p_shop_user_eval ( + v_guid, # a_guid + a_id_user, # a_id_user + 0, # a_get_inactive_users + CONVERT((SELECT id_permission FROM Shop_Permission WHERE 'STORE_ADMIN' = code), CHAR), # a_ids_permission + (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'ADMIN' AND active), # a_ids_access_level + (SELECT GROUP_CONCAT(DISTINCT id_product SEPARATOR ',') FROM tmp_Shop_Product_Currency_Link), # (SELECT DISTINCT id_product FROM tmp_Shop_Product_Currency_Link) calc_PCL) # a_ids_product + (SELECT GROUP_CONCAT(DISTINCT id_permutation SEPARATOR ',') FROM tmp_Shop_Product_Currency_Link) # a_ids_permutation + ); + # SELECT * FROM tmp_Msg_Error LIMIT 1; + + IF EXISTS (SELECT can_admin FROM Shop_User_Eval_Temp WHERE guid = v_guid AND NOT can_admin LIMIT 1) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_permission, + 'User ID does not have permission to get all new stripe prices.' + ) + ; + END IF; + + DELETE FROM Shop_User_Eval_Temp + WHERE guid = v_guid + ; + END IF; + + + + -- Returns + IF EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid LIMIT 1) THEN + DELETE FROM tmp_Shop_Product_Currency_Link; + END IF; + /* + SELECT * + FROM tmp_Shop_User + ; + */ + + + SELECT t_PCL.id_product, + t_PCL.id_permutation, + P.price_GBP_full * C.factor_from_GBP AS unit_price, + C.code AS code_currency, + P.id_stripe_product, + P.is_subscription, + LOWER(RI.code) AS name_recurring_interval, + P.count_recurrence_interval + FROM tmp_Shop_Product_Currency_Link t_PCL + INNER JOIN Shop_Product P + ON t_PCL.id_product = P.id_product + AND P.active + INNER JOIN Shop_Recurrence_Interval RI + ON P.id_recurrence_interval = RI.id_interval + AND RI.active + INNER JOIN Shop_Currency C + ON t_PCL.id_currency = C.id_currency + AND C.active + WHERE t_PCL.active + ; + + + # Errors + SELECT * + FROM tmp_Msg_Error + WHERE guid = v_guid + ; + + + /* + # Return arguments for test + SELECT + a_id_user + ; + */ + + -- Clean up + DROP TABLE IF EXISTS tmp_Shop_User; + DROP TABLE IF EXISTS tmp_Shop_Product_Currency_Link; +END // +DELIMITER ; + + +/* +CALL p_shop_get_many_stripe_price_new ( + '' +); + +CALL p_shop_get_many_stripe_price_new ( + 'auth0|6582b95c895d09a70ba10fef' +); + +*/ diff --git a/static/sql/900_populate.sql b/static/sql/900_populate.sql new file mode 100644 index 00000000..2e1db709 --- /dev/null +++ b/static/sql/900_populate.sql @@ -0,0 +1,553 @@ + +USE PARTS; + +/* + +CALL p_populate_database () + +*/ + +/* +-- Remove previous proc +DROP PROCEDURE IF EXISTS p_populate_database; + + +DELIMITER // +CREATE PROCEDURE p_populate_database () +BEGIN +*/ + + +# Access Levels +INSERT INTO Shop_Access_Level ( + display_order, code, name, priority +) +VALUES + (1, 'VIEW', 'View', 3), + (2, 'EDIT', 'Edit', 2), + (3, 'ADMIN', 'Admin', 1) +; + +# Error Message Types +INSERT INTO Shop_Msg_Error_Type ( + code, name, description +) +VALUES + ('BAD_DATA', 'Invalid data', 'Rubbish data'), + ('NO_PERMISSION', 'No permission', 'Not authorised'), + ('PRODUCT_AVAILABILITY', 'Product not available', 'Product not available') +; + +# File Types +INSERT INTO File_Type ( + code, name, extension +) +VALUES + ('JPEG', 'Joint Photographic Export Group', 'jpg'), + ('PNG', 'Portable Network Graphic', 'png'), + ('GIF', 'GIF', 'gif'), + ('MPEG-4', 'Multimedia Photographic Export Group 4', 'mp4') +; + +# Generic / shared properties +INSERT INTO Shop_General ( + quantity_max +) +VALUES ( + 10 +); + +# Categories +INSERT INTO Shop_Category ( + display_order, + code, + name, + description +) +VALUES + (1, 'ASS', 'Assistive Devices', 'Braille product line and other assistive devices'), + (99, 'MISC', 'Miscellaneous', 'Not category allocated products'), + (2, 'TECH', 'Technology', 'Technological devices') +; + +# Recurrence Interval +INSERT INTO Shop_Recurrence_Interval ( + code, name, name_plural +) +VALUES + ('WEEK', 'Week', 'Weeks'), + ('MONTH', 'Month', 'Months'), + ('YEAR', 'Year', 'Years') +; + +INSERT INTO Shop_Region ( + display_order, code, name +) +VALUES + (1, 'UK', 'United Kingdom') +; + +/* +INSERT INTO Shop_Region_Branch ( + display_order, id_region_parent, id_region_child +) +VALUES + (1, 1, 2) +; +*/ + +# Currency +INSERT INTO Shop_Currency ( + display_order, code, name, symbol, factor_from_GBP +) +VALUES + (1, 'GBP', 'Great British Pound', '£', 1), + (2, 'EUR', 'Euro', '€', 1.17) +; + +# Taxes and Surcharges +INSERT INTO Shop_Tax_Or_Surcharge ( + display_order, + id_tax, + code, + name, + id_region_buyer, + id_region_seller, + fixed_fee, + multiplier, + apply_fixed_fee_before_multiplier, + quantity_min, + quantity_max +) +VALUES + (1, 1, 'VAT', 'Value Added Tax', 1, 1, 0, 0.2, 1, 0, 1) +; + +# Products +INSERT INTO Shop_Product ( + display_order, + id_category, + name, + has_variations, + id_access_level_required +) +VALUES + ( + 1, + 1, + 'Braille Keyboard Translator', + 1, + 3 + ), + ( + 2, + 2, + 'Test product 1', + 0, + 3 + ), + ( + 3, + 3, + 'Phone', + 0, + 1 + ), + ( + 4, + 3, + 'Laptop', + 0, + 1 + ), + ( + 5, + 3, + 'Smart Watch', + 0, + 1 + ) +; + +# Variation Types +INSERT INTO Shop_Variation_Type ( + display_order, code, name, name_plural +) +VALUES + (1, 'COLOUR', 'Colour', 'Colours') +; + +# Variations +INSERT INTO Shop_Variation ( + display_order, id_type, code, name +) +VALUES + (1, 1, 'RED', 'Red'), + (2, 1, 'BLUE', 'Blue') +; + +# Product Permutations +INSERT INTO Shop_Product_Permutation ( + display_order, + id_product, + description, + cost_local_manufacturing, + id_currency_cost_manufacturing, + profit_local_min, + id_currency_profit_min, + latency_manufacture, + quantity_min, + quantity_max, + quantity_step, + quantity_stock, + is_subscription, + id_recurrence_interval, + count_recurrence_interval, + id_access_level_required, + id_stripe_product +) +VALUES + ( + 1, + 1, + 'Good Red', + 5, + 1, + 3, + 1, + 14, + 1, + 3, + 1, + 99, + 0, + NULL, + NULL, + 1, + NULL + ), + ( + 2, + 1, + 'Good Blue', + 6, + 1, + 4, + 1, + 14, + 1, + 3, + 1, + 99, + 0, + NULL, + NULL, + 1, + NULL + ), + ( + 3, + 2, + 'Test product describes good', + 10, + 1, + 5, + 1, + 14, + 1, + 2, + 1, + 99, + 0, + NULL, + NULL, + 1, + NULL + ), + ( + 4, + 3, + 'Phone describes good', + 10, + 1, + 5, + 1, + 14, + 1, + 2, + 1, + 99, + 0, + NULL, + NULL, + 1, + NULL + ), + ( + 5, + 4, + 'Laptop describes good', + 10, + 1, + 5, + 1, + 14, + 1, + 2, + 1, + 99, + 0, + NULL, + NULL, + 1, + NULL + ), + ( + 6, + 5, + 'Smart watch describes good', + 10, + 1, + 5, + 1, + 14, + 1, + 2, + 1, + 99, + 0, + NULL, + NULL, + 1, + NULL + ) +; + +# Product Permutation Variation Links +INSERT INTO Shop_Product_Permutation_Variation_Link ( + display_order, id_permutation, id_variation +) +VALUES + (1, 1, 1), + (2, 2, 2) +; + +# Product Currency Link +INSERT INTO Shop_Product_Currency_Region_Link ( + id_product, id_permutation, id_currency, id_region_purchase, price_local_VAT_incl, price_local_VAT_excl +) +VALUES + (1, 1, 1, 1, 24, 20), + (1, 1, 2, 1, 48, 40), + (1, 2, 1, 1, 96, 80), + (2, 3, 1, 1, 144, 120), + (3, 4, 1, 1, 600, 500), + (4, 5, 1, 1, 1500, 1200), + (5, 6, 1, 1, 180, 150) +; + +INSERT INTO Shop_Image_Type ( + display_order, code, name, name_plural +) +VALUES + (1, 'FULL', 'Full Quality Image', 'Full Quality Images'), + (2, 'LOW', 'Low Quality Image', 'Low Quality Images'), + (3, 'THUMBNAIL', 'Thumbnail Image', 'Thumbnail Images') +; + +INSERT INTO Shop_Image ( + display_order, id_product, id_permutation, id_type_image, id_type_file, url +) +VALUES + (1, 1, 1, 1, 1, '/static/images/prod_PB0NUOSEs06ymG.jpg'), + # (1, NULL, 1, 1, 1, '/static/images/prod_PB0NUOSEs06ymG.jpg'), + (2, 1, 2, 1, 1, '/static/images/prod_PB0NUOSEs06ymG.jpg'), + # (1, NULL, 2, 1, 1, '/static/images/prod_PB0NUOSEs06ymG.jpg') + (3, 2, 3, 1, 1, '/static/images/prod_PB0NUOSEs06ymG.jpg'), + (4, 3, 4, 1, 1, '/static/images/prod_.jpg'), + (5, 4, 5, 1, 1, '/static/images/prod_1.jpg'), + (6, 5, 6, 1, 1, '/static/images/prod_2.jpg') +; + +INSERT INTO Shop_Delivery_Option ( + display_order, code, name, latency_delivery_min, latency_delivery_max, quantity_min, quantity_max +) +VALUES + (1, 'COLLECT', 'Collection', 0, 0, 0, 1), + (2, 'SIGNED_1', 'First Class Signed-For', 2, 4, 0, 1) +; + +INSERT INTO Shop_Product_Delivery_Option_Link ( + display_order, id_product, id_permutation, id_delivery_option, id_region, id_currency, price_local +) +VALUES + (1, 1, 1, 1, 1, 1, 5), + (2, 1, 2, 1, 1, 1, 9), + (3, 2, NULL, 1, 1, 1, 10), + (4, 3, 4, 1, 1, 1, 10), + (5, 4, 5, 1, 1, 1, 10), + (6, 5, 6, 1, 1, 1, 10) +; + +# Discounts +INSERT INTO Shop_Discount ( + id_product, + id_permutation, + code, + name, + multiplier, + quantity_min, + quantity_max, + date_start, + date_end, + display_order +) +VALUES + (1, 1, 'CRIMBO50', 'Christmas 50% off sale!', 0.5, 3, 9, NOW(), '2023-12-31 23:59:59', 1), + (1, 2, 'CRIMBO50', 'Christmas 50% off sale!', 0.5, 3, 9, NOW(), '2023-12-31 23:59:59', 1) +; + +# Discount Delivery Region Links +INSERT INTO Shop_Discount_Region_Currency_Link ( + id_discount, + id_region, + id_currency +) +VALUES + (1, 1, 1), + (2, 1, 1), + (1, 1, 2), + (2, 1, 2) +; + +# Permission Groups +INSERT INTO Shop_Permission_Group ( + display_order, code, name +) +VALUES + (0, 'ADMIN', 'Website Admin'), + (1, 'HOME', 'Home, Contact Us, and other public information'), + (2, 'PRODUCT', 'Store Products'), + (3, 'USER', 'Store User') +; + +# Permissions +INSERT INTO Shop_Permission ( + display_order, code, name, id_permission_group, id_access_level_required +) +VALUES + (1, 'HOME', 'Home Page', 2, 1), + (2, 'STORE_PRODUCT', 'Store Product Page', 3, 1), + (3, 'STORE_USER', 'Store User Account Page', 4, 2), + (4, 'STORE_ADMIN', 'Store Admin Page', 1, 3), + (99, 'CONTACT_US', 'Contact Us Page', 2, 1) +; + +# Roles +INSERT INTO Shop_Role ( + display_order, + code, + name +) +VALUES + (1, 'DIRECTOR', 'Director'), + (2, 'USER', 'User') +; + +# Role Permission link +INSERT INTO Shop_Role_Permission_Link ( + id_role, id_permission, id_access_level +) +VALUES + (1, 1, 3), + (1, 2, 3), + (1, 3, 3), + (1, 4, 3), + (1, 5, 3), + (2, 1, 1), + (2, 2, 1), + (2, 3, 1), + (2, 4, 1), + (2, 5, 1) +; + +# Users +INSERT INTO Shop_User ( + id_user, + name, + email, + # email_verified, + is_super_user +) +VALUES + ('auth0|6582b95c895d09a70ba10fef', 'Teddy', 'edward.middletonsmith@gmail.com', 1), + ('parts_guest', 'Guest', '', 0) +; + +# User Role link +INSERT INTO Shop_User_Role_Link ( + id_user, id_role +) +VALUES + ('auth0|6582b95c895d09a70ba10fef', 1) +; + +# Addresses +INSERT INTO Shop_Address ( + id_user, id_region, name_full, phone_number, postcode, address_line_1, address_line_2, city, county +) +SELECT U.id_user, 1, U.name, '07375 571430', 'NN6 6EB', 'The Laurels', 'Cold Ashby Road', 'Cold Ashby', 'Northamptonshire' + FROM Shop_User U +; + +# User Basket +INSERT INTO Shop_User_Basket ( + id_user, + id_product, + id_permutation, + quantity +) +VALUES + ('auth0|6582b95c895d09a70ba10fef', 1, 1, 69) +; + +# User Order Status +INSERT INTO Shop_User_Order_Status ( + display_order, code, name, name_plural +) +VALUES + (1, 'SUCCESS', 'Success', 'Successes'), + (2, 'FAIL', 'Failure', 'Failures') +; + +# User Order +INSERT INTO Shop_User_Order ( + id_user, value_total, id_order_status, id_checkout_session, id_currency +) +VALUES + ('auth0|6582b95c895d09a70ba10fef', 25, 1, 'noods', 1), + ('auth0|6582b95c895d09a70ba10fef', 25, 1, 'noods', 1) +; + +# User Order Product Link +INSERT INTO Shop_User_Order_Product_Link ( + id_order, id_product, id_permutation, quantity +) +VALUES + (1, 1, 1, 69), + (1, 2, NULL, 69), + (1, 1, 2, 69) +; + +/* + -- Clean up +END // +DELIMITER ; + + +-- Call +CALL p_populate_database(); + +-- Remove proc +DROP PROCEDURE IF EXISTS p_populate_database; +*/ \ No newline at end of file diff --git a/static/sql/901_view.sql b/static/sql/901_view.sql new file mode 100644 index 00000000..faedf80a --- /dev/null +++ b/static/sql/901_view.sql @@ -0,0 +1,141 @@ + +USE PARTS; + +# Product Change Sets +SELECT * FROM Shop_Product_Change_Set; + +# User Change Sets +SELECT * FROM Shop_User_Change_Set; + +# Access Levels +SELECT * FROM Shop_Access_Level; +SELECT * FROM Shop_Access_Level_Audit; + +# Error Message type +SELECT * FROM Shop_Msg_Error_Type; + +# File Types +SELECT * FROM File_Type; +SELECT * FROM File_Type_Audit; + +# Generic / shared properties +SELECT * FROM Shop_General; +SELECT * FROM Shop_General_Audit; + +# Categories +SELECT * FROM Shop_Category; +SELECT * FROM Shop_Category_Audit; + +# Recurrence Interval +SELECT * FROM Shop_Recurrence_Interval; +SELECT * FROM Shop_Recurrence_Interval_Audit; + +# Region +SELECT * FROM Shop_Region; +SELECT * FROM Shop_Region_Audit; + +# Region Branch +SELECT * FROM Shop_Region_Branch; +SELECT * FROM Shop_Region_Branch_Audit; + +# Currency +SELECT * FROM Shop_Currency; +SELECT * FROM Shop_Currency_Audit; + +# Taxes and Surcharges +SELECT * FROM Shop_Tax_Or_Surcharge; +SELECT * FROM Shop_Tax_Or_Surcharge_Audit; + +# Products +SELECT * FROM Shop_Product; +SELECT * FROM Shop_Product_Audit; + +# Variation Types +SELECT * FROM Shop_Variation_Type; +SELECT * FROM Shop_Variation_Type_Audit; + +# Variations +SELECT * FROM Shop_Variation; +SELECT * FROM Shop_Variation_Audit; + +# Permutations +SELECT * FROM Shop_Product_Permutation; +SELECT * FROM Shop_Product_Permutation_Audit; + +# Permutation Variation Links +SELECT * FROM Shop_Product_Permutation_Variation_Link; +SELECT * FROM Shop_Product_Permutation_Variation_Link_Audit; + +# Product Currency Links +SELECT * FROM Shop_Product_Currency_Region_Link; +SELECT * FROM Shop_Product_Currency_Region_Link_Audit; + +# Image Types +SELECT * FROM Shop_Image_Type; +SELECT * FROM Shop_Image_Type_Audit; + +# Images +SELECT * FROM Shop_Image; +SELECT * FROM Shop_Image_Audit; + +# Delivery Option Types +SELECT * FROM Shop_Delivery_Option; +SELECT * FROM Shop_Delivery_Option_Audit; + +# Delivery Options +SELECT * FROM Shop_Product_Delivery_Option_Link; +SELECT * FROM Shop_Product_Delivery_Option_Link_Audit; + +# Discounts +SELECT * FROM Shop_Discount; +SELECT * FROM Shop_Discount_Audit; + +# Discount Delivery Region Links +SELECT * FROM Shop_Discount_Region_Currency_Link; +SELECT * FROM Shop_Discount_Region_Currency_Link_Audit; + + +# Permission Groups +SELECT * FROM Shop_Permission_Group; +SELECT * FROM Shop_Permission_Group_Audit; + +# Permissions +SELECT * FROM Shop_Permission; +SELECT * FROM Shop_Permission_Audit; + +# Roles +SELECT * FROM Shop_Role; +SELECT * FROM Shop_Role_Audit; + +# Role Permission link +SELECT * FROM Shop_Role_Permission_Link; +SELECT * FROM Shop_Role_Permission_Link_Audit; + +# Users +SELECT * FROM Shop_User; +SELECT * FROM Shop_User_Audit; + +# User Role link +SELECT * FROM Shop_User_Role_Link; +SELECT * FROM Shop_User_Role_Link_Audit; + + +# Addresses +SELECT * FROM Shop_Address; +SELECT * FROM Shop_Address_Audit; + +# Basket +SELECT * FROM Shop_User_Basket; +SELECT * FROM Shop_User_Basket_Audit; + +# Order Statuses +SELECT * FROM Shop_User_Order_Status; +SELECT * FROM Shop_User_Order_Status_Audit; + +# Orders +SELECT * FROM Shop_User_Order; +SELECT * FROM Shop_User_Order_Audit; + +# Order Products +SELECT * FROM Shop_User_Order_Product_Link; +SELECT * FROM Shop_User_Order_Product_Link_Audit; diff --git a/static/sql/910_anal.sql b/static/sql/910_anal.sql new file mode 100644 index 00000000..dc4d76af --- /dev/null +++ b/static/sql/910_anal.sql @@ -0,0 +1,26 @@ + +USE PARTS; + + +SELECT TABLE_NAME +FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_NAME LIKE '%SHOP%' + OR TABLE_NAME LIKE '%FILE_TYPE%'; + + +SELECT FOUND_ROWS(); + + + +SELECT + CONSTRAINT_NAME, + CONSTRAINT_TYPE, + TABLE_NAME, + COLUMN_NAME, + REFERENCED_TABLE_NAME, + REFERENCED_COLUMN_NAME +FROM + INFORMATION_SCHEMA.TABLES +WHERE + TABLE_SCHEMA = 'PARTS' + -- AND TABLE_NAME = 'your_table_name'; diff --git a/static/sql/920_edit_permissions.sql b/static/sql/920_edit_permissions.sql new file mode 100644 index 00000000..bacf7ecc --- /dev/null +++ b/static/sql/920_edit_permissions.sql @@ -0,0 +1,83 @@ +SELECT URL.id_link, + URL.id_user, + U.name AS name, + URL.id_role, + R.name AS role +FROM Shop_User_Role_Link URL +INNER JOIN Shop_User U + ON URL.id_user = U.id_user +INNER JOIN Shop_Role R + ON URL.id_role = R.id_role +; +SELECT * +FROM Shop_Role_Permission_Link +; +SELECT * +FROM Shop_Access_Level +; +SELECT * +FROM Shop_Permission +; +SELECT * +FROM Shop_Access_Level +; + + +select * from shop_user; +select * from shop_user_audit; +select * from Shop_User_Change_Set; +/* +INSERT INTO Shop_User_Change_Set ( comment ) +VALUES ('Demotion'); +*/ +UPDATE Shop_User +SET is_super_user = 0, + id_change_set = (SELECT id_change_set FROM Shop_User_Change_Set LIMIT 1) +WHERE id_user = 1 +; +select * from shop_user; +select * from shop_user_audit; + + +drop procedure if exists p_test; +delimiter // +create procedure p_test () +begin + declare b0 int; + declare b1 int; + SET b0 = 0; + SET b1 = 1; + select b0, b1; + select cast(b0 as char), cast(b1 as char); + select cast(b0 as char character set utf8), cast(b1 as char character set utf8); + select convert(b0, char), convert(b1, char); + select convert(b0, char character set utf8), convert(b1, char character set utf8); + select convert(convert(b0, signed), char), convert(convert(b1, signed), char); + select convert(convert(b0, signed), char character set utf8), convert(convert(b1, signed), char character set utf8); +end // +delimiter ; +call p_test(); +drop procedure if exists p_test; + +INSERT INTO Shop_User_Audit ( + id_user, + name_field, + value_prev, + value_new, + id_change_set +) +SELECT id_user, name_field, value_prev, value_new, id_change_set +FROM Shop_User_Audit +WHERE id_audit = 1 +UNION +SELECT id_user, name_field, value_prev, value_new, id_change_set +FROM Shop_User_Audit +WHERE id_audit = 1 +; + +select * from shop_user_audit; + + +SELECT * FROM Shop_Access_Level; + +SELECT * FROM Shop_Product; \ No newline at end of file diff --git a/static/sql/deprecated/000_init_tables_authentication.sql b/static/sql/deprecated/000_init_tables_authentication.sql new file mode 100644 index 00000000..cc43878b --- /dev/null +++ b/static/sql/deprecated/000_init_tables_authentication.sql @@ -0,0 +1,824 @@ +/* Store */ +USE PARTS; + +# Drop dependencies +# DROP PROCEDURE IF EXISTS p_shop_user_eval; +DROP TABLE IF EXISTS User_Eval_Temp; + +# Delete old tables +DROP TABLE IF EXISTS Shop_Address_Audit; +DROP TABLE IF EXISTS Shop_Address; + +DROP TABLE IF EXISTS Shop_User_Role_Link_Audit; +DROP TABLE IF EXISTS Shop_User_Role_Link; + +DROP TABLE IF EXISTS Shop_User_Audit; +DROP TABLE IF EXISTS Shop_User; + +DROP TABLE IF EXISTS Shop_Role_Permission_Link_Audit; +DROP TABLE IF EXISTS Shop_Role_Permission_Link; + +DROP TABLE IF EXISTS Shop_Role_Audit; +DROP TABLE IF EXISTS Shop_Role; + +DROP TABLE IF EXISTS Shop_Permission_Audit; +DROP TABLE IF EXISTS Shop_Permission; + +DROP TABLE IF EXISTS Shop_Permission_Group_Audit; +DROP TABLE IF EXISTS Shop_Permission_Group; + +DROP TABLE IF EXISTS Shop_Access_Level_Audit; +DROP TABLE IF EXISTS Shop_Access_Level; + +DROP TABLE IF EXISTS Shop_User_Change_Set; + + + +# User Change Sets +CREATE TABLE Shop_User_Change_Set ( + id_change_set INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + comment VARCHAR(500), + updated_last_on DATETIME, + updated_last_by VARCHAR(100) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Change_Set +BEFORE INSERT ON Shop_User_Change_Set +FOR EACH ROW +BEGIN + IF NEW.updated_last_on <=> NULL THEN + SET NEW.updated_last_on = NOW(); + END IF; + IF NEW.updated_last_by <=> NULL THEN + SET NEW.updated_last_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +SELECT * FROM Shop_User_Change_Set; + + + +# Access Levels +CREATE TABLE Shop_Access_Level ( + id_access_level INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + priority INT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Access_Level_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Access_Level +BEFORE INSERT ON Shop_Access_Level +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +CREATE TABLE Shop_Access_Level_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_access_level INT NOT NULL, + CONSTRAINT FK_Shop_Access_Level_Audit_id_access_level + FOREIGN KEY (id_access_level) + REFERENCES Shop_Access_Level(id_access_level) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Access_Level_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Access_Level +BEFORE UPDATE ON Shop_Access_Level +FOR EACH ROW +BEGIN + INSERT INTO Shop_Access_Level_Audit ( + id_access_level, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_access_level, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT (OLD.code <=> NEW.code) + UNION + # Changed name + SELECT NEW.id_access_level, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT (OLD.name <=> NEW.name) + UNION + # Changed priority + SELECT NEW.id_access_level, 'priority', CONVERT(OLD.priority, CHAR), CONVERT(NEW.priority, CHAR), NEW.id_change_set + WHERE NOT (OLD.priority <=> NEW.priority) + UNION + # Changed active + SELECT NEW.id_access_level, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; + +INSERT INTO Shop_Access_Level ( + display_order, code, name, priority +) +VALUES + (1, 'VIEW', 'View', 3), + (2, 'EDIT', 'Edit', 2), + (3, 'ADMIN', 'Admin', 1) +; + +SELECT * FROM Shop_Access_Level; +SELECT * FROM Shop_Access_Level_Audit; + + + +# Permission Groups +CREATE TABLE Shop_Permission_Group ( + id_group INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Permission_Group_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Permission_Group +BEFORE INSERT ON Shop_Permission_Group +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +CREATE TABLE Shop_Permission_Group_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_group INT NOT NULL, + CONSTRAINT FK_Shop_Permission_Group_Audit_id_group + FOREIGN KEY (id_group) + REFERENCES Shop_Permission_Group(id_group) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Permission_Group_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Permission_Group +BEFORE UPDATE ON Shop_Permission_Group +FOR EACH ROW +BEGIN + INSERT INTO Shop_Permission_Group_Audit ( + id_group, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_group, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_group, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed active + SELECT NEW.id_group, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; + +INSERT INTO Shop_Permission_Group ( + display_order, code, name +) +VALUES + (1, 'STORE', 'Store Home') +; + +SELECT * FROM Shop_Permission_Group; +SELECT * FROM Shop_Permission_Group_Audit; + + + +# Permissions +CREATE TABLE Shop_Permission ( + id_permission INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + id_permission_group INT NOT NULL, + CONSTRAINT FK_Shop_Permission_id_permission_group + FOREIGN KEY (id_permission_group) + REFERENCES Shop_Permission_Group(id_group) + ON UPDATE RESTRICT, + required_access_level INT NOT NULL, + CONSTRAINT FK_Shop_Permission_id_access_level + FOREIGN KEY (required_access_level) + REFERENCES Shop_Access_Level(id_access_level), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Permission_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Permission +BEFORE INSERT ON Shop_Permission +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +CREATE TABLE Shop_Permission_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_permission INT NOT NULL, + CONSTRAINT FK_Shop_Permission_Audit_id_permission + FOREIGN KEY (id_permission) + REFERENCES Shop_Permission(id_permission) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Permission_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Permission +BEFORE UPDATE ON Shop_Permission +FOR EACH ROW +BEGIN + INSERT INTO Shop_Permission_Audit ( + id_permission, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_permission, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_permission, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed id_permission_group + SELECT NEW.id_permission, 'id_permission_group', CONVERT(OLD.id_permission_group, CHAR), CONVERT(NEW.id_permission_group, CHAR), NEW.id_change_set + WHERE NOT OLD.id_permission_group <=> NEW.id_permission_group + UNION + # Changed required_access_level + SELECT NEW.id_permission, 'required_access_level', CONVERT(OLD.required_access_level, CHAR), CONVERT(NEW.required_access_level, CHAR), NEW.id_change_set + WHERE NOT OLD.required_access_level <=> NEW.required_access_level + UNION + # Changed active + SELECT NEW.id_permission, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; + +INSERT INTO Shop_Permission ( + display_order, code, name, id_permission_group, required_access_level +) +VALUES + (1, 'STORE_PRODUCT', 'Store Product Page', 1, 1), + (2, 'STORE_SERVICES', 'Store Services Page', 1, 1), + (3, 'CONTACT_US', 'Contact Us Page', 1, 1) +; + +SELECT * FROM Shop_Permission; +SELECT * FROM Shop_Permission_Audit; + + + +# Roles +CREATE TABLE Shop_Role ( + id_role INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Role_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Role +BEFORE INSERT ON Shop_Role +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +CREATE TABLE Shop_Role_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_role INT NOT NULL, + CONSTRAINT FK_Shop_Role_Audit_id_role + FOREIGN KEY (id_role) + REFERENCES Shop_Role(id_role) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Role_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Role +BEFORE UPDATE ON Shop_Role +FOR EACH ROW +BEGIN + INSERT INTO Shop_Role_Audit ( + id_role, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_role, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_role, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed active + SELECT NEW.id_role, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; + +INSERT INTO Shop_Role ( + display_order, + code, + name +) +VALUES + (1, 'DIRECTOR', 'Director'), + (2, 'USER', 'User') +; + +SELECT * FROM Shop_Role; +SELECT * FROM Shop_Role_Audit; + + + +# Role Permission link +CREATE TABLE Shop_Role_Permission_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_role INT, + CONSTRAINT FK_Shop_Role_Permission_Link_id_role + FOREIGN KEY (id_role) + REFERENCES Shop_Role(id_role) + ON UPDATE RESTRICT, + id_permission INT, + CONSTRAINT FK_Shop_Role_Permission_Link_id_permission + FOREIGN KEY (id_permission) + REFERENCES Shop_Permission(id_permission) + ON UPDATE RESTRICT, + id_access_level INT, + CONSTRAINT FK_Shop_Role_Permission_Link_id_access_level + FOREIGN KEY (id_access_level) + REFERENCES Shop_Access_Level(id_access_level) + ON UPDATE RESTRICT, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Role_Permission_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Role_Permission_Link +BEFORE INSERT ON Shop_Role_Permission_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +CREATE TABLE Shop_Role_Permission_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Role_Permission_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Role_Permission_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Role_Permission_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Role_Permission_Link +BEFORE UPDATE ON Shop_Role_Permission_Link +FOR EACH ROW +BEGIN + INSERT INTO Shop_Role_Permission_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed id_role + SELECT NEW.id_link, 'id_role', CONVERT(OLD.id_role, CHAR), CONVERT(NEW.id_role, CHAR), NEW.id_change_set + WHERE NOT OLD.id_role <=> NEW.id_role + UNION + # Changed id_permission + SELECT NEW.id_link, 'id_permission', CONVERT(OLD.id_permission, CHAR), CONVERT(NEW.id_permission, CHAR), NEW.id_change_set + WHERE NOT OLD.id_permission <=> NEW.id_permission + UNION + # Changed id_access_level + SELECT NEW.id_link, 'id_access_level', CONVERT(OLD.id_access_level, CHAR), CONVERT(NEW.id_access_level, CHAR), NEW.id_change_set + WHERE NOT OLD.id_access_level <=> NEW.id_access_level + UNION + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; + +INSERT INTO Shop_Role_Permission_Link ( + id_role, id_permission, id_access_level +) +VALUES + (1, 1, 3), + (1, 2, 3), + (1, 3, 3), + (2, 1, 1), + (2, 2, 1), + (2, 3, 1) +; + +SELECT * FROM Shop_Role_Permission_Link; +SELECT * FROM Shop_Role_Permission_Link_Audit; + + + +# Users +CREATE TABLE Shop_User ( + id_user INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255), + is_super_user BIT NOT NULL DEFAULT 0, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_User_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User +BEFORE INSERT ON Shop_User +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +CREATE TABLE Shop_User_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_user INT NOT NULL, + CONSTRAINT FK_Shop_User_Audit_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_User_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_User +BEFORE UPDATE ON Shop_User +FOR EACH ROW +BEGIN + INSERT INTO Shop_User_Audit ( + id_user, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed name + SELECT NEW.id_user, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT (OLD.name <=> NEW.name) + UNION + # Changed is_super_user + SELECT NEW.id_user, 'is_super_user', CONVERT(CONVERT(OLD.is_super_user, SIGNED), CHAR), CONVERT(CONVERT(NEW.is_super_user, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.is_super_user <=> NEW.is_super_user) + UNION + # Changed active + SELECT NEW.id_user, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; + +INSERT INTO Shop_User ( + name, + is_super_user +) +VALUES ( + 'Teddy', + 1 +); + +SELECT * FROM Shop_User; +SELECT * FROM Shop_User_Audit; + + + +# User Role link +CREATE TABLE Shop_User_Role_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_user INT, + CONSTRAINT FK_Shop_User_Role_Link_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user) + ON UPDATE RESTRICT, + id_role INT, + CONSTRAINT FK_Shop_User_Role_Link_id_role + FOREIGN KEY (id_role) + REFERENCES Shop_Role(id_role) + ON UPDATE RESTRICT, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_User_Role_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_User_Role_Link +BEFORE INSERT ON Shop_User_Role_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +CREATE TABLE Shop_User_Role_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_User_Role_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_User_Role_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_User_Role_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_User_Role_Link +BEFORE UPDATE ON Shop_User_Role_Link +FOR EACH ROW +BEGIN + INSERT INTO Shop_User_Role_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; + +INSERT INTO Shop_User_Role_Link ( + id_user, id_role +) +VALUES + (1, 1) +; + +SELECT * FROM Shop_User_Role_Link; +SELECT * FROM Shop_User_Role_Link_Audit; + + + +# Addresses +CREATE TABLE Shop_Address ( + id_address INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_user INT NOT NULL, + CONSTRAINT FK_Shop_Address_id_user + FOREIGN KEY (id_user) + REFERENCES Shop_User(id_user) + ON UPDATE RESTRICT, + region VARCHAR(100) NOT NULL, + name_full VARCHAR(255) NOT NULL, + phone_number VARCHAR(20) NOT NULL, + postcode VARCHAR(20) NOT NULL, + address_line_1 VARCHAR(100) NOT NULL, + address_line_2 VARCHAR(100) NOT NULL, + city VARCHAR(50) NOT NULL, + county VARCHAR(100) NOT NULL, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Address_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Address +BEFORE INSERT ON Shop_Address +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +CREATE TABLE Shop_Address_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_address INT NOT NULL, + CONSTRAINT FK_Shop_Address_Audit_id_address + FOREIGN KEY (id_address) + REFERENCES Shop_Address(id_address) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Address_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_User_Change_Set(id_change_set) + ON UPDATE RESTRICT +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Address +BEFORE UPDATE ON Shop_Address +FOR EACH ROW +BEGIN + INSERT INTO Shop_Address_Audit ( + id_address, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed region + SELECT NEW.id_address, 'region', OLD.region, NEW.region, NEW.id_change_set + WHERE NOT OLD.region <=> NEW.region + UNION + # Changed name_full + SELECT NEW.id_address, 'name_full', OLD.name_full, NEW.name_full, NEW.id_change_set + WHERE NOT OLD.name_full <=> NEW.name_full + UNION + # Changed phone_number + SELECT NEW.id_address, 'phone_number', OLD.phone_number, NEW.phone_number, NEW.id_change_set + WHERE NOT OLD.phone_number <=> NEW.phone_number + UNION + # Changed postcode + SELECT NEW.id_address, 'postcode', OLD.postcode, NEW.postcode, NEW.id_change_set + WHERE NOT OLD.postcode <=> NEW.postcode + UNION + # Changed address_line_1 + SELECT NEW.id_address, 'address_line_1', OLD.address_line_1, NEW.address_line_1, NEW.id_change_set + WHERE NOT OLD.address_line_1 <=> NEW.address_line_1 + UNION + # Changed address_line_2 + SELECT NEW.id_address, 'address_line_2', OLD.address_line_2, NEW.address_line_2, NEW.id_change_set + WHERE NOT OLD.address_line_2 <=> NEW.address_line_2 + UNION + # Changed city + SELECT NEW.id_address, 'city', OLD.city, NEW.city, NEW.id_change_set + WHERE NOT OLD.city <=> NEW.city + UNION + # Changed county + SELECT NEW.id_address, 'county', OLD.county, NEW.county, NEW.id_change_set + WHERE NOT OLD.county <=> NEW.county + UNION + # Changed active + SELECT NEW.id_address, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; + +INSERT INTO Shop_Address ( + id_user, region, name_full, phone_number, postcode, address_line_1, address_line_2, city, county +) +SELECT U.id_user, 'United Kingdom', U.name, '07375 571430', 'NN6 6EB', 'The Laurels', 'Cold Ashby Road', 'Cold Ashby', 'Northamptonshire' + FROM Shop_User U; + +SELECT * FROM Shop_Address; +SELECT * FROM Shop_Address_Audit; + + diff --git a/static/sql/deprecated/000_init_tables_product.sql b/static/sql/deprecated/000_init_tables_product.sql new file mode 100644 index 00000000..1ebaeb37 --- /dev/null +++ b/static/sql/deprecated/000_init_tables_product.sql @@ -0,0 +1,1520 @@ +/* Store */ +USE PARTS; + + +# Delete old tables +DROP TABLE IF EXISTS Shop_Product_Delivery_Region_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Delivery_Region_Link; + +DROP TABLE IF EXISTS Shop_Delivery_Region_Audit; +DROP TABLE IF EXISTS Shop_Delivery_Region; + +DROP TABLE IF EXISTS Shop_Delivery_Option_Audit; +DROP TABLE IF EXISTS Shop_Delivery_Option; + +DROP TABLE IF EXISTS Shop_Delivery_Option_Type_Audit; +DROP TABLE IF EXISTS Shop_Delivery_Option_Type; + +DROP TABLE IF EXISTS Shop_Product_Image_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Image_Link; + +DROP TABLE IF EXISTS Shop_Image_Audit; +DROP TABLE IF EXISTS Shop_Image; + +DROP TABLE IF EXISTS Shop_Image_Type_Audit; +DROP TABLE IF EXISTS Shop_Image_Type; + +DROP TABLE IF EXISTS Shop_Product_Variation_Link_Audit; +DROP TABLE IF EXISTS Shop_Product_Variation_Link; + +DROP TABLE IF EXISTS Shop_Variation_Audit; +DROP TABLE IF EXISTS Shop_Variation; + +DROP TABLE IF EXISTS Shop_Variation_Type_Audit; +DROP TABLE IF EXISTS Shop_Variation_Type; + +DROP TABLE IF EXISTS Shop_Product_Audit; +DROP TABLE IF EXISTS Shop_Product; + +DROP TABLE IF EXISTS Shop_Recurrence_Interval_Audit; +DROP TABLE IF EXISTS Shop_Recurrence_Interval; + +DROP TABLE IF EXISTS Shop_Category_Audit; +DROP TABLE IF EXISTS Shop_Category; + +DROP TABLE IF EXISTS Shop_General_Audit; +DROP TABLE IF EXISTS Shop_General; + +DROP TABLE IF EXISTS File_Type_Audit; +DROP TABLE IF EXISTS File_Type; + +DROP TABLE IF EXISTS Shop_Product_Change_Set; + + + +# Product Change Sets +CREATE TABLE Shop_Product_Change_Set ( + id_change_set INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + comment VARCHAR(500), + updated_last_on DATETIME, + updated_last_by VARCHAR(100) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Change_Set +BEFORE INSERT ON Shop_Product_Change_Set +FOR EACH ROW +BEGIN + IF NEW.updated_last_on <=> NULL THEN + SET NEW.updated_last_on = NOW(); + END IF; + IF NEW.updated_last_by <=> NULL THEN + SET NEW.updated_last_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +SELECT * FROM Shop_Product_Change_Set; + + + +# File Types +CREATE TABLE File_Type ( + id_type INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(100), + extension VARCHAR(50), + created_on DATETIME, + created_by VARCHAR(100), + updated_last_on DATETIME, + updated_last_by VARCHAR(100) +); + +DELIMITER // +CREATE TRIGGER before_insert_File_Type +BEFORE INSERT ON File_Type +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +CREATE TABLE File_Type_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_File_Type_Audit_id_type + FOREIGN KEY (id_type) + REFERENCES File_Type(id_type) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + created_on DATETIME, + created_by VARCHAR(100), + updated_last_on DATETIME, + updated_last_by VARCHAR(100) +); + +DELIMITER // +CREATE TRIGGER before_insert_File_Type_Audit +BEFORE INSERT ON File_Type_Audit +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_File_Type_Audit +BEFORE UPDATE ON File_Type_Audit +FOR EACH ROW +BEGIN + SET NEW.updated_last_on = NOW(); + SET NEW.updated_last_by = CURRENT_USER(); +END // +DELIMITER ; + +DELIMITER // +CREATE TRIGGER before_update_File_Type +BEFORE UPDATE ON File_Type +FOR EACH ROW +BEGIN + INSERT INTO File_Type_Audit ( + id_type, + name_field, + value_prev, + value_new + ) + # Changed code + SELECT NEW.id_type, 'code', OLD.code, NEW.code + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_type, 'name', OLD.name, NEW.name + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed extension + SELECT NEW.id_type, 'extension', CONVERT(OLD.extension, CHAR), CONVERT(NEW.extension, CHAR) + WHERE NOT OLD.extension <=> NEW.extension + ; +END // +DELIMITER ; + +INSERT INTO File_Type ( + code, name, extension +) +VALUES + ('JPEG', 'Joint Photographic Export Group', 'jpg'), + ('PNG', 'Portable Network Graphic', 'png'), + ('GIF', 'GIF', 'gif'), + ('MPEG-4', 'Multimedia Photographic Export Group 4', 'mp4') +; + +SELECT * FROM File_Type; +SELECT * FROM File_Type_Audit; + + + +# Generic / shared properties +CREATE TABLE Shop_General ( + id_general INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + quantity_max FLOAT, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_General_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_General +BEFORE INSERT ON Shop_General +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +CREATE TABLE Shop_General_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_general INT NOT NULL, + CONSTRAINT FK_Shop_General_Audit_id_general + FOREIGN KEY (id_general) + REFERENCES Shop_General(id_general) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_General_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_General +BEFORE UPDATE ON Shop_General +FOR EACH ROW +BEGIN + INSERT INTO Shop_General_Audit ( + id_general, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed quantity max + SELECT NEW.id_general, 'quantity_max', CONVERT(OLD.quantity_max, CHAR), CONVERT(NEW.quantity_max, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + ; +END // +DELIMITER ; + +INSERT INTO Shop_General ( + quantity_max +) +VALUES ( + 10 +); + +SELECT * FROM Shop_General; +SELECT * FROM Shop_General_Audit; + + + +# Categories +CREATE TABLE Shop_Category ( + id_category INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + description VARCHAR(4000), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Category_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Category +BEFORE INSERT ON Shop_Category +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +CREATE TABLE Shop_Category_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_category INT NOT NULL, + CONSTRAINT FK_Shop_Category_Audit_id_category + FOREIGN KEY (id_category) + REFERENCES Shop_Category(id_category) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Category_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Category +BEFORE UPDATE ON Shop_Category +FOR EACH ROW +BEGIN + INSERT INTO Shop_Category_Audit ( + id_category, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_category, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_category, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed description + SELECT NEW.id_category, 'description', OLD.description, NEW.description, NEW.id_change_set + WHERE NOT OLD.description <=> NEW.description + UNION + # Changed active + SELECT NEW.id_category, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_category, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; + +INSERT INTO Shop_Category ( + display_order, + code, + name, + description +) +VALUES ( + 1, + 'MISC', + 'Miscellaneous', + 'Not category allocated products' +); + +SELECT * FROM Shop_Category; +SELECT * FROM Shop_Category_Audit; + + + +# Recurrence Interval +CREATE TABLE Shop_Recurrence_Interval ( + id_interval INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + name_plural VARCHAR(256), + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Recurrence_Interval_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Recurrence_Interval +BEFORE INSERT ON Shop_Recurrence_Interval +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +CREATE TABLE Shop_Recurrence_Interval_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_interval INT NOT NULL, + CONSTRAINT FK_Shop_Recurrence_Interval_Audit_id_interval + FOREIGN KEY (id_interval) + REFERENCES Shop_Recurrence_Interval(id_interval) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(256), + value_new VARCHAR(256), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Recurrence_Interval_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Recurrence_Interval +BEFORE UPDATE ON Shop_Recurrence_Interval +FOR EACH ROW +BEGIN + INSERT INTO Shop_Recurrence_Interval_Audit ( + id_interval, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_interval, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_interval, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed name_plural + SELECT NEW.id_interval, 'name_plural', OLD.name_plural, NEW.name_plural, NEW.id_change_set + WHERE NOT OLD.name_plural <=> NEW.name_plural + ; +END // +DELIMITER ; + +INSERT INTO Shop_Recurrence_Interval ( + code, name, name_plural +) +VALUES + ('WEEK', 'Week', 'Weeks'), + ('MONTH', 'Month', 'Months'), + ('YEAR', 'Year', 'Years') +; + +SELECT * FROM Shop_Recurrence_Interval; +SELECT * FROM Shop_Recurrence_Interval_Audit; + + + +# Products +CREATE TABLE Shop_Product ( + id_product INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255), + description VARCHAR(4000), + price_GBP FLOAT, + id_category INT NOT NULL, + CONSTRAINT FK_Shop_Product_id_category + FOREIGN KEY (id_category) + REFERENCES Shop_Category(id_category) + ON UPDATE RESTRICT, + latency_manuf INT NOT NULL DEFAULT 14, + quantity_min FLOAT NOT NULL DEFAULT 1, + quantity_max FLOAT NOT NULL DEFAULT 1, # @_quantity_max, + quantity_step FLOAT NOT NULL DEFAULT 1, + quantity_stock FLOAT NOT NULL DEFAULT 0, + is_subscription BIT NOT NULL DEFAULT 0, + id_recurrence_interval INT, + CONSTRAINT FK_Shop_Product_id_recurrence_interval + FOREIGN KEY (id_recurrence_interval) + REFERENCES Shop_Recurrence_Interval(id_interval), + count_recurrence_interval INT, + id_stripe_product VARCHAR(100), + id_stripe_price VARCHAR(100), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product +BEFORE INSERT ON Shop_Product +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +CREATE TABLE Shop_Product_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Audit_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product +BEFORE UPDATE ON Shop_Product +FOR EACH ROW +BEGIN + INSERT INTO Shop_Product_Audit ( + id_product, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed name + SELECT NEW.id_product, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed description + SELECT NEW.id_product, 'description', OLD.description, NEW.description, NEW.id_change_set + WHERE NOT OLD.description <=> NEW.description + UNION + # Changed price_GBP + SELECT NEW.id_product, 'price_GBP', CONVERT(OLD.price_GBP, CHAR), CONVERT(NEW.price_GBP, CHAR), NEW.id_change_set + WHERE NOT OLD.price_GBP <=> NEW.price_GBP + UNION + # Changed id_category + SELECT NEW.id_product, 'id_category', CONVERT(OLD.id_category, CHAR), CONVERT(NEW.id_category, CHAR), NEW.id_change_set + WHERE NOT OLD.id_category <=> NEW.id_category + UNION + # Changed latency_manuf + SELECT NEW.id_product, 'latency_manuf', CONVERT(OLD.latency_manuf, CHAR), CONVERT(NEW.latency_manuf, CHAR), NEW.id_change_set + WHERE NOT OLD.latency_manuf <=> NEW.latency_manuf + UNION + # Changed quantity_min + SELECT NEW.id_product, 'quantity_min', CONVERT(OLD.quantity_min, CHAR), CONVERT(NEW.quantity_min, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_min <=> NEW.quantity_min + UNION + # Changed quantity_max + SELECT NEW.id_product, 'quantity_max', CONVERT(OLD.quantity_max, CHAR), CONVERT(NEW.quantity_max, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + UNION + # Changed quantity_step + SELECT NEW.id_product, 'quantity_step', CONVERT(OLD.quantity_step, CHAR), CONVERT(NEW.quantity_step, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_step <=> NEW.quantity_step + UNION + # Changed quantity_stock + SELECT NEW.id_product, 'quantity_stock', CONVERT(OLD.quantity_stock, CHAR), CONVERT(NEW.quantity_stock, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_stock <=> NEW.quantity_stock + UNION + # Changed is_subscription + SELECT NEW.id_product, 'is_subscription', CONVERT(CONVERT(OLD.is_subscription, SIGNED), CHAR), CONVERT(CONVERT(NEW.is_subscription, SIGNED), CHAR), NEW.id_change_set + WHERE NOT OLD.is_subscription <=> NEW.is_subscription + UNION + # Changed id_recurrence_interval + SELECT NEW.id_product, 'id_recurrence_interval', CONVERT(OLD.id_recurrence_interval, CHAR), CONVERT(NEW.id_recurrence_interval, CHAR), NEW.id_change_set + WHERE NOT OLD.id_recurrence_interval <=> NEW.id_recurrence_interval + UNION + # Changed count_recurrence_interval + SELECT NEW.id_product, 'count_recurrence_interval', CONVERT(OLD.count_recurrence_interval, CHAR), CONVERT(NEW.count_recurrence_interval, CHAR), NEW.id_change_set + WHERE NOT OLD.count_recurrence_interval <=> NEW.count_recurrence_interval + UNION + # Changed id_stripe_product + SELECT NEW.id_product, 'id_stripe_product', OLD.id_stripe_product, NEW.id_stripe_product, NEW.id_change_set + WHERE NOT OLD.id_stripe_product <=> NEW.id_stripe_product + UNION + # Changed id_stripe_price + SELECT NEW.id_product, 'id_stripe_price', OLD.id_stripe_price, NEW.id_stripe_price, NEW.id_change_set + WHERE NOT OLD.id_stripe_price <=> NEW.id_stripe_price + UNION + # Changed active + SELECT NEW.id_product, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_product, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; + +INSERT INTO Shop_Product ( + display_order, + name, + description, + price_GBP, + id_category, + latency_manuf, + quantity_stock, + id_stripe_product, + id_stripe_price +) +VALUES ( + 1, + 'Braille Keyboard Translator', + 'Translate text into 3D Braille keyboard.', + 25, + 1, + 14, + 99, + 'prod_PB0NUOSEs06ymG', + 'price_1OMeN9L7BuLKjoMpyMY6Aae4' +); + +SELECT * FROM Shop_Product; +SELECT * FROM Shop_Product_Audit; + + + +# Variation Types +CREATE TABLE Shop_Variation_Type ( + id_type INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + name_plural VARCHAR(256), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Variation_Type_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Variation_Type +BEFORE INSERT ON Shop_Variation_Type +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +CREATE TABLE Shop_Variation_Type_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_Shop_Variation_Type_Audit_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Variation_Type(id_type) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Variation_Type_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Variation_Type +BEFORE UPDATE ON Shop_Variation_Type +FOR EACH ROW +BEGIN + INSERT INTO Shop_Variation_Type_Audit ( + id_type, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_type, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_type, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed name_plural + SELECT NEW.id_type, 'name_plural', OLD.name_plural, NEW.name_plural, NEW.id_change_set + WHERE NOT OLD.name_plural <=> NEW.name_plural + UNION + # Changed active + SELECT NEW.id_type, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_type, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; + +INSERT INTO Shop_Variation_Type ( + display_order, code, name, name_plural +) +VALUES + (1, 'COLOUR', 'Colour', 'Colours') +; + +SELECT * FROM Shop_Variation_Type; +SELECT * FROM Shop_Variation_Type_Audit; + + + +# Variations +CREATE TABLE Shop_Variation ( + id_variation INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_Shop_Variation_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Variation_Type(id_type) + ON UPDATE RESTRICT, + code VARCHAR(50), + name VARCHAR(255), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Variation_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Variation +BEFORE INSERT ON Shop_Variation +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +CREATE TABLE Shop_Variation_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_variation INT NOT NULL, + CONSTRAINT FK_Shop_Variation_Audit_id_variation + FOREIGN KEY (id_variation) + REFERENCES Shop_Variation(id_variation) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Variation_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Variation +BEFORE UPDATE ON Shop_Variation +FOR EACH ROW +BEGIN + INSERT INTO Shop_Variation_Audit ( + id_variation, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_variation, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_variation, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed active + SELECT NEW.id_variation, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_variation, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; + +INSERT INTO Shop_Variation ( + display_order, id_type, code, name +) +VALUES + (1, 1, 'RED', 'Red') +; + +SELECT * FROM Shop_Variation_Type; +SELECT * FROM Shop_Variation_Type_Audit; + + + +# Product Variation Link +CREATE TABLE Shop_Product_Variation_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT, + CONSTRAINT FK_Shop_Product_Variation_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_variation INT, + CONSTRAINT FK_Shop_Product_Variation_Link_id_variation + FOREIGN KEY (id_variation) + REFERENCES Shop_Variation(id_variation) + ON UPDATE RESTRICT, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Variation_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Variation_Link +BEFORE INSERT ON Shop_Product_Variation_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +CREATE TABLE Shop_Product_Variation_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Variation_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Variation_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Variation_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Variation_Link +BEFORE UPDATE ON Shop_Product_Variation_Link +FOR EACH ROW +BEGIN + INSERT INTO Shop_Product_Variation_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed id_product + SELECT NEW.id_link, 'id_product', OLD.id_product, NEW.id_product, NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_variation + SELECT NEW.id_link, 'id_variation', OLD.id_variation, NEW.id_variation, NEW.id_change_set + WHERE NOT OLD.id_variation <=> NEW.id_variation + UNION + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_link, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; + +INSERT INTO Shop_Product_Variation_Link ( + display_order, id_product, id_variation +) +VALUES + (1, 1, 1) +; + +SELECT * FROM Shop_Product_Variation_Link; +SELECT * FROM Shop_Product_Variation_Link_Audit; + + + +# Image Types +CREATE TABLE Shop_Image_Type ( + id_type INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(255), + name_plural VARCHAR(256), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Image_Type_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Image_Type +BEFORE INSERT ON Shop_Image_Type +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +CREATE TABLE Shop_Image_Type_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_Shop_Image_Type_Audit_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Image_Type(id_type) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Image_Type_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Image_Type +BEFORE UPDATE ON Shop_Image_Type +FOR EACH ROW +BEGIN + INSERT INTO Shop_Image_Type_Audit ( + id_type, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_type, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_type, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed name_plural + SELECT NEW.id_type, 'name_plural', OLD.name_plural, NEW.name_plural, NEW.id_change_set + WHERE NOT OLD.name_plural <=> NEW.name_plural + UNION + # Changed active + SELECT NEW.id_type, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_type, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; + +INSERT INTO Shop_Image_Type ( + display_order, code, name, name_plural +) +VALUES + (1, 'FULL', 'Full Quality Image', 'Full Quality Images'), + (1, 'LOW', 'Low Quality Image', 'Low Quality Images'), + (1, 'THUMBNAIL', 'Thumbnail Image', 'Thumbnail Images') +; + +SELECT * FROM Shop_Image_Type; +SELECT * FROM Shop_Image_Type_Audit; + + + +# Images +CREATE TABLE Shop_Image ( + id_image INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_Shop_Image_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Image_Type(id_type), + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Image_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + url VARCHAR(255), + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Image_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Image +BEFORE INSERT ON Shop_Image +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +CREATE TABLE Shop_Image_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_image INT NOT NULL, + CONSTRAINT FK_Shop_Image_Audit_id_image + FOREIGN KEY (id_image) + REFERENCES Shop_Image(id_image), + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Image_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Image +BEFORE UPDATE ON Shop_Image +FOR EACH ROW +BEGIN + INSERT INTO Shop_Image_Audit ( + id_image, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed id_type + SELECT NEW.id_image, 'id_type', CONVERT(OLD.id_type, CHAR), CONVERT(NEW.id_type, CHAR), NEW.id_change_set + WHERE NOT OLD.id_type <=> NEW.id_type + UNION + # Changed id_product + SELECT NEW.id_image, 'id_product', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed url + SELECT NEW.id_image, 'url', OLD.url, NEW.url, NEW.id_change_set + WHERE NOT OLD.url <=> NEW.url + UNION + # Changed active + SELECT NEW.id_image, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_image, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; + +INSERT INTO Shop_Image ( + display_order, id_product, id_type, url +) +VALUES + (1, 1, 1, 'www.porn.co.uk') +; + +SELECT * FROM Shop_Image; +SELECT * FROM Shop_Image_Audit; + + +/* +# Product Image Link +CREATE TABLE Shop_Product_Image_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT, + CONSTRAINT FK_Shop_Product_Image_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_image INT, + CONSTRAINT FK_Shop_Product_Image_Link_id_image + FOREIGN KEY (id_image) + REFERENCES Shop_Image(id_image) + ON UPDATE RESTRICT, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Image_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Image_Link +BEFORE INSERT ON Shop_Product_Image_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +CREATE TABLE Shop_Product_Image_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Image_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Image_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Image_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Image_Link +BEFORE UPDATE ON Shop_Product_Image_Link +FOR EACH ROW +BEGIN + INSERT INTO Shop_Product_Image_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + VALUES ( + ( # Changed id_product + SELECT NEW.id_link, 'id_product', OLD.id_product, NEW.id_product, NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + ), + ( # Changed id_variation + SELECT NEW.id_link, 'id_image', OLD.id_image, NEW.id_image, NEW.id_change_set + WHERE NOT OLD.id_image <=> NEW.id_image + ), + ( # Changed active + SELECT NEW.id_link, 'active', OLD.active, NEW.active, NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + ) + ); +END // +DELIMITER ; + +INSERT INTO Shop_Product_Image_Link ( + id_product, id_image +) +VALUES + (1, 1) +; + +SELECT * FROM Shop_Product_Image_Link; +SELECT * FROM Shop_Product_Image_Link_Audit; +*/ + + +# Delivery Option Types +CREATE TABLE Shop_Delivery_Option_Type ( + id_type INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(100) NOT NULL, + latency_delivery_min INT NOT NULL, + latency_delivery_max INT NOT NULL, + quantity_min INT NOT NULL, + quantity_max INT NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Delivery_Option_Type_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Delivery_Option_Type +BEFORE INSERT ON Shop_Delivery_Option_Type +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +CREATE TABLE Shop_Delivery_Option_Type_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_type INT NOT NULL, + CONSTRAINT FK_Shop_Delivery_Option_Type_Audit_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Delivery_Option_Type(id_type) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Delivery_Option_Type_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Delivery_Option_Type +BEFORE UPDATE ON Shop_Delivery_Option_Type +FOR EACH ROW +BEGIN + INSERT INTO Shop_Delivery_Option_Type_Audit ( + id_type, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_type, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_type, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed latency_delivery_min + SELECT NEW.id_type, 'latency_delivery_min', CONVERT(OLD.latency_delivery_min, CHAR), CONVERT(NEW.latency_delivery_min, CHAR), NEW.id_change_set + WHERE NOT OLD.latency_delivery_min <=> NEW.latency_delivery_min + UNION + # Changed latency_delivery_max + SELECT NEW.id_type, 'latency_delivery_max', CONVERT(OLD.latency_delivery_max, CHAR), CONVERT(NEW.latency_delivery_max, CHAR), NEW.id_change_set + WHERE NOT OLD.latency_delivery_max <=> NEW.latency_delivery_max + UNION + # Changed quantity_min + SELECT NEW.id_type, 'quantity_min', CONVERT(OLD.quantity_min, CHAR), CONVERT(NEW.quantity_min, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_min <=> NEW.quantity_min + UNION + # Changed quantity_max + SELECT NEW.id_type, 'quantity_max', CONVERT(OLD.quantity_max, CHAR), CONVERT(NEW.quantity_max, CHAR), NEW.id_change_set + WHERE NOT OLD.quantity_max <=> NEW.quantity_max + UNION + # Changed active + SELECT NEW.id_type, 'active', CONVERT(OLD.active, CHAR), CONVERT(NEW.active, CHAR), NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + UNION + # Changed display_order + SELECT NEW.id_type, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; + +INSERT INTO Shop_Delivery_Option_Type ( + display_order, code, name, latency_delivery_min, latency_delivery_max, quantity_min, quantity_max +) +VALUES + (1, 'COLLECT', 'Collection', 0, 0, 0, 1), + (2, 'SIGNED_1', 'First Class Signed-For', 2, 4, 0, 1) +; + +SELECT * FROM Shop_Delivery_Option_Type; +SELECT * FROM Shop_Delivery_Option_Type_Audit; + + + +# Delivery Option +CREATE TABLE Shop_Delivery_Option ( + id_option INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT, + CONSTRAINT FK_Shop_Delivery_Option_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_delivery_type INT, + CONSTRAINT FK_Shop_Delivery_Option_id_delivery_type + FOREIGN KEY (id_delivery_type) + REFERENCES Shop_Delivery_Option_Type(id_type) + ON UPDATE RESTRICT, + price_GBP FLOAT NOT NULL, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Delivery_Option_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Delivery_Option +BEFORE INSERT ON Shop_Delivery_Option +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +CREATE TABLE Shop_Delivery_Option_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_option INT NOT NULL, + CONSTRAINT FK_Shop_Delivery_Option_Audit_id_option + FOREIGN KEY (id_option) + REFERENCES Shop_Delivery_Option(id_option) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Delivery_Option_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Delivery_Option +BEFORE UPDATE ON Shop_Delivery_Option +FOR EACH ROW +BEGIN + INSERT INTO Shop_Delivery_Option_Audit ( + id_option, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed id_product + SELECT NEW.id_option, 'id_product', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_delivery_type + SELECT NEW.id_option, 'id_delivery_type', CONVERT(OLD.id_delivery_type, CHAR), CONVERT(NEW.id_delivery_type, CHAR), NEW.id_change_set + WHERE NOT OLD.id_delivery_type <=> NEW.id_delivery_type + UNION + # Changed price_GBP + SELECT NEW.id_option, 'price_GBP', CONVERT(OLD.price_GBP, CHAR), CONVERT(NEW.price_GBP, CHAR), NEW.id_change_set + WHERE NOT OLD.price_GBP <=> NEW.price_GBP + UNION + # Changed active + SELECT NEW.id_option, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; + +INSERT INTO Shop_Delivery_Option ( + id_product, id_delivery_type, price_GBP +) +VALUES + (1, 1, 5) +; + +SELECT * FROM Shop_Delivery_Option; +SELECT * FROM Shop_Delivery_Option_Audit; + + + +# Delivery Regions +CREATE TABLE Shop_Delivery_Region ( + id_region INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50) NOT NULL, + name VARCHAR(200) NOT NULL, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Delivery_Region_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Delivery_Region +BEFORE INSERT ON Shop_Delivery_Region +FOR EACH ROW +BEGIN + SET NEW.created_on = NOW(); + SET NEW.created_by = CURRENT_USER(); +END // +DELIMITER ; + +CREATE TABLE Shop_Delivery_Region_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_region INT NOT NULL, + CONSTRAINT FK_Shop_Delivery_Region_Audit_id_region + FOREIGN KEY (id_region) + REFERENCES Shop_Delivery_Region(id_region) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Delivery_Region_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Delivery_Region +BEFORE UPDATE ON Shop_Delivery_Region +FOR EACH ROW +BEGIN + INSERT INTO Shop_Delivery_Region_Audit ( + id_region, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed code + SELECT NEW.id_region, 'code', OLD.code, NEW.code, NEW.id_change_set + WHERE NOT OLD.code <=> NEW.code + UNION + # Changed name + SELECT NEW.id_region, 'name', OLD.name, NEW.name, NEW.id_change_set + WHERE NOT OLD.name <=> NEW.name + UNION + # Changed active + SELECT NEW.id_region, 'active', CONVERT(OLD.active, CHAR), CONVERT(NEW.active, CHAR), NEW.id_change_set + WHERE NOT OLD.active <=> NEW.active + UNION + # Changed display_order + SELECT NEW.id_region, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT OLD.display_order <=> NEW.display_order + ; +END // +DELIMITER ; + +INSERT INTO Shop_Delivery_Region ( + display_order, code, name +) +VALUES + (1, 'UK', 'United Kingdom') +; + +SELECT * FROM Shop_Delivery_Region; +SELECT * FROM Shop_Delivery_Region_Audit; + + + +# Product Delivery Option Link +CREATE TABLE Shop_Product_Delivery_Region_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Region_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_region INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Region_Link_id_region + FOREIGN KEY (id_region) + REFERENCES Shop_Delivery_Region(id_region) + ON UPDATE RESTRICT, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Delivery_Region_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Delivery_Region_Link +BEFORE INSERT ON Shop_Product_Delivery_Region_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + +CREATE TABLE Shop_Product_Delivery_Region_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Region_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Delivery_Region_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Region_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Delivery_Region_Link +BEFORE UPDATE ON Shop_Product_Delivery_Region_Link +FOR EACH ROW +BEGIN + INSERT INTO Shop_Product_Delivery_Region_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + # Changed id_product + SELECT NEW.id_link, 'id_product', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_region + SELECT NEW.id_link, 'id_region', CONVERT(OLD.id_region, CHAR), CONVERT(NEW.id_region, CHAR), NEW.id_change_set + WHERE NOT OLD.id_region <=> NEW.id_region + UNION + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; + +INSERT INTO Shop_Product_Delivery_Region_Link ( + id_product, id_region +) +VALUES + (1, 1) +; + +SELECT * FROM Shop_Product_Delivery_Region_Link; +SELECT * FROM Shop_Product_Delivery_Region_Link_Audit; diff --git a/static/sql/deprecated/113.1_tbl_Shop_Product_Variation_Type_Link.sql b/static/sql/deprecated/113.1_tbl_Shop_Product_Variation_Type_Link.sql new file mode 100644 index 00000000..6fdf8f33 --- /dev/null +++ b/static/sql/deprecated/113.1_tbl_Shop_Product_Variation_Type_Link.sql @@ -0,0 +1,28 @@ + +# Product Variation Type Link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Variation_Type_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Variation_Type_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Variation_Type_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_variation_type INT NOT NULL, + CONSTRAINT FK_Shop_Product_Variation_Type_Link_id_variation_type + FOREIGN KEY (id_variation_type) + REFERENCES Shop_Variation_Type(id_type) + ON UPDATE RESTRICT, + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Variation_Type_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/deprecated/113.2_tbl_Shop_Product_Variation_Type_Link_Audit.sql b/static/sql/deprecated/113.2_tbl_Shop_Product_Variation_Type_Link_Audit.sql new file mode 100644 index 00000000..68d73e18 --- /dev/null +++ b/static/sql/deprecated/113.2_tbl_Shop_Product_Variation_Type_Link_Audit.sql @@ -0,0 +1,23 @@ + +# Product Variation Type Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Variation_Type_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Variation_Type_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Variation_Type_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Variation_Type_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Variation_Type_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); diff --git a/static/sql/deprecated/116_tbl_Shop_Product_Variation_Link.sql b/static/sql/deprecated/116_tbl_Shop_Product_Variation_Link.sql new file mode 100644 index 00000000..710f2727 --- /dev/null +++ b/static/sql/deprecated/116_tbl_Shop_Product_Variation_Link.sql @@ -0,0 +1,35 @@ + +# Product Variation Link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Variation_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Variation_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Variation_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_variation INT NOT NULL, + CONSTRAINT FK_Shop_Product_Variation_Link_id_variation + FOREIGN KEY (id_variation) + REFERENCES Shop_Variation(id_variation) + ON UPDATE RESTRICT, + /* + id_product_variation_type_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Variation_Link_id_product_variation_type_link + FOREIGN KEY (id_product_variation_type_link) + REFERENCES Shop_Product_Variation_Type_Link(id_link) + ON UPDATE RESTRICT, + */ + active BIT NOT NULL DEFAULT 1, + display_order INT NOT NULL, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Variation_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); diff --git a/static/sql/deprecated/117.0_tbl_Shop_Product_Variation_Link_Audit.sql b/static/sql/deprecated/117.0_tbl_Shop_Product_Variation_Link_Audit.sql new file mode 100644 index 00000000..1f6c69d9 --- /dev/null +++ b/static/sql/deprecated/117.0_tbl_Shop_Product_Variation_Link_Audit.sql @@ -0,0 +1,23 @@ + +# Product Variation Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Variation_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Variation_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Variation_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Variation_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Variation_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); diff --git a/static/sql/deprecated/128_tbl_Shop_Product_Delivery_Region_Link.sql b/static/sql/deprecated/128_tbl_Shop_Product_Delivery_Region_Link.sql new file mode 100644 index 00000000..3fc550a0 --- /dev/null +++ b/static/sql/deprecated/128_tbl_Shop_Product_Delivery_Region_Link.sql @@ -0,0 +1,32 @@ + +# Product Delivery Option Link + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Delivery_Region_Link'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Delivery_Region_Link ( + id_link INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_product INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Region_Link_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product) + ON UPDATE RESTRICT, + id_permutation INT, + CONSTRAINT FK_Shop_Product_Delivery_Region_Link_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation) + ON UPDATE RESTRICT, + id_region INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Region_Link_id_region + FOREIGN KEY (id_region) + REFERENCES Shop_Delivery_Region(id_region) + ON UPDATE RESTRICT, + active BIT NOT NULL DEFAULT 1, + created_on DATETIME, + created_by VARCHAR(100), + id_change_set INT, + CONSTRAINT FK_Shop_Product_Delivery_Region_Link_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) +); \ No newline at end of file diff --git a/static/sql/deprecated/129_tbl_Shop_Product_Delivery_Region_Link_Audit.sql b/static/sql/deprecated/129_tbl_Shop_Product_Delivery_Region_Link_Audit.sql new file mode 100644 index 00000000..b5e02c49 --- /dev/null +++ b/static/sql/deprecated/129_tbl_Shop_Product_Delivery_Region_Link_Audit.sql @@ -0,0 +1,23 @@ + +# Product Delivery Region Link Audits + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Delivery_Region_Link_Audit'; + +CREATE TABLE IF NOT EXISTS Shop_Product_Delivery_Region_Link_Audit ( + id_audit INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_link INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Region_Link_Audit_id_link + FOREIGN KEY (id_link) + REFERENCES Shop_Product_Delivery_Region_Link(id_link) + ON UPDATE RESTRICT, + name_field VARCHAR(50), + value_prev VARCHAR(500), + value_new VARCHAR(500), + id_change_set INT NOT NULL, + CONSTRAINT FK_Shop_Product_Delivery_Region_Link_Audit_id_change_set + FOREIGN KEY (id_change_set) + REFERENCES Shop_Product_Change_Set(id_change_set) + ON UPDATE RESTRICT +); \ No newline at end of file diff --git a/static/sql/deprecated/170_ish_tbl_ERP_Order.sql b/static/sql/deprecated/170_ish_tbl_ERP_Order.sql new file mode 100644 index 00000000..19a069c5 --- /dev/null +++ b/static/sql/deprecated/170_ish_tbl_ERP_Order.sql @@ -0,0 +1,19 @@ + +# ERP Order + +USE PARTS; + +SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'ERP_Order'; + +CREATE TABLE IF NOT EXISTS ERP_Order ( + id_order INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + code VARCHAR(50), + name VARCHAR(100), + extension VARCHAR(50), + created_on DATETIME, + created_by VARCHAR(100), + id_customer INT NOT NULL, + CONSTRAINT FK_ERP_Order_id_customer + FOREIGN KEY (id_customer) + REFERENCES ERP_Customer(id_customer) +); diff --git a/static/sql/deprecated/313.1_tri_Shop_Product_Variation_Type_Link.sql b/static/sql/deprecated/313.1_tri_Shop_Product_Variation_Type_Link.sql new file mode 100644 index 00000000..6e558806 --- /dev/null +++ b/static/sql/deprecated/313.1_tri_Shop_Product_Variation_Type_Link.sql @@ -0,0 +1,61 @@ + +# Shop Product Variation Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Variation_Type_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Product_Variation_Type_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Variation_Type_Link +BEFORE INSERT ON Shop_Product_Variation_Type_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Variation_Type_Link +BEFORE UPDATE ON Shop_Product_Variation_Type_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Product_Variation_Type_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_product + SELECT NEW.id_link, 'id_product', OLD.id_product, NEW.id_product, NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_variation + SELECT NEW.id_link, 'id_variation', OLD.id_variation, NEW.id_variation, NEW.id_change_set + WHERE NOT OLD.id_variation <=> NEW.id_variation + UNION + */ + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_link, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/deprecated/316_tri_Shop_Product_Variation_Link.sql b/static/sql/deprecated/316_tri_Shop_Product_Variation_Link.sql new file mode 100644 index 00000000..7ce5732b --- /dev/null +++ b/static/sql/deprecated/316_tri_Shop_Product_Variation_Link.sql @@ -0,0 +1,61 @@ + +# Shop Product Variation Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Variation_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Product_Variation_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Variation_Link +BEFORE INSERT ON Shop_Product_Variation_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Variation_Link +BEFORE UPDATE ON Shop_Product_Variation_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Product_Variation_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_product + SELECT NEW.id_link, 'id_product', OLD.id_product, NEW.id_product, NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_variation + SELECT NEW.id_link, 'id_variation', OLD.id_variation, NEW.id_variation, NEW.id_change_set + WHERE NOT OLD.id_variation <=> NEW.id_variation + UNION + */ + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + UNION + # Changed display_order + SELECT NEW.id_link, 'display_order', CONVERT(OLD.display_order, CHAR), CONVERT(NEW.display_order, CHAR), NEW.id_change_set + WHERE NOT (OLD.display_order <=> NEW.display_order) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/deprecated/328_tri_Shop_Product_Delivery_Region_Link.sql b/static/sql/deprecated/328_tri_Shop_Product_Delivery_Region_Link.sql new file mode 100644 index 00000000..fbfda587 --- /dev/null +++ b/static/sql/deprecated/328_tri_Shop_Product_Delivery_Region_Link.sql @@ -0,0 +1,57 @@ + +# Shop Product Delivery Region Link + +USE PARTS; + +DROP TRIGGER IF EXISTS before_insert_Shop_Product_Delivery_Region_Link; +DROP TRIGGER IF EXISTS before_update_Shop_Product_Delivery_Region_Link; + + +DELIMITER // +CREATE TRIGGER before_insert_Shop_Product_Delivery_Region_Link +BEFORE INSERT ON Shop_Product_Delivery_Region_Link +FOR EACH ROW +BEGIN + IF NEW.created_on <=> NULL THEN + SET NEW.created_on = NOW(); + END IF; + IF NEW.created_by <=> NULL THEN + SET NEW.created_by = CURRENT_USER(); + END IF; +END // +DELIMITER ; + + +DELIMITER // +CREATE TRIGGER before_update_Shop_Product_Delivery_Region_Link +BEFORE UPDATE ON Shop_Product_Delivery_Region_Link +FOR EACH ROW +BEGIN + IF OLD.id_change_set <=> NEW.id_change_set THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'New change Set ID must be provided.'; + END IF; + + INSERT INTO Shop_Product_Delivery_Region_Link_Audit ( + id_link, + name_field, + value_prev, + value_new, + id_change_set + ) + /* + # Changed id_product + SELECT NEW.id_link, 'id_product', CONVERT(OLD.id_product, CHAR), CONVERT(NEW.id_product, CHAR), NEW.id_change_set + WHERE NOT OLD.id_product <=> NEW.id_product + UNION + # Changed id_region + SELECT NEW.id_link, 'id_region', CONVERT(OLD.id_region, CHAR), CONVERT(NEW.id_region, CHAR), NEW.id_change_set + WHERE NOT OLD.id_region <=> NEW.id_region + UNION + */ + # Changed active + SELECT NEW.id_link, 'active', CONVERT(CONVERT(OLD.active, SIGNED), CHAR), CONVERT(CONVERT(NEW.active, SIGNED), CHAR), NEW.id_change_set + WHERE NOT (OLD.active <=> NEW.active) + ; +END // +DELIMITER ; \ No newline at end of file diff --git a/static/sql/deprecated/706_p_shop_get_product.sql b/static/sql/deprecated/706_p_shop_get_product.sql new file mode 100644 index 00000000..f1f1a801 --- /dev/null +++ b/static/sql/deprecated/706_p_shop_get_product.sql @@ -0,0 +1,657 @@ + +USE PARTS; + +/* + +CALL p_shop_get_product ( + '', # a_id_user + 1, # a_id_product + '', # a_ids_image + 0, # a_get_first_image_only + 1 # a_get_all_images +) + +*/ + + +-- Clear previous proc +DROP PROCEDURE IF EXISTS p_shop_get_product; + + +DELIMITER // +CREATE PROCEDURE p_shop_get_product ( + IN a_id_user VARCHAR(200), + IN a_id_product INT, + IN a_ids_permutation VARCHAR(4000), + IN a_ids_image VARCHAR(500), + IN a_get_first_image_only BIT, + IN a_get_all_images BIT +) +BEGIN + -- Argument redeclaration + -- Variable declaration + DECLARE v_has_filter_product BIT; + DECLARE v_id_product_search VARCHAR(10); + DECLARE v_has_filter_permutation BIT; + DECLARE v_has_product_permutations BIT; + DECLARE v_guid VARCHAR(36); + # DECLARE v_id_user VARCHAR(100); + DECLARE v_id_permission_product INT; + DECLARE v_ids_product_permission VARCHAR(500); + DECLARE v_id_access_level_view INT; + DECLARE v_has_filter_image BIT; + DECLARE v_now DATETIME; + DECLARE v_id_minimum INT; + DECLARE v_code_error_data VARCHAR(50); + + + SET v_guid := UUID(); + SET v_code_error_data := (SELECT code FROM Shop_Msg_Error_Type WHERE id_type = 1); + SET v_id_access_level_view := (SELECT id_access_level FROM Shop_Access_Level WHERE code = 'VIEW'); + + -- Argument validation + default values + IF a_id_user IS NULL THEN + SET a_id_user = ''; + ELSE + SET a_id_user = TRIM(a_id_user); + END IF; + IF a_ids_image IS NULL THEN + SET a_ids_image = ''; + ELSE + SET a_ids_image = TRIM(a_ids_image); + END IF; + + + -- Temporary tables + DROP TABLE IF EXISTS tmp_Shop_Image; + DROP TABLE IF EXISTS tmp_Shop_Variation; + DROP TABLE IF EXISTS tmp_Shop_Product; + + CREATE TABLE tmp_Shop_Product ( + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + id_category INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Product_id_category + FOREIGN KEY (id_category) + REFERENCES Shop_Category(id_category), + display_order INT, + can_view BIT, + can_edit BIT, + can_admin BIT + ); + + /* + CREATE TEMPORARY TABLE tmp_Shop_Variation ( + id_variation INT NOT NULL, + id_product INT NOT NULL, + display_order INT NOT NULL + ); + */ + + CREATE TABLE tmp_Shop_Image ( + id_product INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Image_id_product + FOREIGN KEY (id_product) + REFERENCES Shop_Product(id_product), + id_permutation INT NULL, + CONSTRAINT FK_tmp_Shop_Image_id_permutation + FOREIGN KEY (id_permutation) + REFERENCES Shop_Product_Permutation(id_permutation), + id_image INT NOT NULL, + CONSTRAINT FK_tmp_Shop_Image_id_image + FOREIGN KEY (id_image) + REFERENCES Shop_Image(id_image), + display_order INT NOT NULL + ); + + CREATE TABLE IF NOT EXISTS tmp_Msg_Error ( + display_order INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + guid VARCHAR(36) NOT NULL, + # code VARCHAR(50) NOT NULL, + # CONSTRAINT chk_tmp_Msg_Error_code CHECK (code IN (SELECT code FROM Shop_Msg_Error_Type)), + id_type INT NOT NULL, + CONSTRAINT FK_tmp_Msg_Error_id_type + FOREIGN KEY (id_type) + REFERENCES Shop_Msg_Error_Type(id_type), + msg VARCHAR(4000) NOT NULL + ); + + + -- Parse filters + # SET v_id_product_search = CONCAT('%', CAST(a_id_product AS CHAR), '%'); + # select v_id_product_search; + SET v_has_filter_image = ''; + + # Products + INSERT INTO tmp_Shop_Product ( + id_product, id_category, display_order + ) + SELECT P.id_product, P.id_category, P.display_order + FROM Shop_Product P + # WHERE P.id_product LIKE v_id_product_search + WHERE P.id_product = a_id_product + AND NOT P.has_variations + AND P.active + ; + # Product Permutations + INSERT INTO tmp_Shop_Product ( + id_product, id_category, id_permutation, display_order + ) + SELECT PP.id_product, P.id_category, PP.id_permutation, PP.display_order + FROM Shop_Product_Permutation PP + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + AND P.has_variations + AND P.active + # WHERE PP.id_product LIKE v_id_product_search + WHERE PP.id_product = a_id_product + AND PP.active + ; + + SET a_id_product := (SELECT id_product FROM tmp_Shop_Product LIMIT 1); + -- SET v_has_filter_product = NOT ISNULL(a_id_product); + SET v_has_product_permutations = EXISTS (SELECT id_permutation FROM tmp_Shop_Product WHERE NOT ISNULL(id_permutation)); + + IF ISNULL(a_id_product) THEN # NOT v_has_filter_product + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_data, + 'Valid product ID not provided.' + ) + ; + END IF; + + # Permutations + IF v_has_filter_permutation THEN + DELETE FROM tmp_Shop_Product + WHERE FIND_IN_SET(id_permutation, a_ids_permutation) = 0 + ; + + IF NOT EXISTS (SELECT * FROM tmp_Shop_Product) THEN + INSERT INTO tmp_Msg_Error ( + guid, + code, + msg + ) + VALUES ( + v_guid, + v_code_error_data, + 'Permutation IDs not associated with product ID.' + ) + ; + END IF; + END IF; + + + /* + # Variations + INSERT INTO tmp_Shop_Variation ( + id_variation, id_product + ) + SELECT P.id_variation, P.id_product + FROM Shop_Variation V + INNER JOIN tmp_Shop_Product t_P + ON V.id_product = t_P.id_product + WHERE V.active + ; + */ + + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid) THEN + # Product Images + INSERT INTO tmp_Shop_Image ( + id_product, id_image, display_order + ) + SELECT t_P.id_product, I.id_image, I.display_order + FROM Shop_Image I + INNER JOIN tmp_Shop_Product t_P + ON I.id_product = t_P.id_product + AND ISNULL(I.id_permutation) + INNER JOIN Shop_Product P + ON t_P.id_product = P.id_product + AND NOT P.has_variations + WHERE I.active + ; + # Product Permutation Images + INSERT INTO tmp_Shop_Image ( + id_product, + id_permutation, + id_image, + display_order + ) + SELECT t_P.id_product, + t_P.id_permutation, + I.id_image, + ROW_NUMBER() OVER W AS display_order + FROM Shop_Image I + INNER JOIN Shop_Product_Permutation PP + ON I.id_permutation = PP.id_permutation + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + AND P.has_variations + INNER JOIN tmp_Shop_Product t_P + ON P.id_product = t_P.id_product + AND PP.id_permutation = t_P.id_permutation + WHERE I.active + WINDOW W AS (ORDER BY P.display_order, PP.display_order, I.display_order) + ; + END IF; + + + -- Permissions + IF NOT EXISTS (SELECT * FROM tmp_Msg_Error WHERE guid = v_guid) AND EXISTS (SELECT * FROM tmp_Shop_Product LIMIT 1) THEN + # SET v_id_user := (SELECT id_user FROM Shop_User WHERE name = CURRENT_USER()); + SET v_id_permission_product := (SELECT id_permission FROM Shop_Permission WHERE code = 'STORE_PRODUCT' LIMIT 1); + SET v_ids_product_permission := (SELECT GROUP_CONCAT(DISTINCT id_product SEPARATOR '|') FROM tmp_Shop_Product); + + SELECT v_guid, a_id_user, false, v_id_permission_product, v_id_access_level_view, v_ids_product_permission; + + CALL p_shop_user_eval(v_guid, a_id_user, false, v_id_permission_product, v_id_access_level_view, v_ids_product_permission); + + select * from shop_user_eval_temp; + + UPDATE tmp_Shop_Product t_P + INNER JOIN Shop_User_Eval_Temp UE_T + ON t_P.id_product = UE_T.id_product + AND UE_T.GUID = v_guid + SET t_P.can_view = UE_T.can_view, + t_P.can_edit = UE_T.can_edit, + t_P.can_admin = UE_T.can_admin; + + DELETE FROM tmp_Shop_Product + WHERE FIND_IN_SET(id_product, (SELECT GROUP_CONCAT(id_product SEPARATOR ',') FROM Shop_User_Eval_Temp)) = 0 # id_product NOT LIKE CONCAT('%', (SELECT GROUP_CONCAT(id_product SEPARATOR '|') FROM Shop_User_Eval_Temp), '%'); + ; + + # CALL p_shop_user_eval_clear_temp(v_guid); + # DROP TABLE IF EXISTS Shop_User_Eval_Temp; + DELETE FROM Shop_User_Eval_Temp + WHERE GUID = v_guid; + END IF; + + + -- Returns + SET v_now := NOW(); + + # Category + SELECT DISTINCT t_P.id_category, + C.name, + C.description, + C.display_order + FROM tmp_Shop_Product t_P + INNER JOIN Shop_Category C + ON t_P.id_category = C.id_category + ORDER BY C.display_order + ; + + IF NOT v_has_product_permutations THEN + # Products + SELECT t_P.id_product, + NULL AS id_permutation, + P.name, + P.description, + P.price_GBP_full, + P.has_variations, + P.id_category, + P.latency_manuf, + P.quantity_min, + P.quantity_max, + P.quantity_step, + P.quantity_stock, + P.id_stripe_product, + P.is_subscription, + RI.name AS name_recurrence_interval, + RI.name_plural AS name_plural_recurrence_interval, + P.count_recurrence_interval + FROM tmp_Shop_Product t_P + INNER JOIN Shop_Product P + ON t_P.id_product = P.id_product + LEFT JOIN Shop_Recurrence_Interval RI + ON P.id_recurrence_interval = RI.id_interval + WHERE ISNULL(t_P.id_permutation) + ORDER BY t_P.display_order + ; + ELSE + # Permutations + SELECT t_P.id_product, + t_P.id_permutation, + P.name, + P.description, + P.price_GBP_full, + P.has_variations, + P.id_category, + P.latency_manuf, + P.quantity_min, + P.quantity_max, + P.quantity_step, + P.quantity_stock, + P.id_stripe_product, + P.is_subscription, + RI.name AS name_recurrence_interval, + RI.name_plural AS name_plural_recurrence_interval, + P.count_recurrence_interval + FROM tmp_Shop_Product t_P + INNER JOIN Shop_Product_Permutation PP + ON t_P.id_permutation = PP.id_permutation + AND PP.active + INNER JOIN Shop_Product P + ON PP.id_product = P.id_product + LEFT JOIN Shop_Recurrence_Interval RI + ON P.id_recurrence_interval = RI.id_interval + WHERE NOT ISNULL(t_P.id_permutation) + ORDER BY t_P.display_order + ; + END IF; + + # Variations + IF v_has_product_permutations THEN + SELECT PPVL.id_variation, + t_P.id_product, + t_P.id_category, + VT.code AS code_variation_type, + VT.name AS name_variation_type, + V.code AS code_variation, + V.name AS name_variation + FROM Shop_Product_Permutation_Variation_Link PPVL + INNER JOIN tmp_Shop_Product t_P + ON PPVL.id_permutation = t_P.id_permutation + INNER JOIN Shop_Variation V + ON PPVL.id_variation = V.id_variation + INNER JOIN Shop_Variation_Type VT + ON V.id_type = VT.id_type + WHERE V.active + AND VT.active + AND PPVL.active + ORDER BY VT.display_order, V.display_order + ; + ELSE + SELECT NULL AS id_variation, + NULL AS id_product, + NULL AS id_category, + NULL AS code_variation_type, + NULL AS name_variation_type, + NULL AS code_variation, + NULL AS name_variation + ; + END IF; + + IF v_has_product_permutations THEN + # Permutation Variations + SELECT t_P.id_permutation, + t_P.id_product, + t_P.id_category, + id_variation + FROM Shop_Product_Permutation_Variation_Link PPVL + INNER JOIN tmp_Shop_Product t_P + ON t_P.id_permutation = PPVL.id_permutation + ; + ELSE + SELECT NULL AS id_permutation, + NULL AS id_product, + NULL AS id_category, + NULL AS id_variation + ; + END IF; + + # Images + SELECT I.id_image, + t_P.id_product, + I.id_permutation, + t_P.id_category, + I.url + FROM tmp_Shop_Image t_I + INNER JOIN Shop_Image I + ON t_I.id_image = I.id_image + INNER JOIN tmp_Shop_Product t_P + ON a_id_product = t_P.id_product + AND I.id_permutation = t_P.id_permutation + -- WHERE I.active + ORDER BY I.display_order + ; + + # Delivery Regions + IF v_has_product_permutations THEN + SELECT DR.id_region, + t_P.id_category, + t_P.id_product, + t_P.id_permutation, + DR.code, + DR.name + FROM Shop_Delivery_Region DR + INNER JOIN Shop_Product_Delivery_Region_Link PDRL + ON DR.id_region = PDRL.id_region + AND PDRL.active + INNER JOIN tmp_Shop_Product t_P + ON PDRL.id_permutation = t_P.id_permutation + WHERE DR.active + ORDER BY t_P.id_permutation, DR.display_order + ; + ELSE + SELECT PDRL.id_region, + t_P.id_category, + t_P.id_product, + t_P.id_permutation, + DR.code, + DR.name + FROM Shop_Delivery_Region DR + INNER JOIN Shop_Product_Delivery_Region_Link PDRL + ON DR.id_region = PDRL.id_region + AND PDRL.active + INNER JOIN tmp_Shop_Product t_P + ON PDRL.id_product = t_P.id_product + WHERE DR.active + ORDER BY DR.display_order + ; + END IF; + + # Delivery options + IF v_has_product_permutations THEN + SELECT _DO.id_option, + _DO.id_product, + _DO.id_permutation, + t_P.id_category, + DOT.code, + DOT.name, + DOT.latency_delivery_min, + DOT.latency_delivery_max, + DOT.quantity_min, + DOT.quantity_max, + GROUP_CONCAT(DR.code SEPARATOR ',') AS codes_region, + GROUP_CONCAT(DR.name SEPARATOR ',') AS names_region, + _DO.price_GBP, + DOT.display_order + FROM Shop_Delivery_Option _DO + INNER JOIN Shop_Delivery_Option_Type DOT + ON _DO.id_delivery_type = DOT.id_type + AND DOT.active + INNER JOIN tmp_Shop_Product t_P + ON _DO.id_permutation = t_P.id_permutation + INNER JOIN Shop_Product_Delivery_Region_Link PDRL + ON t_P.id_product = PDRL.id_product + AND PDRL.active + INNER JOIN Shop_Delivery_Region DR + ON PDRL.id_region = DR.id_region + AND DR.active + WHERE _DO.active + AND a_id_product = _DO.id_product + GROUP BY t_P.id_product, PDRL.id_region, _DO.id_option, t_P.id_category + ORDER BY DOT.display_order + ; + ELSE + SELECT _DO.id_option, + _DO.id_product, + _DO.id_permutation, + t_P.id_category, + DOT.code, + DOT.name, + DOT.latency_delivery_min, + DOT.latency_delivery_max, + DOT.quantity_min, + DOT.quantity_max, + GROUP_CONCAT(DR.code SEPARATOR ',') AS codes_region, + GROUP_CONCAT(DR.name SEPARATOR ',') AS names_region, + _DO.price_GBP, + DOT.display_order + FROM Shop_Delivery_Option _DO + INNER JOIN Shop_Delivery_Option_Type DOT + ON _DO.id_delivery_type = DOT.id_type + AND DOT.active + INNER JOIN tmp_Shop_Product t_P + ON _DO.id_product = t_P.id_product + INNER JOIN Shop_Product_Delivery_Region_Link PDRL + ON t_P.id_product = PDRL.id_product + AND PDRL.active + INNER JOIN Shop_Delivery_Region DR + ON PDRL.id_region = DR.id_region + AND DR.active + WHERE _DO.active + AND a_id_product = _DO.id_product + GROUP BY t_P.id_product, PDRL.id_region, _DO.id_option, t_P.id_category + ORDER BY DOT.display_order + ; + END IF; + + IF v_has_product_permutations THEN + # Discounts + SELECT D.id_discount, + t_P.id_category, + a_id_product, + D.id_permutation, + D.code, + D.name, + D.multiplier, + D.quantity_min, + D.quantity_max, + D.date_start, + D.date_end, + D.display_order + FROM Shop_Discount D + INNER JOIN tmp_Shop_Product t_P + ON D.id_permutation = t_P.id_permutation + WHERE D.active + ; + ELSE + # Discounts + SELECT D.id_discount, + t_P.id_category, + D.id_product, + NULL AS id_permutation, + D.code, + D.name, + D.multiplier, + D.quantity_min, + D.quantity_max, + D.date_start, + D.date_end, + D.display_order + FROM Shop_Discount D + INNER JOIN tmp_Shop_Product t_P + ON D.id_product = t_P.id_product + WHERE D.active + AND a_id_product = D.id_product + ; + END IF; + + IF v_has_product_permutations THEN + # Discount Delivery Regions + SELECT DDRL.id_discount, + DDRL.id_region, + t_P.id_category, + t_P.id_product, + t_P.id_permutation, + DR.code, + DR.name, + DR.display_order + FROM Shop_Discount D + INNER JOIN tmp_Shop_Product t_P + ON D.id_permutation = t_P.id_permutation + INNER JOIN Shop_Discount_Delivery_Region_Link DDRL + ON D.id_discount = DDRL.id_discount + AND DDRL.active + INNER JOIN Shop_Delivery_Region DR + ON DDRL.id_region = DR.id_region + AND DR.active + WHERE D.active + ; + ELSE + # Discount Delivery Regions + SELECT DDRL.id_discount, + DDRL.id_region, + t_P.id_category, + t_P.id_product, + NULL AS id_permutation, + DR.code, + DR.name, + DR.display_order + FROM Shop_Discount D + INNER JOIN tmp_Shop_Product t_P + ON D.id_product = t_P.id_product + INNER JOIN Shop_Discount_Delivery_Region_Link DDRL + ON D.id_discount = DDRL.id_discount + AND DDRL.active + INNER JOIN Shop_Delivery_Region DR + ON DDRL.id_region = DR.id_region + AND DR.active + WHERE D.active + AND a_id_product = D.id_product + ; + END IF; + + # Errors + SELECT * + FROM tmp_Msg_Error + WHERE guid = v_guid + ; + + /* + # Return arguments for test + SELECT + a_ids_category, + a_get_inactive_categories, + a_ids_product, + a_get_inactive_products, + a_get_first_product_only, + a_get_all_products, + a_ids_image, + a_get_inactive_images, + a_get_first_image_only, + a_get_all_images + ; + */ + + -- Clean up + DROP TABLE IF EXISTS tmp_Shop_Image; + DROP TABLE IF EXISTS tmp_Shop_Variation; + DROP TABLE IF EXISTS tmp_Shop_Product; +END // +DELIMITER ; + + + + +CALL p_shop_get_product ( + '', # a_id_user + 1 # a_id_product +); + +/* +drop table tmp_msg_error; +select * from shop_image; +select * from shop_discount; + +insert into shop_product_change_set (comment) + values ('set product not subscription - test bool output to python'); + update shop_product + set is_subscription = 0, + id_change_set = (select id_change_set from shop_product_change_set order by id_change_set desc limit 1) + where id_product = 1 +*/ diff --git a/static/sql/temp.txt b/static/sql/temp.txt new file mode 100644 index 00000000..e455160a --- /dev/null +++ b/static/sql/temp.txt @@ -0,0 +1,117 @@ +001_destroy.sql +100.0_tbl_Shop_Product_Change_Set.sql +100.1_tbl_Shop_User_Change_Set.sql +100.2_tbl_Shop_Access_Level.sql +100.3_tbl_Shop_Access_Level_Audit.sql +100_tbl_Msg_Error_Type.sql +102_tbl_File_Type.sql +103_tbl_File_Type_Audit.sql +104_tbl_Shop_General.sql +105_tbl_Shop_General_Audit.sql +106_tbl_Shop_Category.sql +107_tbl_Shop_Category_Audit.sql +108_tbl_Shop_Recurrence_Interval.sql +109_tbl_Shop_Recurrence_Interval_Audit.sql +110.0_tbl_Shop_Region.sql +110.1_tbl_Shop_Region_Audit.sql +110.2_tbl_Shop_Region_Branch.sql +110.3_tbl_Shop_Region_Branch_Audit.sql +110.4_tbl_Shop_Currency.sql +110.5_tbl_Shop_Currency_Audit.sql +110.6_tbl_Shop_Tax_Or_Surcharge.sql +110.7_tbl_Shop_Tax_Or_Surcharge_Audit.sql +110.8_tbl_Shop_Product.sql +110.9_tbl_Shop_Product_Audit.sql +112_tbl_Shop_Variation_Type.sql +113.0_tbl_Shop_Variation_Type_Audit.sql +114_tbl_Shop_Variation.sql +115_tbl_Shop_Variation_Audit.sql +117.1_tbl_Shop_Product_Permutation.sql +117.2_tbl_Shop_Product_Permutation_Audit.sql +117.3_tbl_Shop_Product_Permutation_Variation_Link.sql +117.4_tbl_Shop_Product_Permutation_Variation_Link_Audit.sql +117.5_tbl_Shop_Product_Currency_Link.sql +117.5_tbl_Shop_Product_Currency_Region_Link.sql +117.6_tbl_Shop_Product_Currency_Link_Audit.sql +117.6_tbl_Shop_Product_Currency_Region_Link_Audit.sql +118_tbl_Shop_Image_Type.sql +119_tbl_Shop_Image_Type_Audit.sql +120_tbl_Shop_Image.sql +121_tbl_Shop_Image_Audit.sql +122_tbl_Shop_Delivery_Option.sql +123_tbl_Shop_Delivery_Option_Audit.sql +124_tbl_Shop_Product_Delivery_Option_Link.sql +125_tbl_Shop_Product_Delivery_Option_Link_Audit.sql +130.4_tbl_Shop_Discount.sql +131_tbl_Shop_Discount_Audit.sql +132_tbl_Shop_Discount_Region_Currency_Link.sql +133_tbl_Shop_Discount_Region_Currency_Link_Audit.sql +153_tbl_Shop_Permission_Group.sql +154_tbl_Shop_Permission_Group_Audit.sql +155_tbl_Shop_Permission.sql +156_tbl_Shop_Permission_Audit.sql +157_tbl_Shop_Role.sql +158_tbl_Shop_Role_Audit.sql +159_tbl_Shop_Role_Permission_Link.sql +160_tbl_Shop_Role_Permission_Link_Audit.sql +161_tbl_Shop_User.sql +162_tbl_Shop_User_Audit.sql +163_tbl_Shop_User_Role_Link.sql +164_tbl_Shop_User_Role_Link_Audit.sql +165_tbl_Shop_Address.sql +166_tbl_Shop_Address_Audit.sql +167_tbl_Shop_User_Basket.sql +168_tbl_Shop_User_Basket_Audit.sql +169_tbl_Shop_User_Order_Status.sql +170_tbl_Shop_User_Order_Status_Audit.sql +171_tbl_Shop_User_Order.sql +172_tbl_Shop_User_Order_Audit.sql +173_tbl_Shop_User_Order_Product_Link.sql +174_tbl_Shop_User_Order_Product_Link_Audit.sql +301.1_tri_Shop_User_Change_Set.sql +301.2_tri_Shop_Access_Level.sql +301_tri_Shop_Product_Change_Set.sql +302_tri_File_Type.sql +303_tri_File_Type_Audit.sql +304_tri_Shop_General.sql +306_tri_Shop_Category.sql +308_tri_Shop_Recurrence_Interval.sql +310.0_tri_Shop_Region.sql +310.2_tri_Shop_Region_Branch.sql +310.4_tri_Shop_Currency.sql +310.6_tri_Shop_Tax_Or_Surcharge.sql +310.8_tri_Shop_Product.sql +312_tri_Shop_Variation_Type.sql +314_tri_Shop_Variation.sql +317.1_tri_Shop_Product_Permutation.sql +317.3_tri_Shop_Product_Permutation_Variation_Link.sql +317.5_tri_Shop_Product_Currency_Link.sql +317.5_tri_Shop_Product_Currency_Region_Link.sql +318_tri_Shop_Image_Type.sql +320_tri_Shop_Image.sql +322_tri_Shop_Delivery_Option.sql +324_tri_Shop_Product_Delivery_Option_Link.sql +330_tri_Shop_Discount.sql +332_tri_Shop_Discount_Region_Currency_Link.sql +353_tri_Shop_Permission_Group.sql +355_tri_Shop_Permission.sql +357_tri_Shop_Role.sql +359_tri_Shop_Role_Permission_Link.sql +361_tri_Shop_User.sql +363_tri_Shop_User_Role_Link.sql +365_tri_Shop_Address.sql +367_tri_Shop_User_Basket.sql +369_tri_Shop_User_Order_Status.sql +371_tri_Shop_User_Order.sql +373_tri_Shop_User_Order_Product_Link.sql +600_p_shop_user_eval.sql +700_p_shop_get_many_product.sql +701_p_shop_edit_user.sql +702.1_p_shop_get_many_currency.sql +702.2_p_shop_get_many_region.sql +702_p_shop_edit_user_basket.sql +703_p_shop_get_many_user_order.sql +704_p_shop_get_many_stripe_product_new.sql +705_p_shop_get_many_stripe_price_new.sql +900_populate.sql +901_view.sql diff --git a/templates/DEPRECATED_block_store_product_price.html b/templates/DEPRECATED_block_store_product_price.html new file mode 100644 index 00000000..625e1ddc --- /dev/null +++ b/templates/DEPRECATED_block_store_product_price.html @@ -0,0 +1,16 @@ + + +
+

{{ product.output_price() }}

+ {% set form = product.form_basket_add %} +
+ {{ form.hidden_tag() }} + {% set tmp_quantity = 1 %} + {% include '_block_input_number_plus_minus.html' %} + {{ form.submit() }} +
+ +
\ No newline at end of file diff --git a/templates/DEPRECATED_page_home.html b/templates/DEPRECATED_page_home.html new file mode 100644 index 00000000..19a8025b --- /dev/null +++ b/templates/DEPRECATED_page_home.html @@ -0,0 +1,26 @@ +{% extends 'layout.html' %} + +{% block title %}{{ model.title }}{% endblock %} + +{% block page_body %} + + + + +
+
+

Offering a full suite of software engineering services.

+
+
+ + + + + +{% endblock %} \ No newline at end of file diff --git a/templates/DEPRECATEDlayout_store.html b/templates/DEPRECATEDlayout_store.html new file mode 100644 index 00000000..8c0dd880 --- /dev/null +++ b/templates/DEPRECATEDlayout_store.html @@ -0,0 +1,140 @@ + + + + + + {% block title %}{% endblock %} - PARTS + + + + + + + + + + + + + + +
+
+ +
+
+

Precision And Research Technology Systems Limited

+
+
+ +
+
+ Home +
+
+ Store +
+
+ +
+ {{ model.form_is_included_VAT.hidden_tag() }} +
+ {{ model.form_is_included_VAT.is_included.label }} + {{ model.form_is_included_VAT.is_included() }} + {% for error in model.form_is_included_VAT.is_included.errors %} +

{{ error }}

+ {% endfor %} +
+
+
+
+
+ {{ model.form_delivery_region.hidden_tag() }} +
+ {{ model.form_delivery_region.id_region_delivery.label }} + {{ model.form_delivery_region.id_region_delivery() }} + {% for error in model.form_delivery_region.id_region_delivery.errors %} +

{{ error }}

+ {% endfor %} +
+
+
+
+
+ {{ model.form_currency.hidden_tag() }} +
+ {{ model.form_currency.id_currency.label }} + {{ model.form_currency.id_currency() }} + {% for error in model.form_currency.id_currency.errors %} +

{{ error }}

+ {% endfor %} +
+
+
+ +
+ + +
+ {% block page_body %}{% endblock %} +
+ + + + + + + + + + + \ No newline at end of file diff --git a/templates/_block_input_number_plus_minus.html b/templates/_block_input_number_plus_minus.html new file mode 100644 index 00000000..906f8dbe --- /dev/null +++ b/templates/_block_input_number_plus_minus.html @@ -0,0 +1,17 @@ + + +
+
+
-
+
+
+ {{ form.quantity(value=tmp_quantity) }} +
+
+
+
+
+
\ No newline at end of file diff --git a/templates/_block_overlay_address.html b/templates/_block_overlay_address.html new file mode 100644 index 00000000..994d9775 --- /dev/null +++ b/templates/_block_overlay_address.html @@ -0,0 +1,10 @@ +{% extends '_template_overlay.html' %} + + +{% block overlay_body %} + {% include '_block_store_address.html' %} +{% endblock %} \ No newline at end of file diff --git a/templates/_block_store_address.html b/templates/_block_store_address.html new file mode 100644 index 00000000..d5575ffc --- /dev/null +++ b/templates/_block_store_address.html @@ -0,0 +1,79 @@ + + +
+ {{ form.hidden_tag() }} + + {% if form.form_type_billing_not_delivery %} +
+ {{ form.identical.label }} + {{ form.identical(checked=True) }} +
+ {% endif %} + +
+ {{ form.region.label }} + {{ form.region() }} + {% for error in form.region.errors %} +

{{ error }}

+ {% endfor %} +
+ +
+ {{ form.name_full.label }} + {{ form.name_full(size=100) }} + {% for error in form.name_full.errors %} +

{{ error }}

+ {% endfor %} +
+ +
+ {{ form.phone_number.label }} + {{ form.phone_number(size=20) }} + {% for error in form.phone_number.errors %} +

{{ error }}

+ {% endfor %} +
+ +
+ {{ form.postcode.label }} + {{ form.postcode(size=10) }} + {% for error in form.postcode.errors %} +

{{ error }}

+ {% endfor %} +
+ +
+ {{ form.address_1.label }} + {{ form.address_1(size=254) }} + {% for error in form.address_1.errors %} +

{{ error }}

+ {% endfor %} +
+ +
+ {{ form.address_2.label }} + {{ form.address_2(size=254) }} +
+ +
+ {{ form.city.label }} + {{ form.city(size=100) }} + {% for error in form.city.errors %} +

{{ error }}

+ {% endfor %} +
+ +
+ {{ form.county.label }} + {{ form.county(size=100) }} + {% for error in form.county.errors %} +

{{ error }}

+ {% endfor %} +
+ +
+ {{ form.submit() }} +
+
+ diff --git a/templates/_block_store_basket.html b/templates/_block_store_basket.html new file mode 100644 index 00000000..3e53f581 --- /dev/null +++ b/templates/_block_store_basket.html @@ -0,0 +1,18 @@ + +{% set show_delivery_option = False %} +
+
+
+

Basket

+ Basket icon +
+ {% for basket_item in model.basket.items %} + {% include '_block_store_basket_item.html' %} + {% endfor %} +

Total: {{ model.output_basket_total() }}

{% if not model.app.is_included_VAT %}

+ VAT

{% endif %} +

Buy some shit dawg!

+ + +
+
\ No newline at end of file diff --git a/templates/_block_store_basket_item.html b/templates/_block_store_basket_item.html new file mode 100644 index 00000000..d5eecfca --- /dev/null +++ b/templates/_block_store_basket_item.html @@ -0,0 +1,35 @@ + + +
+ {% set product = basket_item.product %} + {% set permutation = product.get_permutation_selected() %} +
+ Basket icon +
+ {% set form = product.form_basket_edit %} + +
+ {{ form.hidden_tag() }} +

{{ product.name }}

+ {% if permutation.is_available %} +

{{ basket_item.quantity }} x {{ product.output_price(model.app.is_included_VAT) }} = {{ basket_item.output_subtotal() }}

+ {% set tmp_quantity = basket_item.quantity %} + {% include '_block_input_number_plus_minus.html' %} + {% elif permutation.is_unavailable_in_currency_or_region %} +

Product not available in currency and region

+ {% else %} +

Product not available

+ {% endif %} + Delete + {% if show_delivery_option %} +
+ {{ product.form_delivery_option.label }} + {{ product.form_delivery_option() }} +
+ {% endif %} + +
+
\ No newline at end of file diff --git a/templates/_block_store_product.html b/templates/_block_store_product.html new file mode 100644 index 00000000..f2dfadb9 --- /dev/null +++ b/templates/_block_store_product.html @@ -0,0 +1,22 @@ + +{% set permutation = product.get_permutation_selected() %} +
+
+ Template product image +
+ {% set form = product.form_basket_add %} +
+ {{ form.hidden_tag() }} +

{{ product.name }}

+

{{ permutation.output_price(model.app.is_included_VAT) }}

+ {% if permutation.is_available %} + {% set tmp_quantity = 1 %} + {% include '_block_input_number_plus_minus.html' %} + {{ form.submit() }} +

Get it: {{ permutation.output_delivery_date() }}

+ {% endif %} +
+ +
\ No newline at end of file diff --git a/templates/_block_store_product_category.html b/templates/_block_store_product_category.html new file mode 100644 index 00000000..58066b27 --- /dev/null +++ b/templates/_block_store_product_category.html @@ -0,0 +1,9 @@ + +
+

{{ cat.name }}

+
+ {% for product in cat.products %} + {% include '_block_store_product.html' %} + {% endfor %} +
+
\ No newline at end of file diff --git a/templates/_page_contact.html b/templates/_page_contact.html new file mode 100644 index 00000000..d2d1e34c --- /dev/null +++ b/templates/_page_contact.html @@ -0,0 +1,94 @@ +{% extends 'layout.html' %} + +{% block title %}{{ model.title }}{% endblock %} + +{% block page_body %} + + + + +
+
+

Complete the form or find our details below.

+ + {{ model.form.hidden_tag() }} +
+ {{ model.form.email.label }} + {{ model.form.email(size=254) }} + {% for error in model.form.email.errors %} +

{{ error }}

+ {% endfor %} +
+ +
+ {{ model.form.name.label }} + {{ model.form.name(size=50) }} + {% for error in model.form.name.errors %} +

{{ error }}

+ {% endfor %} +
+
+ {{ model.form.msg.label }} + {{ model.form.msg(rows=4, cols=80) }} + {% for error in model.form.name.errors %} +

{{ error }}

+ {% endfor %} +
+
+ {{ model.form.submit() }} +
+
+
+ +
+

Contact Details

+
+

edward.middletonsmith@gmail.com

+

LinkedIn

+

GitHub

+
+
+

Unit 12c, Somers Road

+

Rugby, Warwickshire

+

CV22 7DH

+
+
+ + + + + +{% endblock %} \ No newline at end of file diff --git a/templates/_page_home.html b/templates/_page_home.html new file mode 100644 index 00000000..6f186074 --- /dev/null +++ b/templates/_page_home.html @@ -0,0 +1,142 @@ +{% extends 'layout.html' %} + +{% block title %}{{ model.title }}{% endblock %} + +{% block page_body %} + + + + +
+
+

Offering a full suite of software engineering services.

+
+
+
+
+

Web App & Database Design

+

Crafting seamless digital experiences with expertly designed web applications and robust database solutions.

+
+
+ + + +
+
+
+
+

Programming services (C++, Python, etc.)

+

Empowering businesses with efficient automation, web manipulation, and cutting-edge AI/ML solutions for complex tasks.

+
+
+ + + + +
+
+
+
+

MS Office Data Analysis & Automation

+

Unleashing the power of MS Office for streamlined data analysis, automation, and enhanced productivity across Excel, PowerPoint, and Outlook.

+
+
+ + + + +
+
+
+
+

Mechatronics Design

+

Integrating mechanical and electronic components seamlessly for innovative mechatronic solutions, elevating your product design.

+
+
+ + + + Mechatronics design gif +
+
+
+
+

CAD, DFM, DFAM

+

Transforming concepts into reality with precision CAD designs, Design for Manufacturing (DFM), and Design for Additive Manufacturing (DFAM) expertise.

+
+
+ + + + Computer aided design gif +
+
+
+
+

Photopolymerisation, Materials Science, AM Advice

+

Navigating the forefront of materials science and additive manufacturing, providing expert advice on photopolymerisation and innovative AM solutions.

+
+
+ + + +
+
+ + + + + +{% endblock %} \ No newline at end of file diff --git a/templates/_page_store_admin_home.html b/templates/_page_store_admin_home.html new file mode 100644 index 00000000..90061e55 --- /dev/null +++ b/templates/_page_store_admin_home.html @@ -0,0 +1,78 @@ +{% extends 'layout.html' %} + +{% block title %}{{ model.title }}{% endblock %} + +{% block page_body %} + + + + +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+

About Us

+ Molly tag image +

We are open for business!

+
+
+
+
+

Promoted content

+
+
+ Braille translator demo image +
+
+

Braille Keyboard Learning Tool

+
+
+
+
+ Prosthetics demo gif +
+
+

FREE Prosthetic Hands by e-NABLE

+
+
+
+
+
+
+

Where to find us

+

LinkedIn

+

GitHub

+
+
+
+
+ + + + + + +{% endblock %} \ No newline at end of file diff --git a/templates/_page_store_basket.html b/templates/_page_store_basket.html new file mode 100644 index 00000000..483948b6 --- /dev/null +++ b/templates/_page_store_basket.html @@ -0,0 +1,89 @@ +{% extends 'layout.html' %} + +{% block title %}{{ model.title }}{% endblock %} + +{% block page_body %} + + {% set block_id = 'styles' %} + {% include '_shared_store.html' %} + + + +
+
+
+

Delivery Information

+
+ Valid delivery information not submitted +
+
+
+

Billing Information

+
+ Valid billing information not submitted +
+
+
+
+ {% include '_block_store_basket.html' %} +
+ +
+
+
+ + {% set form = model.form_delivery %} + {% set overlay_id = model.id_overlay_info_delivery %} + {% set overlay_title = 'Delivery Information' %} + {% include '_block_overlay_address.html' %} + + {% set form = model.form_billing %} + {% set overlay_id = model.id_overlay_info_billing %} + {% set overlay_title = 'Billing Information' %} + {% include '_block_overlay_address.html' %} + + + + {% set block_id = 'scripts' %} + {% include '_shared_store.html' %} + + + +{% endblock %} \ No newline at end of file diff --git a/templates/_page_store_checkout_success.html b/templates/_page_store_checkout_success.html new file mode 100644 index 00000000..2f5a1451 --- /dev/null +++ b/templates/_page_store_checkout_success.html @@ -0,0 +1,63 @@ +{% extends 'layout.html' %} + +{% block title %}{{ model.title }}{% endblock %} + +{% block page_body %} + + {% set block_id = 'styles' %} + {% include '_shared_store.html' %} + + + +
+
+
+

Order successful!

+
+
Order reference: {{ model.checkout_session.id }}
+
You will receive an order acknowledgement by email
+
+ {% if model.is_user_logged_in %} +
+

Your order:

+
+ {% endif %} +
+
+
+ + + {% set block_id = 'scripts' %} + {% include '_shared_store.html' %} + + + +{% endblock %} \ No newline at end of file diff --git a/templates/_page_store_home.html b/templates/_page_store_home.html new file mode 100644 index 00000000..d635677c --- /dev/null +++ b/templates/_page_store_home.html @@ -0,0 +1,37 @@ +{% extends 'layout.html' %} + +{% block title %}{{ model.title }}{% endblock %} + +{% block page_body %} + {% set block_id = 'styles' %} + {% include '_shared_store.html' %} + + + + +
+
+ {% for cat in model.category_list.categories %} + {% include '_block_store_product_category.html' %} + {% endfor %} +
+
+ {% include '_block_store_basket.html' %} +
+
+ + {% set block_id = 'scripts' %} + {% include '_shared_store.html' %} + + + + +{% endblock %} \ No newline at end of file diff --git a/templates/_page_store_product.html b/templates/_page_store_product.html new file mode 100644 index 00000000..5083f27a --- /dev/null +++ b/templates/_page_store_product.html @@ -0,0 +1,53 @@ +{% extends 'layout.html' %} + +{% block title %}{{ model.title }}{% endblock %} + +{% block page_body %} + {% set product = model.product %} + {% set permutation = product.get_permutation_selected() %} + {% set block_id = 'styles' %} + {% include '_shared_store.html' %} + + + + +
+
+
+
+
+
+

{{ product.get_name() }}

+ +
+ {% include '_block_store_product_price.html' %} +
+
+
{{ permutation.description }}
+
+
+
+
+
+ {% include '_block_store_basket.html' %} +
+
+ + {% set block_id = 'scripts' %} + {% include '_shared_store.html' %} + + + + +{% endblock %} \ No newline at end of file diff --git a/templates/_shared_store.html b/templates/_shared_store.html new file mode 100644 index 00000000..206c2974 --- /dev/null +++ b/templates/_shared_store.html @@ -0,0 +1,51 @@ +{% if block_id == 'block1' %} +
+

Feckin common block boi

+
+{% elif block_id == 'styles' %} + + +{% elif block_id == 'scripts' %} + + + + +{% endif %} \ No newline at end of file diff --git a/templates/_template_overlay.html b/templates/_template_overlay.html new file mode 100644 index 00000000..464f817e --- /dev/null +++ b/templates/_template_overlay.html @@ -0,0 +1,23 @@ + + + + +
+
+
+
+

{{ overlay_title }}

+
+
+ +
+
+
+ {% block overlay_body %}{% endblock %} +
+
+
+ diff --git a/templates/layout - stripe.html b/templates/layout - stripe.html new file mode 100644 index 00000000..1d3da4a5 --- /dev/null +++ b/templates/layout - stripe.html @@ -0,0 +1,66 @@ + + + + + + {% block title %}{% endblock %} - PARTS + + + + + + + + + + +
+
+ +
+
+

Precision And Research Technology Systems Limited

+
+
+ +
+ Home + Store + + Contact +
+ +
+ {% block content %}{% endblock %} +
+ + + + + + + + + + \ No newline at end of file diff --git a/templates/layout.html b/templates/layout.html new file mode 100644 index 00000000..bca6b428 --- /dev/null +++ b/templates/layout.html @@ -0,0 +1,206 @@ + + + + + + {% block title %}{% endblock %} - PARTS + + + + + + + + + + + + + + +
+
+ +
+
+

Precision And Research Technology Systems Limited

+
+
+ +
+
+ Home +
+
+ Services +
+ +
+ Store +
+
+ Contact +
+ {% if model.is_page_store %} +
+ +
+ {{ model.form_is_included_VAT.hidden_tag() }} +
+ {{ model.form_is_included_VAT.is_included.label }} + {{ model.form_is_included_VAT.is_included() }} + {% for error in model.form_is_included_VAT.is_included.errors %} +

{{ error }}

+ {% endfor %} +
+
+
+
+
+ {{ model.form_delivery_region.hidden_tag() }} +
+ {{ model.form_delivery_region.id_region_delivery.label }} + {{ model.form_delivery_region.id_region_delivery() }} + {% for error in model.form_delivery_region.id_region_delivery.errors %} +

{{ error }}

+ {% endfor %} +
+
+
+
+
+ {{ model.form_currency.hidden_tag() }} +
+ {{ model.form_currency.id_currency.label }} + {{ model.form_currency.id_currency() }} + {% for error in model.form_currency.id_currency.errors %} +

{{ error }}

+ {% endfor %} +
+
+
+ + {% endif %} +
+ + + + +
+ {% block page_body %}{% endblock %} +
+ + + + + + + + + + +