pantry-track/application/administration/administration_services.py
2025-08-28 17:58:05 -05:00

261 lines
10 KiB
Python

# 3RD PARTY IMPORTS
import psycopg2
import datetime
# APPLICATION IMPORTS
import config
from application import postsqldb, database_payloads
from application.administration import administration_database, administration_models
from dataclasses import dataclass, field
from application.database_postgres import (
CostLayersModel,
BrandsModel,
FoodInfoModel,
ItemInfoModel,
ZonesModel,
LocationsModel,
LogisticsInfoModel,
TransactionsModel,
ItemsModel,
ItemLocationsModel,
ConversionsModel,
SKUPrefixModel,
BarcodesModel,
VendorsModel,
ReceiptsModel,
ReceiptItemsModel,
RecipesModel,
RecipeItemsModel,
ShoppingListsModel,
ShoppingListItemsModel,
PlansModel,
PlanEventsModel,
SitesModel,
UsersModel,
RolesModel,
UnitsModel
)
from application.database_postgres import BaseModel
@dataclass
class SiteManager:
site_name: str
admin_user: tuple
default_zone: int
default_location: int
description: str
create_order: list = field(init=False)
drop_order: list = field(init=False)
def create_tables(self, conn):
UsersModel.UsersModel.create_table(self.site_name, conn=conn)
SitesModel.SitesModel.create_table(self.site_name, conn=conn)
RolesModel.RolesModel.create_table(self.site_name, conn=conn)
UnitsModel.UnitsModel.create_table(self.site_name, conn=conn)
# Needed for Items and Logistics
BrandsModel.BrandsModel.create_table(self.site_name, conn=conn)
ZonesModel.ZonesModel.create_table(self.site_name, conn=conn)
LocationsModel.LocationsModel.create_table(self.site_name, conn=conn)
ItemsModel.ItemsModel.create_table(self.site_name, conn=conn)
FoodInfoModel.FoodInfoModel.create_table(self.site_name, conn=conn)
ItemInfoModel.ItemInfoModel.create_table(self.site_name, conn=conn)
LogisticsInfoModel.LogisticsInfoModel.create_table(self.site_name, conn=conn)
ItemLocationsModel.ItemLocationsModel.create_table(self.site_name, conn=conn)
CostLayersModel.CostLayersModel.create_table(self.site_name, conn=conn)
ConversionsModel.ConversionsModel.create_table(self.site_name, conn=conn)
TransactionsModel.TransactionsModel.create_table(self.site_name, conn=conn)
SKUPrefixModel.SKUPrefixModel.create_table(self.site_name, conn=conn)
BarcodesModel.BarcodesModel.create_table(self.site_name, conn=conn)
# Vendors is used losely in Planner and in receipts.
VendorsModel.VendorsModel.create_table(self.site_name, conn=conn)
ReceiptsModel.ReceiptsModel.create_table(self.site_name, conn=conn)
ReceiptItemsModel.ReceiptItemsModel.create_table(self.site_name, conn=conn)
# This is the Recipe Module
RecipesModel.RecipesModel.create_table(self.site_name, conn=conn)
RecipeItemsModel.RecipeItemsModel.create_table(self.site_name, conn=conn)
# this is the Shopping List Module
ShoppingListsModel.ShoppingListsModel.create_table(self.site_name, conn=conn)
ShoppingListItemsModel.ShoppingListItemsModel.create_table(self.site_name, conn=conn)
# Planner Module
PlansModel.PlansModel.create_table(self.site_name, conn=conn)
PlanEventsModel.PlanEventsModel.create_table(self.site_name, conn=conn)
def drop_tables(self, conn):
# Needed for Items and Logistics
BrandsModel.BrandsModel.drop_table(self.site_name,conn=conn)
CostLayersModel.CostLayersModel.drop_table(self.site_name, conn=conn)
FoodInfoModel.FoodInfoModel.drop_table(self.site_name, conn=conn)
ItemInfoModel.ItemInfoModel.drop_table(self.site_name, conn=conn)
ZonesModel.ZonesModel.drop_table(self.site_name, conn=conn)
LocationsModel.LocationsModel.drop_table(self.site_name, conn=conn)
LogisticsInfoModel.LogisticsInfoModel.drop_table(self.site_name, conn=conn)
TransactionsModel.TransactionsModel.drop_table(self.site_name, conn=conn)
ItemsModel.ItemsModel.drop_table(self.site_name, conn=conn)
ItemLocationsModel.ItemLocationsModel.drop_table(self.site_name, conn=conn)
ConversionsModel.ConversionsModel.drop_table(self.site_name, conn=conn)
SKUPrefixModel.SKUPrefixModel.drop_table(self.site_name, conn=conn)
BarcodesModel.BarcodesModel.drop_table(self.site_name, conn=conn)
# Vendors is used losely in Planner and in receipts.
VendorsModel.VendorsModel.drop_table(self.site_name, conn=conn)
ReceiptsModel.ReceiptsModel.drop_table(self.site_name, conn=conn)
ReceiptItemsModel.ReceiptItemsModel.drop_table(self.site_name, conn=conn)
# This is the Recipe Module
RecipesModel.RecipesModel.drop_table(self.site_name, conn=conn)
RecipeItemsModel.RecipeItemsModel.drop_table(self.site_name, conn=conn)
# this is the Shopping List Module
ShoppingListsModel.ShoppingListsModel.drop_table(self.site_name, conn=conn)
ShoppingListItemsModel.ShoppingListItemsModel.drop_table(self.site_name, conn=conn)
# Planner Module
PlansModel.PlansModel.drop_table(self.site_name, conn=conn)
PlanEventsModel.PlanEventsModel.drop_table(self.site_name, conn=conn)
def deleteSite(payload, conn=None):
"""Uses a Site Manager to delete a site from the system.
Args:
site_manager (MyDataclasses.SiteManager):
Raises:
Exception:
"""
self_conn = False
if not conn:
database_config = config.config()
conn = psycopg2.connect(**database_config)
conn.autocommit = False
self_conn = True
site_manager = SiteManager(
payload['site_name'],
payload['admin_user'],
payload['default_zone'],
payload['default_primary_location'],
payload['site_description']
)
roles = administration_models.ExtendedRolesModel.select_by_site_uuid({'site_uuid': payload['site_uuid']}, conn=conn)
roles = RolesModel.RolesModel.delete_tuples([role['role_uuid'] for role in roles], conn=conn)
site_manager.drop_tables(conn=conn)
for role in roles:
administration_models.ExtendedUsersModel.update_roles({'role_uuid': role['role_uuid']}, conn=conn)
administration_models.ExtendedUsersModel.update_sites({'site_uuid': payload['site_uuid']}, conn=conn)
SitesModel.SitesModel.delete_tuples((payload['site_uuid'],), conn=conn)
if self_conn:
conn.commit()
conn.close()
def addSite(payload, conn=None):
"""uses a Site Manager to add a site to the system
Args:
site_manager (MyDataclasses.SiteManager):
"""
self_conn = False
site_manager = SiteManager(
payload['site_name'],
payload['admin_user'],
payload['default_zone'],
payload['default_primary_location'],
payload['site_description']
)
try:
if not conn:
database_config = config.config()
conn = psycopg2.connect(**database_config)
conn.autocommit = False
self_conn = True
sql = 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp";'
with conn.cursor() as cur:
cur.execute(sql)
site_manager.create_tables(conn=conn)
admin_user = administration_models.ExtendedUsersModel.add_admin_user(site_manager.admin_user, conn=conn)
site = SitesModel.SitesModel.Payload(
site_name=site_manager.site_name,
site_description=site_manager.description,
site_created_by=admin_user['user_uuid']
)
# have to build site table
site = SitesModel.SitesModel.insert_tuple(site.site_name, site.payload_dictionary(), conn=conn)
# have to build roles table
role = RolesModel.RolesModel.Payload(
role_name="Admin",
role_description=f"Admin for {site['site_name']}",
role_site_uuid=site['site_uuid']
)
role = RolesModel.RolesModel.insert_tuple(site['site_name'], role.payload_dictionary(), conn=conn)
# have to build logins table
payload = {
'user_uuid': admin_user['user_uuid'],
'site_uuid': site['site_uuid'],
'role_uuid': role['role_uuid']
}
admin_user = administration_models.ExtendedUsersModel.update_user_site_roles(payload, conn=conn)
default_zone = ZonesModel.ZonesModel.Payload(zone_name=site_manager.default_zone)
default_zone = ZonesModel.ZonesModel.insert_tuple(site["site_name"], default_zone.payload_dictionary(), conn=conn)
uuid = f"{site_manager.default_zone}@{site_manager.default_location}"
default_location = LocationsModel.LocationsModel.Payload(
location_shortname=uuid,
location_name=site_manager.default_location,
zone_uuid=default_zone['zone_uuid']
)
default_location = LocationsModel.LocationsModel.insert_tuple(site['site_name'], default_location.payload_dictionary(), conn=conn)
payload = {
'key': site['site_uuid'],
'update': {
'site_default_zone_uuid': default_zone['zone_uuid'],
'site_default_auto_issue_location_uuid': default_location['location_uuid'],
'site_default_primary_location_uuid': default_location['location_uuid']
}
}
SitesModel.SitesModel.update_tuple(payload, conn=conn)
blank_vendor = VendorsModel.VendorsModel.Payload("None", admin_user['user_uuid'])
blank_brand = BrandsModel.BrandsModel.Payload("None")
VendorsModel.VendorsModel.insert_tuple(site['site_name'], blank_vendor.payload_dictionary(), conn=conn)
BrandsModel.BrandsModel.insert_tuple(site['site_name'], blank_brand.payload_dictionary(), conn=conn)
if self_conn:
conn.commit()
conn.close()
except Exception as error:
with open("logs/process.log", "a+") as file:
file.write(f"{datetime.datetime.now()} --- ERROR --- {error}\n")
conn.rollback()
raise error