diff --git a/.gitignore b/.gitignore index 2714bdf..6456288 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ test.py .VScodeCounter celerybeat-schedule instance/application.cfg.py +docs diff --git a/application/access_module/__pycache__/access_processes.cpython-313.pyc b/application/access_module/__pycache__/access_processes.cpython-313.pyc new file mode 100644 index 0000000..8dfe248 Binary files /dev/null and b/application/access_module/__pycache__/access_processes.cpython-313.pyc differ diff --git a/application/database_postgres/BaseModel.py b/application/database_postgres/BaseModel.py index 7c446c3..4e345e4 100644 --- a/application/database_postgres/BaseModel.py +++ b/application/database_postgres/BaseModel.py @@ -234,6 +234,7 @@ class BaseModel(ABC): @classmethod def select_tuple(self, site: str, payload: dict, convert: bool = True, conn=None): + ''' payload = {'key': value_to_filter}''' record = () self_conn = False @@ -264,7 +265,41 @@ class BaseModel(ABC): except Exception as error: raise DatabaseError(error, payload, sql) + + @classmethod + def select_tuples_by_key(self, site: str, payload: dict, convert: bool = True, conn=None): + '''payload = {'key'}''' + records = () + self_conn = False + if self.site_agnostic: + sql = f"SELECT * FROM {self.table_name} WHERE {self.primary_key} = %(key)s::{self.primary_key_type};" + else: + sql = f"SELECT * FROM {site}_{self.table_name} WHERE {self.primary_key} = %(key)s::{self.primary_key_type};" + try: + if not conn: + database_config = config.config() + conn = psycopg2.connect(**database_config) + conn.autocommit = True + self_conn = True + + with conn.cursor() as cur: + cur.execute(sql, payload) + rows = cur.fetchall() + if rows and convert: + records = [tupleDictionaryFactory(cur.description, row) for row in rows] + elif rows and not convert: + records = rows + + if self_conn: + conn.commit() + conn.close() + + return records + + except Exception as error: + raise DatabaseError(error, {}, sql) + @classmethod def select_tuples(self, site: str, convert: bool = True, conn=None): records = () diff --git a/application/database_postgres/CostLayersModel.py b/application/database_postgres/CostLayersModel.py index 0fcfb46..ec70814 100644 --- a/application/database_postgres/CostLayersModel.py +++ b/application/database_postgres/CostLayersModel.py @@ -1,17 +1,93 @@ from dataclasses import dataclass import datetime -from application.database_postgres.BaseModel import BasePayload, BaseModel +import config +import psycopg2 +from application.database_postgres.BaseModel import BasePayload, BaseModel, tupleDictionaryFactory, DatabaseError, updateStringFactory class CostLayersModel(BaseModel): table_name = "cost_layers" + primary_key = "item_location_uuid" + primary_key_type = "uuid" @dataclass class Payload(BasePayload): - aquisition_date: datetime.datetime - quantity: float - cost: float - currency_type: str - vendor: int = 0 - expires: datetime.datetime = None - \ No newline at end of file + item_location_uuid: str + layer_aquisition_date: datetime.datetime + layer_quantity: float + layer_cost: float + layer_currency_type: str + layer_vendor: str = None + layer_expires: datetime.datetime = None + + @classmethod + def delete_by_layer_id(self, site: str, payload: tuple, convert: bool = True, conn=None): + """ Pass a tuple of layer_ids to remove from the database. + + Args: + site (str): name of the site to delete from + payload (tuple): a tuple of layer_ids + convert (bool, optional): whether to return the deleted rows as dictionaries. Defaults to True. + conn (_type_, optional): postgresql connector object. Defaults to None. + + Raises: + DatabaseError: raised for all errors with database handling, logs to database.log + + Returns: + dict, list: returns a list of all deleted rows. + """ + deleted = () + self_conn = False + sql = f"WITH deleted_rows AS (DELETE FROM {site}_{self.table_name} WHERE layer_id IN ({','.join(['%s'] * len(payload))}) RETURNING *) SELECT * FROM deleted_rows;" + try: + if not conn: + database_config = config.config() + conn = psycopg2.connect(**database_config) + conn.autocommit = True + self_conn = True + + with conn.cursor() as cur: + cur.execute(sql, payload) + rows = cur.fetchall() + if rows and convert: + deleted = [tupleDictionaryFactory(cur.description, r) for r in rows] + elif rows and not convert: + deleted = rows + + if self_conn: + conn.commit() + conn.close() + + return deleted + except Exception as error: + raise DatabaseError(error, payload, sql) + + @classmethod + def update_by_layer_id(self, site: str, payload:dict, convert=True, conn=None): + updated = () + self_conn = False + set_clause, values = updateStringFactory(payload['update']) + values.append(payload['key']) + sql = f"UPDATE {site}_{self.table_name} SET {set_clause} WHERE layer_id=%s RETURNING *;" + try: + if not conn: + database_config = config.config() + conn = psycopg2.connect(**database_config) + conn.autocommit = False + self_conn = True + + with conn.cursor() as cur: + cur.execute(sql, values) + rows = cur.fetchone() + if rows and convert: + updated = tupleDictionaryFactory(cur.description, rows) + elif rows and not convert: + updated = rows + + if self_conn: + conn.commit() + conn.close() + + return updated + except Exception as error: + raise DatabaseError(error, payload, sql) \ No newline at end of file diff --git a/application/database_postgres/ItemLocationsModel.py b/application/database_postgres/ItemLocationsModel.py index 3d023df..c883df9 100644 --- a/application/database_postgres/ItemLocationsModel.py +++ b/application/database_postgres/ItemLocationsModel.py @@ -1,5 +1,9 @@ from dataclasses import dataclass, field -from application.database_postgres.BaseModel import BasePayload, BaseModel, lst2pgarr +from application.database_postgres.BaseModel import BasePayload, BaseModel, lst2pgarr, tupleDictionaryFactory, DatabaseError + +import config + +import psycopg2 class ItemLocationsModel(BaseModel): table_name = "item_locations" @@ -11,4 +15,32 @@ class ItemLocationsModel(BaseModel): item_uuid: str location_uuid: str item_quantity_on_hand: float = 0.0 - \ No newline at end of file + + @classmethod + def select_by_location_and_item(self, site:str, payload:dict, convert: bool=True, conn = None): + recordset = () + self_conn = False + sql = f"SELECT * FROM {site}_item_locations WHERE item_uuid = %(item_uuid)s AND location_uuid = %(location_uuid)s;" + try: + if not conn: + database_config = config.config() + conn = psycopg2.connect(**database_config) + conn.autocommit = True + self_conn = True + + with conn.cursor() as cur: + cur.execute(sql, payload) + rows = cur.fetchone() + if rows and convert: + recordset = tupleDictionaryFactory(cur.description, rows) + if rows and not convert: + recordset = rows + + + if self_conn: + conn.close() + + return recordset + + except Exception as error: + raise DatabaseError(error, payload, sql) \ No newline at end of file diff --git a/application/database_postgres/ItemsModel.py b/application/database_postgres/ItemsModel.py index 337ecbe..c0b29b9 100644 --- a/application/database_postgres/ItemsModel.py +++ b/application/database_postgres/ItemsModel.py @@ -33,6 +33,35 @@ class ItemsModel(BaseModel): payload['item_links'] = json.dumps(self.item_links) return payload + @classmethod + def get_item_by_uuid(self, site:str, payload: dict, convert: bool=True, conn = None): + record = () + self_conn = False + with open('application/database_postgres/sql/ItemsModel/getItemAllByUUID.sql', 'r+') as file: + sql = file.read().replace("%%site_name%%", site) + try: + if not conn: + database_config = config.config() + conn = psycopg2.connect(**database_config) + conn.autocommit = True + self_conn = True + + with conn.cursor() as cur: + cur.execute(sql, payload) + rows = cur.fetchone() + if rows and convert: + record = tupleDictionaryFactory(cur.description, rows) + if rows and not convert: + record = rows + + if self_conn: + conn.close() + + return record + + except Exception as error: + raise DatabaseError(error, payload, sql) + @classmethod def paginate_items_with_qoh(self, site:str, payload: dict, convert: bool=True, conn = None): recordset = () diff --git a/application/database_postgres/TransactionsModel.py b/application/database_postgres/TransactionsModel.py index aa5bd9e..bd0c9bc 100644 --- a/application/database_postgres/TransactionsModel.py +++ b/application/database_postgres/TransactionsModel.py @@ -6,7 +6,7 @@ from application.database_postgres.BaseModel import BasePayload, BaseModel class TransactionsModel(BaseModel): table_name = "transactions" - primary_key = "item_uuid" + primary_key = "transaction_uuid" primary_key_type = "uuid" @dataclass diff --git a/application/database_postgres/__pycache__/BaseModel.cpython-313.pyc b/application/database_postgres/__pycache__/BaseModel.cpython-313.pyc index 611c1b8..cd77b68 100644 Binary files a/application/database_postgres/__pycache__/BaseModel.cpython-313.pyc and b/application/database_postgres/__pycache__/BaseModel.cpython-313.pyc differ diff --git a/application/database_postgres/__pycache__/CostLayersModel.cpython-313.pyc b/application/database_postgres/__pycache__/CostLayersModel.cpython-313.pyc index f2fd2c5..fdde6a4 100644 Binary files a/application/database_postgres/__pycache__/CostLayersModel.cpython-313.pyc and b/application/database_postgres/__pycache__/CostLayersModel.cpython-313.pyc differ diff --git a/application/database_postgres/__pycache__/ItemLocationsModel.cpython-313.pyc b/application/database_postgres/__pycache__/ItemLocationsModel.cpython-313.pyc index ef0d38f..c7e1a5f 100644 Binary files a/application/database_postgres/__pycache__/ItemLocationsModel.cpython-313.pyc and b/application/database_postgres/__pycache__/ItemLocationsModel.cpython-313.pyc differ diff --git a/application/database_postgres/__pycache__/ItemsModel.cpython-313.pyc b/application/database_postgres/__pycache__/ItemsModel.cpython-313.pyc index c3ed4ec..6c6d4a6 100644 Binary files a/application/database_postgres/__pycache__/ItemsModel.cpython-313.pyc and b/application/database_postgres/__pycache__/ItemsModel.cpython-313.pyc differ diff --git a/application/database_postgres/__pycache__/TransactionsModel.cpython-313.pyc b/application/database_postgres/__pycache__/TransactionsModel.cpython-313.pyc index 14fc344..51985c1 100644 Binary files a/application/database_postgres/__pycache__/TransactionsModel.cpython-313.pyc and b/application/database_postgres/__pycache__/TransactionsModel.cpython-313.pyc differ diff --git a/application/database_postgres/sql/CREATE/cost_layers.sql b/application/database_postgres/sql/CREATE/cost_layers.sql index 566c74a..52e9725 100644 --- a/application/database_postgres/sql/CREATE/cost_layers.sql +++ b/application/database_postgres/sql/CREATE/cost_layers.sql @@ -1,4 +1,5 @@ CREATE TABLE IF NOT EXISTS %%site_name%%_cost_layers ( + layer_id SERIAL UNIQUE, item_location_uuid UUID REFERENCES %%site_name%%_item_locations(item_location_uuid) ON DELETE SET NULL, layer_aquisition_date TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL, layer_quantity FLOAT8 DEFAULT 0.00 NOT NULL, diff --git a/application/database_postgres/sql/CREATE/item_info.sql b/application/database_postgres/sql/CREATE/item_info.sql index 02f9fe2..e85c480 100644 --- a/application/database_postgres/sql/CREATE/item_info.sql +++ b/application/database_postgres/sql/CREATE/item_info.sql @@ -7,5 +7,5 @@ CREATE TABLE IF NOT EXISTS %%site_name%%_item_info ( item_safety_stock FLOAT8 DEFAULT 0.00 NOT NULL, item_lead_time_days FLOAT8 DEFAULT 0.00 NOT NULL, item_ai_pick BOOLEAN DEFAULT false NOT NULL, - item_prefixes INTEGER [] DEFAULT '{}' NOT NULL + item_prefixes UUID [] DEFAULT '{}' NOT NULL ); \ No newline at end of file diff --git a/application/database_postgres/sql/CREATE/transactions.sql b/application/database_postgres/sql/CREATE/transactions.sql index e24facd..dad4da9 100644 --- a/application/database_postgres/sql/CREATE/transactions.sql +++ b/application/database_postgres/sql/CREATE/transactions.sql @@ -1,6 +1,6 @@ CREATE TABLE IF NOT EXISTS %%site_name%%_transactions ( - item_uuid UUID PRIMARY KEY REFERENCES %%site_name%%_items(item_uuid) ON DELETE CASCADE, - transaction_uuid UUID DEFAULT uuid_generate_v4() NOT NULL; + transaction_uuid UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + item_uuid UUID REFERENCES %%site_name%%_items(item_uuid) ON DELETE CASCADE NOT NULL, transaction_created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL, transaction_name VARCHAR(255) DEFAULT NULL, transaction_type VARCHAR(64) DEFAULT '' NOT NULL, diff --git a/application/database_postgres/sql/INSERT/cost_layers.sql b/application/database_postgres/sql/INSERT/cost_layers.sql index 5515a0e..2651ced 100644 --- a/application/database_postgres/sql/INSERT/cost_layers.sql +++ b/application/database_postgres/sql/INSERT/cost_layers.sql @@ -1,4 +1,4 @@ INSERT INTO %%site_name%%_cost_layers -(aquisition_date, quantity, cost, currency_type, expires, vendor) -VALUES (%(aquisition_date)s, %(quantity)s, %(cost)s, %(currency_type)s, %(expires)s, %(vendor)s) +(item_location_uuid, layer_aquisition_date, layer_quantity, layer_cost, layer_currency_type, layer_expires, layer_vendor) +VALUES (%(item_location_uuid)s::uuid, %(layer_aquisition_date)s, %(layer_quantity)s, %(layer_cost)s, %(layer_currency_type)s, %(layer_expires)s, %(layer_vendor)s) RETURNING *; \ No newline at end of file diff --git a/application/database_postgres/sql/ItemsModel/getItemAllByUUID.sql b/application/database_postgres/sql/ItemsModel/getItemAllByUUID.sql new file mode 100644 index 0000000..c63242e --- /dev/null +++ b/application/database_postgres/sql/ItemsModel/getItemAllByUUID.sql @@ -0,0 +1,44 @@ +WITH passed_uuid AS (SELECT %(item_uuid)s::uuid AS passed_uuid), + cte_conversions AS ( + SELECT * + FROM %%site_name%%_conversions conversion + WHERE conversion.item_uuid = (SELECT passed_uuid FROM passed_uuid) + ), + cte_item_info AS (SELECT item_info.*, + COALESCE((SELECT json_agg(convs) FROM cte_conversions convs), '[]'::json) AS conversions, + COALESCE((SELECT json_agg(p.*) FROM %%site_name%%_sku_prefix p WHERE p.sku_prefix_uuid = ANY(item_info.item_prefixes)), '[]'::json) as prefixes + FROM %%site_name%%_item_info item_info + WHERE item_info.item_uuid = (SELECT passed_uuid FROM passed_uuid) + ), + cte_food_info AS (SELECT * + FROM %%site_name%%_food_info food_info + WHERE food_info.item_uuid = (SELECT passed_uuid FROM passed_uuid) + ), + cte_logistics_info AS (SELECT * + FROM %%site_name%%_logistics_info log_info + WHERE log_info.item_uuid = (SELECT passed_uuid FROM passed_uuid) + ), + cte_item_locations AS ( + SELECT * FROM %%site_name%%_item_locations item_locations + LEFT JOIN %%site_name%%_locations locations ON locations.location_uuid = item_locations.location_uuid + WHERE item_locations.item_uuid = (SELECT passed_uuid FROM passed_uuid) + ), + cte_barcodes AS ( + SELECT + barcode.barcode As barcode, + barcode.in_exchange AS in_exchange, + barcode.out_exchange AS out_exchange, + barcode.descriptor AS descriptor + FROM %%site_name%%_barcodes AS barcode + LEFT JOIN %%site_name%%_items AS item ON item.item_uuid = (SELECT passed_uuid FROM passed_uuid) + WHERE barcode.item_uuid = item.item_uuid + ) + +SELECT item.*, +(SELECT COALESCE(row_to_json(ii), '{}') FROM cte_item_info ii) AS item_info, +(SELECT COALESCE(row_to_json(fi), '{}') FROM cte_food_info fi) AS food_info, +(SELECT COALESCE(row_to_json(li), '{}') FROM cte_logistics_info li) AS logistics_info, +(SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations, +(SELECT COALESCE(array_agg(row_to_json(bar)), '{}') FROM cte_barcodes bar) AS item_barcodes +FROM %%site_name%%_items item +WHERE item.item_uuid=(SELECT passed_uuid FROM passed_uuid) diff --git a/application/items/__pycache__/items_API.cpython-313.pyc b/application/items/__pycache__/items_API.cpython-313.pyc index a6f45a0..da55cdb 100644 Binary files a/application/items/__pycache__/items_API.cpython-313.pyc and b/application/items/__pycache__/items_API.cpython-313.pyc differ diff --git a/application/items/__pycache__/services.cpython-313.pyc b/application/items/__pycache__/services.cpython-313.pyc index 6f550a3..1186726 100644 Binary files a/application/items/__pycache__/services.cpython-313.pyc and b/application/items/__pycache__/services.cpython-313.pyc differ diff --git a/application/items/items_API.py b/application/items/items_API.py index e1ebbe5..5981073 100644 --- a/application/items/items_API.py +++ b/application/items/items_API.py @@ -18,8 +18,9 @@ import application.database_payloads as dbPayloads from application.database_postgres.UsersModel import UsersModel from application.database_postgres.SitesModel import SitesModel from application.database_postgres.UnitsModel import UnitsModel -from application.items import models +from application.items import models, services from application.database_postgres.ItemsModel import ItemsModel +from application.database_postgres.TransactionsModel import TransactionsModel items_api = Blueprint('items_api', __name__, template_folder="templates", static_folder="static") @@ -44,7 +45,7 @@ def items(): def item(item_uuid): sites = [SitesModel.select_tuple('', {'key': site})['site_name'] for site in session['user'].get('user_sites', [])] units = UnitsModel.select_tuples('') - return render_template("item_new.html", id=id, units=units, current_site=session['selected_site'], sites=sites) + return render_template("item_new.html", item_uuid=item_uuid, units=units, current_site=session['selected_site'], sites=sites) @items_api.route("/transaction") @access_api.login_required @@ -82,9 +83,10 @@ def getTransactions(): def getTransaction(): transaction = () if request.method == "GET": - id = int(request.args.get('id', 1)) - site_name = session['selected_site'] - transaction = database_items.getTransaction(site_name, (id, )) + transaction_uuid = int(request.args.get('transaction_uuid', None)) + if transaction_uuid: + site_name = session['selected_site'] + transaction = TransactionsModel.select_tuple(site_name, {'key': transaction_uuid}) return jsonify({"transaction": transaction, "error": False, "message": ""}) return jsonify({"transaction": transaction, "error": True, "message": f"method {request.method} is not allowed."}) @@ -92,11 +94,13 @@ def getTransaction(): @access_api.login_required def get_item(): if request.method == "GET": - id = int(request.args.get('id', 1)) - site_name = session['selected_site'] + item_uuid = request.args.get('item_uuid', None) item = () - - item = database_items.getItemAllByID(site_name, (id, )) + print(item_uuid) + if item_uuid: + site_name = session['selected_site'] + item = ItemsModel.get_item_by_uuid(site_name, {'item_uuid': item_uuid}) + print(item) return jsonify({'item': item, 'error': False, 'message': ''}) return jsonify({'item': item, 'error': True, 'message': f'method {request.method} not allowed.'}) @@ -424,15 +428,13 @@ def getItemLocations(): return jsonify({"locations":recordset, "end":math.ceil(count/limit), "error":False, "message":"item fetched succesfully!"}) return jsonify({"locations":recordset, "end": math.ceil(count/limit), "error":True, "message":"There was an error with this GET statement"}) + @items_api.route('/postTransaction', methods=["POST"]) @access_api.login_required def post_transaction(): if request.method == "POST": - result = items_processes.postAdjustment( - site_name=session['selected_site'], - user_id=session['user_id'], - data=dict(request.json) - ) + print(session.keys()) + result = services.postAdjustment(site_name=session['selected_site'], user_uuid=session['user_uuid'], data=request.get_json()) return jsonify(result) return jsonify({"error":True, "message":"There was an error with this POST statement"}) diff --git a/application/items/services.py b/application/items/services.py index 6e4fb09..087a663 100644 --- a/application/items/services.py +++ b/application/items/services.py @@ -1,4 +1,5 @@ import psycopg2 +import datetime from application.database_postgres.ItemsModel import ItemsModel from application.database_postgres.ItemInfoModel import ItemInfoModel @@ -6,6 +7,7 @@ from application.database_postgres.LogisticsInfoModel import LogisticsInfoModel from application.database_postgres.FoodInfoModel import FoodInfoModel from application.database_postgres.TransactionsModel import TransactionsModel from application.database_postgres.ItemLocationsModel import ItemLocationsModel +from application.database_postgres.CostLayersModel import CostLayersModel import config def add_new_item(site: str, data: dict, user_uuid: str, conn=None): @@ -42,7 +44,7 @@ def add_new_item(site: str, data: dict, user_uuid: str, conn=None): ) items_location = ItemLocationsModel.insert_tuple(site, items_location.payload_dictionary(), conn=conn) - if item['item_category'] in ['FOOD', 'FOOD PLU']: + if item['item_category'] in ['FOOD', 'FOOD_PLU']: food_info['item_uuid'] = item['item_uuid'] food_info_payload = FoodInfoModel.Payload(**food_info) food_info = FoodInfoModel.insert_tuple(site, food_info_payload.payload_dictionary(), conn=conn) @@ -58,4 +60,93 @@ def add_new_item(site: str, data: dict, user_uuid: str, conn=None): if self_conn: conn.commit() - conn.close() \ No newline at end of file + conn.close() + +def postAdjustment(site_name, user_uuid, data: dict, conn=None): + """ This process handles manual transactions found at /items/transaction endpoint + + Args: + site_name (_type_): _description_ + user_uuid (_type_): _description_ + data (dict): dataKEYS = {'item_uuid', 'item_name', 'transaction_type', 'transaction_quantity', 'transaction_description', 'transaction_cost', 'transaction_vendor', 'trans_action_expires', 'location_uuid'} + conn (_type_, optional): _description_. Defaults to None. + """ + def quantityFactory(quantity_on_hand:float, quantity:float, transaction_type:str): + if transaction_type == "Adjust In": + quantity_on_hand += quantity + return quantity_on_hand + if transaction_type == "Adjust Out": + quantity_on_hand -= quantity + return quantity_on_hand + raise Exception("The transaction type is wrong!") + + self_conn = False + + if not conn: + database_config = config.config() + conn = psycopg2.connect(**database_config) + conn.autocommit = False + self_conn = True + + transaction_data = { + 'item_uuid': data['item_uuid'], + 'transaction_created_by': user_uuid, + 'transaction_name': data['item_name'], + 'transaction_type': data['transaction_type'], + 'transaction_quantity': data['transaction_quantity'], + 'transaction_cost': data['transaction_cost'], + 'transaction_description': data['transaction_description'] + } + + transaction = TransactionsModel.Payload(**transaction_data) + + location = ItemLocationsModel.select_by_location_and_item(site_name, {'item_uuid': data['item_uuid'], 'location_uuid': data['location_uuid']}) + + cost_layer_data = { + 'item_location_uuid': location['item_location_uuid'], + 'layer_aquisition_date': datetime.datetime.now(), + 'layer_quantity': data['transaction_quantity'], + 'layer_cost': data['transaction_cost'], + 'layer_currency_type': "USD" + } + + new_cost_layer = CostLayersModel.Payload(**cost_layer_data) + + cost_layers = list(CostLayersModel.select_tuples_by_key(site_name, {'key': location['item_location_uuid']}, conn=conn)) + print(cost_layers) + cost_layers.sort(key=lambda x: x['layer_aquisition_date']) + + if data['transaction_type'] == "Adjust In": + CostLayersModel.insert_tuple(site_name, new_cost_layer.payload_dictionary(), conn=conn) + + if data['transaction_type'] == "Adjust Out": + if float(location['item_quantity_on_hand']) < float(data['transaction_quantity']): + pass + else: + qty = float(data['transaction_quantity']) + for layer in cost_layers: + if qty >= float(layer['layer_quantity']): + qty -= float(layer['layer_quantity']) + layer['layer_quantity'] = 0.0 + else: + layer['layer_quantity'] -= qty + CostLayersModel.update_by_layer_id(site_name, {'key': layer['layer_id'], 'update': {'layer_quantity': layer['layer_quantity']}}, conn=conn) + qty = 0.0 + + if layer['layer_quantity'] == 0.0: + CostLayersModel.delete_by_layer_id(site_name, (layer['layer_id'],), conn=conn) + + quantity_on_hand = quantityFactory(float(location['item_quantity_on_hand']), data['transaction_quantity'], data['transaction_type']) + + ItemLocationsModel.update_tuple(site_name, {'key': location['item_location_uuid'], 'update': {'item_quantity_on_hand': quantity_on_hand}}, conn=conn) + + transaction.data = {'location': location['item_location_uuid']} + + TransactionsModel.insert_tuple(site_name, transaction.payload_dictionary(), conn=conn) + + if self_conn: + conn.commit() + conn.close() + return False + + return conn \ No newline at end of file diff --git a/application/items/static/itemEditHandler.js b/application/items/static/itemEditHandler.js index 457f224..270119e 100644 --- a/application/items/static/itemEditHandler.js +++ b/application/items/static/itemEditHandler.js @@ -1117,8 +1117,8 @@ async function fetchLocations(logis) { } async function fetchItem() { - const url = new URL('/items/getItem', window.location.origin); - url.searchParams.append('id', item_id); + const url = new URL('/items/api/getItem', window.location.origin); + url.searchParams.append('item_uuid', item_uuid); const response = await fetch(url); data = await response.json(); item = data.item; diff --git a/application/items/static/transactionHandler.js b/application/items/static/transactionHandler.js index 5100dc8..92386ce 100644 --- a/application/items/static/transactionHandler.js +++ b/application/items/static/transactionHandler.js @@ -87,7 +87,7 @@ async function selectItem(item_uuid) { } var transaction_zone_uuid = "" -var transaction_location_uuid = "" +var transaction_item_location_uuid = "" async function selectLocation(zone_uuid, location_uuid, zone_name, location_name) { document.getElementById('zone').value = zone_name document.getElementById('location').value = location_name @@ -131,6 +131,7 @@ async function replenishItemLocationsTable(locations) { let itemLocationTableBody = document.getElementById('itemLocationTableBody') itemLocationTableBody.innerHTML = "" for(let i = 0; i < locations.length; i++){ + console.log(locations[i]) let tableRow = document.createElement('tr') let loca = locations[i].location_shortname.split('@') @@ -198,7 +199,7 @@ async function getItem(item_uuid) { } async function validateTransaction() { - let database_id = document.getElementById("database_id") + let database_uuid = document.getElementById("database_uuid") let transaction_type = document.getElementById("trans_type") let transaction_zone = document.getElementById("zone") let transaction_location = document.getElementById("location") @@ -207,11 +208,11 @@ async function validateTransaction() { let error_count = 0 - if(database_id.value === ""){ + if(database_uuid.value === ""){ error_count = error_count + 1 - database_id.classList.add("uk-form-danger") + database_uuid.classList.add("uk-form-danger") } else { - database_id.classList.remove("uk-form-danger") + database_uuid.classList.remove("uk-form-danger") } if(transaction_type.value === "0"){ error_count = error_count + 1 @@ -270,12 +271,12 @@ async function submitTransaction() { item_uuid: item.item_uuid, item_name: item.item_name, transaction_type: document.getElementById('trans_type').value, - quantity: parseFloat(document.getElementById('transaction_quantity').value), - description: document.getElementById('transaction_description').value, - cost: cost, - vendor: 0, - expires: null, - location_id: transaction_location_uuid + transaction_quantity: parseFloat(document.getElementById('transaction_quantity').value), + transaction_description: document.getElementById('transaction_description').value, + transaction_cost: cost, + transaction_vendor: null, + trans_action_expires: null, + location_uuid: transaction_item_location_uuid }), }); data = await response.json(); @@ -291,7 +292,7 @@ async function submitTransaction() { timeout: 5000 }); - item = await getItem(item.id) + item = await getItem(item.item_uuid) await populateForm() document.getElementById('transaction_quantity').value = '0.00' diff --git a/application/items/static/transactionsHandler.js b/application/items/static/transactionsHandler.js index a2d76c8..b210375 100644 --- a/application/items/static/transactionsHandler.js +++ b/application/items/static/transactionsHandler.js @@ -104,9 +104,9 @@ async function getItem(id) { return item; } -async function getTransaction(id) { +async function getTransaction(transaction_uuid) { const url = new URL('/items/getTransaction', window.location.origin); - url.searchParams.append('id', id); + url.searchParams.append('transaction_uuid', transaction_uuid); const response = await fetch(url); data = await response.json(); let transaction = data.transaction; diff --git a/application/items/templates/transaction.html b/application/items/templates/transaction.html index 7a8345a..324f984 100644 --- a/application/items/templates/transaction.html +++ b/application/items/templates/transaction.html @@ -128,7 +128,7 @@
- +
diff --git a/application/site_management/__pycache__/site_management_processes.cpython-313.pyc b/application/site_management/__pycache__/site_management_processes.cpython-313.pyc new file mode 100644 index 0000000..decd595 Binary files /dev/null and b/application/site_management/__pycache__/site_management_processes.cpython-313.pyc differ diff --git a/logs/database.log b/logs/database.log index ab3fc1d..36081e4 100644 --- a/logs/database.log +++ b/logs/database.log @@ -926,3 +926,117 @@ 2025-09-07 11:31:37.389493 --- ERROR --- DatabaseError(message='value too long for type character varying(32)', payload=(None, "Take Out: Richie's Brickhouse BBQ Grill", "Take out dining at Take Out: Richie's Brickhouse BBQ Grill", datetime.datetime(2025, 9, 4, 0, 0), datetime.datetime(2025, 9, 4, 0, 0), 1, None, '08671808-a664-4dbc-8147-8634500364f7', 'take out'), sql='INSERT INTO main_plan_events(plan_uuid, event_shortname, event_description, event_date_start, event_date_end, created_by, recipe_uuid, receipt_uuid, event_type) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING *;') + +2025-09-09 09:20:09.636365 --- ERROR --- DatabaseError(message='syntax error at or near ")"LINE 1: ...ed_rows AS (DELETE FROM roles WHERE role_uuid IN () RETURNIN... ^', + payload=[], + sql='WITH deleted_rows AS (DELETE FROM roles WHERE role_uuid IN () RETURNING *) SELECT * FROM deleted_rows;') +2025-09-09 09:26:10.538173 --- ERROR --- DatabaseError(message='syntax error at or near ";"LINE 3: ... transaction_uuid UUID DEFAULT uuid_generate_v4() NOT NULL; ^', + payload=CREATE TABLE IF NOT EXISTS test_transactions ( + item_uuid UUID PRIMARY KEY REFERENCES test_items(item_uuid) ON DELETE CASCADE, + transaction_uuid UUID DEFAULT uuid_generate_v4() NOT NULL; + transaction_created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL, + transaction_name VARCHAR(255) DEFAULT NULL, + transaction_type VARCHAR(64) DEFAULT '' NOT NULL, + transaction_quantity FLOAT8 DEFAULT 0.00 NOT NULL, + transaction_description TEXT DEFAULT '' NOT NULL, + transaction_cost FLOAT8 DEFAULT 0.00 NOT NULL, + transaction_created_by UUID DEFAULT NULL REFERENCES users(user_uuid) ON DELETE SET NULL, + transaction_data JSONB DEFAULT '{}' NOT NULL +);, + sql='transactions') +2025-09-09 11:52:17.057408 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "undefined"LINE 1: WITH parameters AS (SELECT 'undefined'::uuid AS item_uuid), ^', + payload={}, + sql='WITH parameters AS (SELECT %(item_uuid)s::uuid AS item_uuid), cte_item_locations_qty AS ( SELECT SUM(item_locations.item_quantity_on_hand) AS quantity_on_hand FROM test_item_locations item_locations WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) ), cte_item_locations AS ( SELECT item_locations.item_location_uuid, item_locations.item_quantity_on_hand, locations.location_shortname, zones.zone_uuid, locations.location_uuid FROM test_item_locations item_locations LEFT JOIN test_locations locations ON locations.location_uuid = item_locations.location_uuid LEFT JOIN test_zones zones ON zones.zone_uuid = locations.zone_uuid WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) )SELECT items.item_uuid, items.item_name, item_info.item_cost, (SELECT COALESCE(ilsq.quantity_on_hand, 0.00) FROM cte_item_locations_qty ilsq) AS item_quantity_on_hand, COALESCE(units.unit_fullname, 'ERROR') AS unit_fullname, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations, (SELECT COALESCE(row_to_json(zones.*), '{}') FROM test_zones zones WHERE zones.zone_uuid = log_info.item_primary_zone) AS primary_zone, (SELECT COALESCE(row_to_json(locations.*), '{}') FROM test_locations locations WHERE locations.location_uuid = log_info.item_primary_location) AS primary_locationFROM test_items itemsLEFT JOIN test_item_info item_info ON item_info.item_uuid = items.item_uuidLEFT JOIN units ON item_info.item_uom = units.unit_uuidLEFT JOIN test_logistics_info log_info ON log_info.item_uuid = items.item_uuidWHERE items.item_uuid = (SELECT item_uuid FROM parameters);') +2025-09-09 11:53:39.671036 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "undefined"LINE 1: WITH parameters AS (SELECT 'undefined'::uuid AS item_uuid), ^', + payload={}, + sql='WITH parameters AS (SELECT %(item_uuid)s::uuid AS item_uuid), cte_item_locations_qty AS ( SELECT SUM(item_locations.item_quantity_on_hand) AS quantity_on_hand FROM test_item_locations item_locations WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) ), cte_item_locations AS ( SELECT item_locations.item_location_uuid, item_locations.item_quantity_on_hand, locations.location_shortname, zones.zone_uuid, locations.location_uuid FROM test_item_locations item_locations LEFT JOIN test_locations locations ON locations.location_uuid = item_locations.location_uuid LEFT JOIN test_zones zones ON zones.zone_uuid = locations.zone_uuid WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) )SELECT items.item_uuid, items.item_name, item_info.item_cost, (SELECT COALESCE(ilsq.quantity_on_hand, 0.00) FROM cte_item_locations_qty ilsq) AS item_quantity_on_hand, COALESCE(units.unit_fullname, 'ERROR') AS unit_fullname, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations, (SELECT COALESCE(row_to_json(zones.*), '{}') FROM test_zones zones WHERE zones.zone_uuid = log_info.item_primary_zone) AS primary_zone, (SELECT COALESCE(row_to_json(locations.*), '{}') FROM test_locations locations WHERE locations.location_uuid = log_info.item_primary_location) AS primary_locationFROM test_items itemsLEFT JOIN test_item_info item_info ON item_info.item_uuid = items.item_uuidLEFT JOIN units ON item_info.item_uom = units.unit_uuidLEFT JOIN test_logistics_info log_info ON log_info.item_uuid = items.item_uuidWHERE items.item_uuid = (SELECT item_uuid FROM parameters);') +2025-09-09 11:54:09.097107 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "undefined"LINE 1: WITH parameters AS (SELECT 'undefined'::uuid AS item_uuid), ^', + payload={}, + sql='WITH parameters AS (SELECT %(item_uuid)s::uuid AS item_uuid), cte_item_locations_qty AS ( SELECT SUM(item_locations.item_quantity_on_hand) AS quantity_on_hand FROM test_item_locations item_locations WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) ), cte_item_locations AS ( SELECT item_locations.item_location_uuid, item_locations.item_quantity_on_hand, locations.location_shortname, zones.zone_uuid, locations.location_uuid FROM test_item_locations item_locations LEFT JOIN test_locations locations ON locations.location_uuid = item_locations.location_uuid LEFT JOIN test_zones zones ON zones.zone_uuid = locations.zone_uuid WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) )SELECT items.item_uuid, items.item_name, item_info.item_cost, (SELECT COALESCE(ilsq.quantity_on_hand, 0.00) FROM cte_item_locations_qty ilsq) AS item_quantity_on_hand, COALESCE(units.unit_fullname, 'ERROR') AS unit_fullname, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations, (SELECT COALESCE(row_to_json(zones.*), '{}') FROM test_zones zones WHERE zones.zone_uuid = log_info.item_primary_zone) AS primary_zone, (SELECT COALESCE(row_to_json(locations.*), '{}') FROM test_locations locations WHERE locations.location_uuid = log_info.item_primary_location) AS primary_locationFROM test_items itemsLEFT JOIN test_item_info item_info ON item_info.item_uuid = items.item_uuidLEFT JOIN units ON item_info.item_uom = units.unit_uuidLEFT JOIN test_logistics_info log_info ON log_info.item_uuid = items.item_uuidWHERE items.item_uuid = (SELECT item_uuid FROM parameters);') +2025-09-09 12:14:04.757096 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "undefined"LINE 1: WITH parameters AS (SELECT 'undefined'::uuid AS item_uuid), ^', + payload={}, + sql='WITH parameters AS (SELECT %(item_uuid)s::uuid AS item_uuid), cte_item_locations_qty AS ( SELECT SUM(item_locations.item_quantity_on_hand) AS quantity_on_hand FROM test_item_locations item_locations WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) ), cte_item_locations AS ( SELECT item_locations.item_location_uuid, item_locations.item_quantity_on_hand, locations.location_shortname, zones.zone_uuid, locations.location_uuid FROM test_item_locations item_locations LEFT JOIN test_locations locations ON locations.location_uuid = item_locations.location_uuid LEFT JOIN test_zones zones ON zones.zone_uuid = locations.zone_uuid WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) )SELECT items.item_uuid, items.item_name, item_info.item_cost, (SELECT COALESCE(ilsq.quantity_on_hand, 0.00) FROM cte_item_locations_qty ilsq) AS item_quantity_on_hand, COALESCE(units.unit_fullname, 'ERROR') AS unit_fullname, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations, (SELECT COALESCE(row_to_json(zones.*), '{}') FROM test_zones zones WHERE zones.zone_uuid = log_info.item_primary_zone) AS primary_zone, (SELECT COALESCE(row_to_json(locations.*), '{}') FROM test_locations locations WHERE locations.location_uuid = log_info.item_primary_location) AS primary_locationFROM test_items itemsLEFT JOIN test_item_info item_info ON item_info.item_uuid = items.item_uuidLEFT JOIN units ON item_info.item_uom = units.unit_uuidLEFT JOIN test_logistics_info log_info ON log_info.item_uuid = items.item_uuidWHERE items.item_uuid = (SELECT item_uuid FROM parameters);') +2025-09-09 12:40:03.412252 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "undefined"LINE 1: WITH parameters AS (SELECT 'undefined'::uuid AS item_uuid), ^', + payload={}, + sql='WITH parameters AS (SELECT %(item_uuid)s::uuid AS item_uuid), cte_item_locations_qty AS ( SELECT SUM(item_locations.item_quantity_on_hand) AS quantity_on_hand FROM test_item_locations item_locations WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) ), cte_item_locations AS ( SELECT item_locations.item_location_uuid, item_locations.item_quantity_on_hand, locations.location_shortname, zones.zone_uuid, locations.location_uuid FROM test_item_locations item_locations LEFT JOIN test_locations locations ON locations.location_uuid = item_locations.location_uuid LEFT JOIN test_zones zones ON zones.zone_uuid = locations.zone_uuid WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) )SELECT items.item_uuid, items.item_name, item_info.item_cost, (SELECT COALESCE(ilsq.quantity_on_hand, 0.00) FROM cte_item_locations_qty ilsq) AS item_quantity_on_hand, COALESCE(units.unit_fullname, 'ERROR') AS unit_fullname, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations, (SELECT COALESCE(row_to_json(zones.*), '{}') FROM test_zones zones WHERE zones.zone_uuid = log_info.item_primary_zone) AS primary_zone, (SELECT COALESCE(row_to_json(locations.*), '{}') FROM test_locations locations WHERE locations.location_uuid = log_info.item_primary_location) AS primary_locationFROM test_items itemsLEFT JOIN test_item_info item_info ON item_info.item_uuid = items.item_uuidLEFT JOIN units ON item_info.item_uom = units.unit_uuidLEFT JOIN test_logistics_info log_info ON log_info.item_uuid = items.item_uuidWHERE items.item_uuid = (SELECT item_uuid FROM parameters);') +2025-09-09 12:50:09.059608 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "undefined"LINE 1: WITH parameters AS (SELECT 'undefined'::uuid AS item_uuid), ^', + payload={}, + sql='WITH parameters AS (SELECT %(item_uuid)s::uuid AS item_uuid), cte_item_locations_qty AS ( SELECT SUM(item_locations.item_quantity_on_hand) AS quantity_on_hand FROM test_item_locations item_locations WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) ), cte_item_locations AS ( SELECT item_locations.item_location_uuid, item_locations.item_quantity_on_hand, locations.location_shortname, zones.zone_uuid, locations.location_uuid FROM test_item_locations item_locations LEFT JOIN test_locations locations ON locations.location_uuid = item_locations.location_uuid LEFT JOIN test_zones zones ON zones.zone_uuid = locations.zone_uuid WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) )SELECT items.item_uuid, items.item_name, item_info.item_cost, (SELECT COALESCE(ilsq.quantity_on_hand, 0.00) FROM cte_item_locations_qty ilsq) AS item_quantity_on_hand, COALESCE(units.unit_fullname, 'ERROR') AS unit_fullname, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations, (SELECT COALESCE(row_to_json(zones.*), '{}') FROM test_zones zones WHERE zones.zone_uuid = log_info.item_primary_zone) AS primary_zone, (SELECT COALESCE(row_to_json(locations.*), '{}') FROM test_locations locations WHERE locations.location_uuid = log_info.item_primary_location) AS primary_locationFROM test_items itemsLEFT JOIN test_item_info item_info ON item_info.item_uuid = items.item_uuidLEFT JOIN units ON item_info.item_uom = units.unit_uuidLEFT JOIN test_logistics_info log_info ON log_info.item_uuid = items.item_uuidWHERE items.item_uuid = (SELECT item_uuid FROM parameters);') +2025-09-09 13:01:03.082952 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "undefined"LINE 1: WITH parameters AS (SELECT 'undefined'::uuid AS item_uuid), ^', + payload={}, + sql='WITH parameters AS (SELECT %(item_uuid)s::uuid AS item_uuid), cte_item_locations_qty AS ( SELECT SUM(item_locations.item_quantity_on_hand) AS quantity_on_hand FROM test_item_locations item_locations WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) ), cte_item_locations AS ( SELECT item_locations.item_location_uuid, item_locations.item_quantity_on_hand, locations.location_shortname, zones.zone_uuid, locations.location_uuid FROM test_item_locations item_locations LEFT JOIN test_locations locations ON locations.location_uuid = item_locations.location_uuid LEFT JOIN test_zones zones ON zones.zone_uuid = locations.zone_uuid WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) )SELECT items.item_uuid, items.item_name, item_info.item_cost, (SELECT COALESCE(ilsq.quantity_on_hand, 0.00) FROM cte_item_locations_qty ilsq) AS item_quantity_on_hand, COALESCE(units.unit_fullname, 'ERROR') AS unit_fullname, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations, (SELECT COALESCE(row_to_json(zones.*), '{}') FROM test_zones zones WHERE zones.zone_uuid = log_info.item_primary_zone) AS primary_zone, (SELECT COALESCE(row_to_json(locations.*), '{}') FROM test_locations locations WHERE locations.location_uuid = log_info.item_primary_location) AS primary_locationFROM test_items itemsLEFT JOIN test_item_info item_info ON item_info.item_uuid = items.item_uuidLEFT JOIN units ON item_info.item_uom = units.unit_uuidLEFT JOIN test_logistics_info log_info ON log_info.item_uuid = items.item_uuidWHERE items.item_uuid = (SELECT item_uuid FROM parameters);') +2025-09-09 13:04:38.126736 --- ERROR --- DatabaseError(message='column "aquisition_date" of relation "test_cost_layers" does not existLINE 2: (aquisition_date, quantity, cost, currency_type, expires, ve... ^', + payload={'aquisition_date': datetime.datetime(2025, 9, 9, 13, 4, 38, 80004), 'quantity': 1.0, 'cost': 0.5, 'currency_type': 'USD', 'vendor': 0, 'expires': None}, + sql='INSERT INTO test_cost_layers(aquisition_date, quantity, cost, currency_type, expires, vendor) VALUES (%(aquisition_date)s, %(quantity)s, %(cost)s, %(currency_type)s, %(expires)s, %(vendor)s) RETURNING *;') +2025-09-09 13:06:39.354770 --- ERROR --- DatabaseError(message=''aquisition_date'', + payload={'item_location_uuid': '278d51f6-efb1-48c5-9c59-d7dd12c13df3', 'layer_aquisition_date': datetime.datetime(2025, 9, 9, 13, 6, 39, 337717), 'layer_quantity': 1.0, 'layer_cost': 0.5, 'layer_currency_type': 'USD', 'layer_vendor': 0, 'layer_expires': None}, + sql='INSERT INTO test_cost_layers(aquisition_date, quantity, cost, currency_type, expires, vendor) VALUES (%(aquisition_date)s, %(quantity)s, %(cost)s, %(currency_type)s, %(expires)s, %(vendor)s) RETURNING *;') +2025-09-09 13:07:44.686437 --- ERROR --- DatabaseError(message=''aquisition_date'', + payload={'item_location_uuid': '278d51f6-efb1-48c5-9c59-d7dd12c13df3', 'layer_aquisition_date': datetime.datetime(2025, 9, 9, 13, 7, 44, 643575), 'layer_quantity': 1.0, 'layer_cost': 0.5, 'layer_currency_type': 'USD', 'layer_vendor': 0, 'layer_expires': None}, + sql='INSERT INTO test_cost_layers(item_location_uuid, layer_aquisition_date, layer_quantity, layer_cost, layer_currency_type, layer_expires, layer_vendor) VALUES (%(item_location_uuid)s::uuid, %(aquisition_date)s, %(quantity)s, %(cost)s, %(currency_type)s, %(expires)s, %(vendor)s) RETURNING *;') +2025-09-09 13:15:34.859428 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "undefined"LINE 1: WITH parameters AS (SELECT 'undefined'::uuid AS item_uuid), ^', + payload={}, + sql='WITH parameters AS (SELECT %(item_uuid)s::uuid AS item_uuid), cte_item_locations_qty AS ( SELECT SUM(item_locations.item_quantity_on_hand) AS quantity_on_hand FROM test_item_locations item_locations WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) ), cte_item_locations AS ( SELECT item_locations.item_location_uuid, item_locations.item_quantity_on_hand, locations.location_shortname, zones.zone_uuid, locations.location_uuid FROM test_item_locations item_locations LEFT JOIN test_locations locations ON locations.location_uuid = item_locations.location_uuid LEFT JOIN test_zones zones ON zones.zone_uuid = locations.zone_uuid WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) )SELECT items.item_uuid, items.item_name, item_info.item_cost, (SELECT COALESCE(ilsq.quantity_on_hand, 0.00) FROM cte_item_locations_qty ilsq) AS item_quantity_on_hand, COALESCE(units.unit_fullname, 'ERROR') AS unit_fullname, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations, (SELECT COALESCE(row_to_json(zones.*), '{}') FROM test_zones zones WHERE zones.zone_uuid = log_info.item_primary_zone) AS primary_zone, (SELECT COALESCE(row_to_json(locations.*), '{}') FROM test_locations locations WHERE locations.location_uuid = log_info.item_primary_location) AS primary_locationFROM test_items itemsLEFT JOIN test_item_info item_info ON item_info.item_uuid = items.item_uuidLEFT JOIN units ON item_info.item_uom = units.unit_uuidLEFT JOIN test_logistics_info log_info ON log_info.item_uuid = items.item_uuidWHERE items.item_uuid = (SELECT item_uuid FROM parameters);') +2025-09-09 13:18:03.184985 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "undefined"LINE 1: WITH parameters AS (SELECT 'undefined'::uuid AS item_uuid), ^', + payload={}, + sql='WITH parameters AS (SELECT %(item_uuid)s::uuid AS item_uuid), cte_item_locations_qty AS ( SELECT SUM(item_locations.item_quantity_on_hand) AS quantity_on_hand FROM test_item_locations item_locations WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) ), cte_item_locations AS ( SELECT item_locations.item_location_uuid, item_locations.item_quantity_on_hand, locations.location_shortname, zones.zone_uuid, locations.location_uuid FROM test_item_locations item_locations LEFT JOIN test_locations locations ON locations.location_uuid = item_locations.location_uuid LEFT JOIN test_zones zones ON zones.zone_uuid = locations.zone_uuid WHERE item_locations.item_uuid = (SELECT item_uuid FROM parameters) )SELECT items.item_uuid, items.item_name, item_info.item_cost, (SELECT COALESCE(ilsq.quantity_on_hand, 0.00) FROM cte_item_locations_qty ilsq) AS item_quantity_on_hand, COALESCE(units.unit_fullname, 'ERROR') AS unit_fullname, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations, (SELECT COALESCE(row_to_json(zones.*), '{}') FROM test_zones zones WHERE zones.zone_uuid = log_info.item_primary_zone) AS primary_zone, (SELECT COALESCE(row_to_json(locations.*), '{}') FROM test_locations locations WHERE locations.location_uuid = log_info.item_primary_location) AS primary_locationFROM test_items itemsLEFT JOIN test_item_info item_info ON item_info.item_uuid = items.item_uuidLEFT JOIN units ON item_info.item_uom = units.unit_uuidLEFT JOIN test_logistics_info log_info ON log_info.item_uuid = items.item_uuidWHERE items.item_uuid = (SELECT item_uuid FROM parameters);') +2025-09-09 14:50:13.000596 --- ERROR --- DatabaseError(message='syntax error at or near ")"LINE 1: ...ed_rows AS (DELETE FROM roles WHERE role_uuid IN () RETURNIN... ^', + payload=[], + sql='WITH deleted_rows AS (DELETE FROM roles WHERE role_uuid IN () RETURNING *) SELECT * FROM deleted_rows;') +2025-09-09 14:52:54.973873 --- ERROR --- DatabaseError(message='syntax error at or near ";"LINE 2: layer_id SERIAL UNIQUE; ^', + payload=CREATE TABLE IF NOT EXISTS test_cost_layers ( + layer_id SERIAL UNIQUE; + item_location_uuid UUID REFERENCES test_item_locations(item_location_uuid) ON DELETE SET NULL, + layer_aquisition_date TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL, + layer_quantity FLOAT8 DEFAULT 0.00 NOT NULL, + layer_cost FLOAT8 DEFAULT 0.00 NOT NULL, + layer_currency_type VARCHAR(16) DEFAULT 'USD' NOT NULL, + layer_expires TIMESTAMP DEFAULT NULL, + layer_vendor UUID DEFAULT NULL +);, + sql='cost_layers') +2025-09-09 15:45:09.078214 --- ERROR --- DatabaseError(message='duplicate key value violates unique constraint "test_transactions_pkey"DETAIL: Key (item_uuid)=(97d2db16-7896-42cf-a94d-cb7f14971112) already exists.', + payload={'item_uuid': '97d2db16-7896-42cf-a94d-cb7f14971112', 'transaction_created_by': UUID('17488a77-e26f-4f1d-bb7d-63beb1e83f6c'), 'transaction_name': 'test23FOODPLU', 'transaction_type': 'Adjust In', 'transaction_quantity': 1, 'transaction_description': '', 'transaction_cost': 0.1, 'transaction_data': '{}', 'transaction_created_at': datetime.datetime(2025, 9, 9, 15, 45, 9, 38563), 'data': {'location': UUID('00db5522-b8e9-4e20-98b0-cc111fa84785')}}, + sql='INSERT INTO test_transactions( item_uuid, transaction_created_by, transaction_name, transaction_type, transaction_created_at, transaction_quantity, transaction_description, transaction_cost, transaction_data) VALUES ( %(item_uuid)s, %(transaction_created_by)s, %(transaction_name)s, %(transaction_type)s, %(transaction_created_at)s, %(transaction_quantity)s, %(transaction_description)s, %(transaction_cost)s, %(transaction_data)s)RETURNING *;') +2025-09-09 15:51:40.473718 --- ERROR --- DatabaseError(message='duplicate key value violates unique constraint "sites_site_name_key"DETAIL: Key (site_name)=(test) already exists.', + payload={'site_name': 'test', 'site_description': 'Test Site', 'site_created_by': '17488a77-e26f-4f1d-bb7d-63beb1e83f6c', 'site_default_zone_uuid': None, 'site_default_auto_issue_location_uuid': None, 'site_default_primary_location_uuid': None, 'site_flags': '{}', 'site_created_on': datetime.datetime(2025, 9, 9, 15, 51, 40, 459928)}, + sql='INSERT INTO sites(site_name, site_description, site_created_by, site_default_zone_uuid, site_default_auto_issue_location_uuid,site_default_primary_location_uuid, site_created_on, site_flags) VALUES (%(site_name)s, %(site_description)s, %(site_created_by)s, %(site_default_zone_uuid)s, %(site_default_auto_issue_location_uuid)s, %(site_default_primary_location_uuid)s, %(site_created_on)s, %(site_flags)s) RETURNING *;') +2025-09-09 17:39:11.341281 --- ERROR --- DatabaseError(message='dict is not a sequence', + payload={'item_uuid': '5b190969-6b23-4cca-84d4-748f607254b3'}, + sql='WITH passed_id AS (SELECT id AS passed_id, item_uuid as passed_uuid FROM test_items WHERE id=%s), logistics_id AS (SELECT logistics_info_id FROM test_items WHERE id=(SELECT passed_id FROM passed_id)), info_id AS (SELECT item_info_id FROM test_items WHERE id=(SELECT passed_id FROM passed_id)), cte_conversions AS ( SELECT test_conversions.id as conv_id, test_conversions.conv_factor as conv_factor, units.* as uom FROM test_conversions LEFT JOIN units ON test_conversions.uom_id = units.id WHERE test_conversions.item_id = (SELECT passed_id FROM passed_id) ), cte_item_info AS ( SELECT test_item_info.*, row_to_json(units.*) as uom, COALESCE((SELECT json_agg(convs) FROM cte_conversions convs), '[]'::json) AS conversions, COALESCE((SELECT json_agg(p.*) FROM test_sku_prefix as p WHERE p.id = ANY(test_item_info.prefixes)), '[]'::json) as prefixes FROM test_item_info LEFT JOIN units ON test_item_info.uom = units.id WHERE test_item_info.id = (SELECT item_info_id FROM info_id) ), cte_shopping_lists AS ( SELECT test_shopping_lists.*, test_shopping_list_items.item_type, test_shopping_list_items.qty FROM test_shopping_lists JOIN test_shopping_list_items ON test_shopping_lists.list_uuid = test_shopping_list_items.list_uuid WHERE test_shopping_list_items.item_uuid = (SELECT passed_uuid FROM passed_id) ), cte_recipes AS ( SELECT rp_items.* FROM test_recipe_items rp_items WHERE rp_items.item_uuid = (SELECT passed_uuid FROM passed_id) ), cte_itemlinks AS ( SELECT * FROM test_itemlinks WHERE link=(SELECT passed_id FROM passed_id) ), cte_item_locations AS ( SELECT * FROM test_item_locations LEFT JOIN test_locations ON test_locations.id = test_item_locations.location_id WHERE part_id = (SELECT passed_id FROM passed_id) ), cte_logistics_info AS ( SELECT li.*, row_to_json(pl) AS primary_location, row_to_json(ail) AS auto_issue_location, row_to_json(pz) AS primary_zone, row_to_json(aiz) AS auto_issue_zone FROM test_logistics_info AS li LEFT JOIN test_locations AS pl ON li.primary_location = pl.id LEFT JOIN test_locations AS ail ON li.auto_issue_location = ail.id LEFT JOIN test_zones AS pz ON li.primary_zone = pz.id LEFT JOIN test_zones AS aiz ON li.auto_issue_zone = aiz.id WHERE li.id=(SELECT logistics_info_id FROM logistics_id) ), cte_barcodes AS ( SELECT barcode.barcode As barcode, barcode.in_exchange AS in_exchange, barcode.out_exchange AS out_exchange, barcode.descriptor AS descriptor FROM test_barcodes AS barcode LEFT JOIN test_items AS item ON item.id = (SELECT passed_id FROM passed_id) WHERE barcode.item_uuid = item.item_uuid )SELECT (SELECT passed_id FROM passed_id) AS passed_id, test_items.*, (SELECT COALESCE(row_to_json(logis), '{}') FROM cte_logistics_info logis) AS logistics_info, row_to_json(test_food_info.*) as food_info, row_to_json(test_brands.*) as brand, (SELECT COALESCE(row_to_json(ii), '{}') FROM cte_item_info ii) AS item_info, (SELECT COALESCE(array_agg(row_to_json(sl)), '{}') FROM cte_shopping_lists sl) AS item_shopping_lists, (SELECT COALESCE(array_agg(row_to_json(rp)), '{}') FROM cte_recipes rp) as item_recipes, (SELECT COALESCE(array_agg(row_to_json(il)), '{}') FROM cte_itemlinks il) AS linked_items, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations, (SELECT COALESCE(array_agg(row_to_json(bar)), '{}') FROM cte_barcodes bar) AS item_barcodesFROM test_items LEFT JOIN test_item_info ON test_items.item_info_id = test_item_info.id LEFT JOIN test_food_info ON test_items.food_info_id = test_food_info.id LEFT JOIN test_brands ON test_items.brand = test_brands.id LEFT JOIN units ON test_item_info.uom = units.id LEFT JOIN cte_shopping_lists ON test_items.id = cte_shopping_lists.idWHERE test_items.id=(SELECT passed_id FROM passed_id)GROUP BY test_items.id, test_item_info.id, test_food_info.id, test_brands.id;') +2025-09-09 17:45:46.050844 --- ERROR --- DatabaseError(message='syntax error at or near "SELECT"LINE 2: SELECT * ^', + payload={'item_uuid': '5b190969-6b23-4cca-84d4-748f607254b3'}, + sql='WITH passed_uuid AS (SELECT %(item_uuid)s AS passed_uuid),SELECT *FROM test_itemsWHERE test_items.item_uuid=(SELECT passed_uuid FROM passed_uuid)') +2025-09-09 17:46:33.040634 --- ERROR --- DatabaseError(message='operator does not exist: uuid = textLINE 2: SELECT * FROM test_items item WHERE item.item_uuid=(SELECT p... ^HINT: No operator matches the given name and argument types. You might need to add explicit type casts.', + payload={'item_uuid': '5b190969-6b23-4cca-84d4-748f607254b3'}, + sql='WITH passed_uuid AS (SELECT %(item_uuid)s AS passed_uuid)SELECT * FROM test_items item WHERE item.item_uuid=(SELECT passed_uuid FROM passed_uuid)') +2025-09-09 17:49:07.945816 --- ERROR --- DatabaseError(message='syntax error at or near "{"LINE 3: COLESCE(item_info, {}) AS item_info ^', + payload={'item_uuid': '5b190969-6b23-4cca-84d4-748f607254b3'}, + sql='WITH passed_uuid AS (SELECT %(item_uuid)s::uuid AS passed_uuid)SELECT item.*,COLESCE(item_info, {}) AS item_info FROM test_items itemLEFT JOIN test_item_info item_info ON item_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)WHERE item.item_uuid=(SELECT passed_uuid FROM passed_uuid)') +2025-09-09 17:49:44.140644 --- ERROR --- DatabaseError(message='syntax error at or near "{"LINE 3: COALESCE(item_info, {}) AS item_info ^', + payload={'item_uuid': '5b190969-6b23-4cca-84d4-748f607254b3'}, + sql='WITH passed_uuid AS (SELECT %(item_uuid)s::uuid AS passed_uuid)SELECT item.*,COALESCE(item_info, {}) AS item_info FROM test_items itemLEFT JOIN test_item_info item_info ON item_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)WHERE item.item_uuid=(SELECT passed_uuid FROM passed_uuid)') +2025-09-09 17:49:58.486463 --- ERROR --- DatabaseError(message='malformed record literal: "{}"LINE 3: COALESCE(item_info, '{}') AS item_info ^DETAIL: Missing left parenthesis.', + payload={'item_uuid': '5b190969-6b23-4cca-84d4-748f607254b3'}, + sql='WITH passed_uuid AS (SELECT %(item_uuid)s::uuid AS passed_uuid)SELECT item.*,COALESCE(item_info, '{}') AS item_info FROM test_items itemLEFT JOIN test_item_info item_info ON item_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)WHERE item.item_uuid=(SELECT passed_uuid FROM passed_uuid)') +2025-09-09 17:50:13.306350 --- ERROR --- DatabaseError(message='malformed record literal: "{}"LINE 3: COALESCE(item_info.*, '{}') AS item_info ^DETAIL: Missing left parenthesis.', + payload={'item_uuid': '5b190969-6b23-4cca-84d4-748f607254b3'}, + sql='WITH passed_uuid AS (SELECT %(item_uuid)s::uuid AS passed_uuid)SELECT item.*,COALESCE(item_info.*, '{}') AS item_info FROM test_items itemLEFT JOIN test_item_info item_info ON item_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)WHERE item.item_uuid=(SELECT passed_uuid FROM passed_uuid)') +2025-09-09 17:50:24.946483 --- ERROR --- DatabaseError(message='syntax error at or near "{"LINE 3: COALESCE(item_info.*, {}) AS item_info ^', + payload={'item_uuid': '5b190969-6b23-4cca-84d4-748f607254b3'}, + sql='WITH passed_uuid AS (SELECT %(item_uuid)s::uuid AS passed_uuid)SELECT item.*,COALESCE(item_info.*, {}) AS item_info FROM test_items itemLEFT JOIN test_item_info item_info ON item_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)WHERE item.item_uuid=(SELECT passed_uuid FROM passed_uuid)') +2025-09-09 17:50:39.169291 --- ERROR --- DatabaseError(message='column "{}" does not existLINE 3: COALESCE(item_info.*, "{}") AS item_info ^', + payload={'item_uuid': '5b190969-6b23-4cca-84d4-748f607254b3'}, + sql='WITH passed_uuid AS (SELECT %(item_uuid)s::uuid AS passed_uuid)SELECT item.*,COALESCE(item_info.*, "{}") AS item_info FROM test_items itemLEFT JOIN test_item_info item_info ON item_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)WHERE item.item_uuid=(SELECT passed_uuid FROM passed_uuid)') +2025-09-09 18:24:36.911338 --- ERROR --- DatabaseError(message='syntax error at or near "FROM"LINE 9: FROM test_item_info item_info ^', + payload={'item_uuid': '94631ea3-14e6-4106-8af3-97c11d104ec9'}, + sql='WITH passed_uuid AS (SELECT %(item_uuid)s::uuid AS passed_uuid), cte_conversions AS ( SELECT * FROM test_conversions WHERE test_conversions.item_uuid = (SELECT passed_uuid FROM passed_uuid) ), cte_item_info AS (SELECT item_info.*, COALESCE((SELECT json_agg(convs) FROM cte_conversions convs), '[]'::json) AS conversions, FROM test_item_info item_info WHERE item_info.item_uuid = (SELECT passed_uuid FROM passed_uuid) )SELECT item.*,(SELECT COALESCE(row_to_json(ii), '{}') FROM cte_item_info ii) AS item_info,COALESCE(row_to_json(food_info.*), '{}') AS food_info,COALESCE(row_to_json(log_info.*), '{}') AS logistics_infoFROM test_items itemLEFT JOIN test_food_info food_info ON food_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)LEFT JOIN test_logistics_info log_info ON log_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)WHERE item.item_uuid=(SELECT passed_uuid FROM passed_uuid)') +2025-09-09 18:33:06.506619 --- ERROR --- DatabaseError(message='invalid reference to FROM-clause entry for table "test_item_info"LINE 9: ...est_sku_prefix as p WHERE p.sku_prefix_uuid = ANY(test_item_... ^HINT: Perhaps you meant to reference the table alias "item_info".', + payload={'item_uuid': '94631ea3-14e6-4106-8af3-97c11d104ec9'}, + sql='WITH passed_uuid AS (SELECT %(item_uuid)s::uuid AS passed_uuid), cte_conversions AS ( SELECT * FROM test_conversions conversion WHERE conversion.item_uuid = (SELECT passed_uuid FROM passed_uuid) ), cte_item_info AS (SELECT item_info.*, COALESCE((SELECT json_agg(convs) FROM cte_conversions convs), '[]'::json) AS conversions, COALESCE((SELECT json_agg(p.*) FROM test_sku_prefix as p WHERE p.sku_prefix_uuid = ANY(test_item_info.prefixes)), '[]'::json) as prefixes FROM test_item_info item_info WHERE item_info.item_uuid = (SELECT passed_uuid FROM passed_uuid) )SELECT item.*,(SELECT COALESCE(row_to_json(ii), '{}') FROM cte_item_info ii) AS item_info,COALESCE(row_to_json(food_info.*), '{}') AS food_info,COALESCE(row_to_json(log_info.*), '{}') AS logistics_infoFROM test_items itemLEFT JOIN test_food_info food_info ON food_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)LEFT JOIN test_logistics_info log_info ON log_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)WHERE item.item_uuid=(SELECT passed_uuid FROM passed_uuid)') +2025-09-09 18:39:42.923673 --- ERROR --- DatabaseError(message='invalid reference to FROM-clause entry for table "test_item_info"LINE 9: ...M test_sku_prefix p WHERE p.sku_prefix_uuid = ANY(test_item_... ^HINT: Perhaps you meant to reference the table alias "item_info".', + payload={'item_uuid': 'b25eaeee-9d83-473e-a493-4f0a2ca15687'}, + sql='WITH passed_uuid AS (SELECT %(item_uuid)s::uuid AS passed_uuid), cte_conversions AS ( SELECT * FROM test_conversions conversion WHERE conversion.item_uuid = (SELECT passed_uuid FROM passed_uuid) ), cte_item_info AS (SELECT item_info.*, COALESCE((SELECT json_agg(convs) FROM cte_conversions convs), '[]'::json) AS conversions, COALESCE((SELECT json_agg(p.*) FROM test_sku_prefix p WHERE p.sku_prefix_uuid = ANY(test_item_info.prefixes)), '[]'::json) as prefixes FROM test_item_info item_info WHERE item_info.item_uuid = (SELECT passed_uuid FROM passed_uuid) )SELECT item.*,(SELECT COALESCE(row_to_json(ii), '{}') FROM cte_item_info ii) AS item_info,COALESCE(row_to_json(food_info.*), '{}') AS food_info,COALESCE(row_to_json(log_info.*), '{}') AS logistics_infoFROM test_items itemLEFT JOIN test_food_info food_info ON food_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)LEFT JOIN test_logistics_info log_info ON log_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)WHERE item.item_uuid=(SELECT passed_uuid FROM passed_uuid)') +2025-09-09 18:41:20.537737 --- ERROR --- DatabaseError(message='column item_info.prefixes does not existLINE 9: ...M test_sku_prefix p WHERE p.sku_prefix_uuid = ANY(item_info.... ^', + payload={'item_uuid': 'b25eaeee-9d83-473e-a493-4f0a2ca15687'}, + sql='WITH passed_uuid AS (SELECT %(item_uuid)s::uuid AS passed_uuid), cte_conversions AS ( SELECT * FROM test_conversions conversion WHERE conversion.item_uuid = (SELECT passed_uuid FROM passed_uuid) ), cte_item_info AS (SELECT item_info.*, COALESCE((SELECT json_agg(convs) FROM cte_conversions convs), '[]'::json) AS conversions, COALESCE((SELECT json_agg(p.*) FROM test_sku_prefix p WHERE p.sku_prefix_uuid = ANY(item_info.prefixes)), '[]'::json) as prefixes FROM test_item_info item_info WHERE item_info.item_uuid = (SELECT passed_uuid FROM passed_uuid) )SELECT item.*,(SELECT COALESCE(row_to_json(ii), '{}') FROM cte_item_info ii) AS item_info,COALESCE(row_to_json(food_info.*), '{}') AS food_info,COALESCE(row_to_json(log_info.*), '{}') AS logistics_infoFROM test_items itemLEFT JOIN test_food_info food_info ON food_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)LEFT JOIN test_logistics_info log_info ON log_info.item_uuid = (SELECT passed_uuid FROM passed_uuid)WHERE item.item_uuid=(SELECT passed_uuid FROM passed_uuid)') \ No newline at end of file diff --git a/logs/process.log b/logs/process.log index 4ef7476..83b0536 100644 --- a/logs/process.log +++ b/logs/process.log @@ -1190,3 +1190,26 @@ DETAIL: Failing row contains (6527c4a4-d1b0-4c62-a1ae-9dcf5d266bca, jadowyne, t layer_expires TIMESTAMP DEFAULT NULL, layer_vendor UUID DEFAULT NULL REFERENCES test_vendors(vendor_uuid) ON DELETE SET NULL );, sql='cost_layers') +2025-09-09 09:26:10.545234 --- ERROR --- DatabaseError(message='syntax error at or near ";"LINE 3: ... transaction_uuid UUID DEFAULT uuid_generate_v4() NOT NULL; ^', payload=CREATE TABLE IF NOT EXISTS test_transactions ( + item_uuid UUID PRIMARY KEY REFERENCES test_items(item_uuid) ON DELETE CASCADE, + transaction_uuid UUID DEFAULT uuid_generate_v4() NOT NULL; + transaction_created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL, + transaction_name VARCHAR(255) DEFAULT NULL, + transaction_type VARCHAR(64) DEFAULT '' NOT NULL, + transaction_quantity FLOAT8 DEFAULT 0.00 NOT NULL, + transaction_description TEXT DEFAULT '' NOT NULL, + transaction_cost FLOAT8 DEFAULT 0.00 NOT NULL, + transaction_created_by UUID DEFAULT NULL REFERENCES users(user_uuid) ON DELETE SET NULL, + transaction_data JSONB DEFAULT '{}' NOT NULL +);, sql='transactions') +2025-09-09 14:52:54.978207 --- ERROR --- DatabaseError(message='syntax error at or near ";"LINE 2: layer_id SERIAL UNIQUE; ^', payload=CREATE TABLE IF NOT EXISTS test_cost_layers ( + layer_id SERIAL UNIQUE; + item_location_uuid UUID REFERENCES test_item_locations(item_location_uuid) ON DELETE SET NULL, + layer_aquisition_date TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL, + layer_quantity FLOAT8 DEFAULT 0.00 NOT NULL, + layer_cost FLOAT8 DEFAULT 0.00 NOT NULL, + layer_currency_type VARCHAR(16) DEFAULT 'USD' NOT NULL, + layer_expires TIMESTAMP DEFAULT NULL, + layer_vendor UUID DEFAULT NULL +);, sql='cost_layers') +2025-09-09 15:51:40.480935 --- ERROR --- DatabaseError(message='duplicate key value violates unique constraint "sites_site_name_key"DETAIL: Key (site_name)=(test) already exists.', payload={'site_name': 'test', 'site_description': 'Test Site', 'site_created_by': '17488a77-e26f-4f1d-bb7d-63beb1e83f6c', 'site_default_zone_uuid': None, 'site_default_auto_issue_location_uuid': None, 'site_default_primary_location_uuid': None, 'site_flags': '{}', 'site_created_on': datetime.datetime(2025, 9, 9, 15, 51, 40, 459928)}, sql='INSERT INTO sites(site_name, site_description, site_created_by, site_default_zone_uuid, site_default_auto_issue_location_uuid,site_default_primary_location_uuid, site_created_on, site_flags) VALUES (%(site_name)s, %(site_description)s, %(site_created_by)s, %(site_default_zone_uuid)s, %(site_default_auto_issue_location_uuid)s, %(site_default_primary_location_uuid)s, %(site_created_on)s, %(site_flags)s) RETURNING *;')