saas-common-lib-473815 0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- saas_common_lib_473815-0.1/PKG-INFO +20 -0
- saas_common_lib_473815-0.1/config/__init__.py +0 -0
- saas_common_lib_473815-0.1/config/settings.py +20 -0
- saas_common_lib_473815-0.1/database/__init__.py +0 -0
- saas_common_lib_473815-0.1/database/base.py +3 -0
- saas_common_lib_473815-0.1/database/postgres.py +50 -0
- saas_common_lib_473815-0.1/entity/__init__.py +0 -0
- saas_common_lib_473815-0.1/entity/billing_entity.py +117 -0
- saas_common_lib_473815-0.1/entity/client_entity.py +27 -0
- saas_common_lib_473815-0.1/entity/document_entity.py +44 -0
- saas_common_lib_473815-0.1/entity/inventory_entity.py +75 -0
- saas_common_lib_473815-0.1/entity/invoice_entity.py +20 -0
- saas_common_lib_473815-0.1/entity/order_entity.py +102 -0
- saas_common_lib_473815-0.1/entity/table_entity.py +40 -0
- saas_common_lib_473815-0.1/entity/user_entity.py +132 -0
- saas_common_lib_473815-0.1/models/__init__.py +0 -0
- saas_common_lib_473815-0.1/models/billing_model.py +86 -0
- saas_common_lib_473815-0.1/models/client_model.py +12 -0
- saas_common_lib_473815-0.1/models/document_model.py +30 -0
- saas_common_lib_473815-0.1/models/inventory_model.py +51 -0
- saas_common_lib_473815-0.1/models/invoice_model.py +14 -0
- saas_common_lib_473815-0.1/models/order_model.py +51 -0
- saas_common_lib_473815-0.1/models/response_model.py +34 -0
- saas_common_lib_473815-0.1/models/saas_context.py +22 -0
- saas_common_lib_473815-0.1/models/table_model.py +28 -0
- saas_common_lib_473815-0.1/models/user_model.py +51 -0
- saas_common_lib_473815-0.1/saas_common_lib_473815.egg-info/PKG-INFO +20 -0
- saas_common_lib_473815-0.1/saas_common_lib_473815.egg-info/SOURCES.txt +34 -0
- saas_common_lib_473815-0.1/saas_common_lib_473815.egg-info/dependency_links.txt +1 -0
- saas_common_lib_473815-0.1/saas_common_lib_473815.egg-info/top_level.txt +5 -0
- saas_common_lib_473815-0.1/setup.cfg +4 -0
- saas_common_lib_473815-0.1/setup.py +21 -0
- saas_common_lib_473815-0.1/utils/__init__.py +0 -0
- saas_common_lib_473815-0.1/utils/auth.py +123 -0
- saas_common_lib_473815-0.1/utils/create_notification.py +19 -0
- saas_common_lib_473815-0.1/utils/send_email_otp.py +26 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: saas_common_lib_473815
|
|
3
|
+
Version: 0.1
|
|
4
|
+
Summary: Packaging all common functionalities
|
|
5
|
+
Home-page:
|
|
6
|
+
Author: Srinidhi Nagarajan
|
|
7
|
+
Author-email: Srinidhinsn@gmail.com
|
|
8
|
+
License: BSD
|
|
9
|
+
Keywords: Saas application
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 2
|
|
15
|
+
Dynamic: author
|
|
16
|
+
Dynamic: author-email
|
|
17
|
+
Dynamic: classifier
|
|
18
|
+
Dynamic: keywords
|
|
19
|
+
Dynamic: license
|
|
20
|
+
Dynamic: summary
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Define logging configuration
|
|
2
|
+
LOGGING_CONFIG = {
|
|
3
|
+
"version": 1,
|
|
4
|
+
"disable_existing_loggers": False,
|
|
5
|
+
"formatters": {
|
|
6
|
+
"default": {
|
|
7
|
+
"format": "%(asctime)s - %(levelname)s - %(name)s - %(message)s"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"handlers": {
|
|
11
|
+
"console": {
|
|
12
|
+
"class": "logging.StreamHandler",
|
|
13
|
+
"formatter": "default"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"root": {
|
|
17
|
+
"handlers": ["console"],
|
|
18
|
+
"level": "INFO"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sqlalchemy
|
|
3
|
+
from sqlalchemy.ext.declarative import declarative_base
|
|
4
|
+
from google.cloud.sql.connector import Connector, IPTypes
|
|
5
|
+
import pg8000
|
|
6
|
+
|
|
7
|
+
Base = declarative_base()
|
|
8
|
+
|
|
9
|
+
def get_db() -> sqlalchemy.engine.base.Engine:
|
|
10
|
+
"""
|
|
11
|
+
Initializes a connection pool for a Cloud SQL instance of Postgres.
|
|
12
|
+
|
|
13
|
+
Uses the Cloud SQL Python Connector package.
|
|
14
|
+
"""
|
|
15
|
+
# Note: Saving credentials in environment variables is convenient, but not
|
|
16
|
+
# secure - consider a more secure solution such as
|
|
17
|
+
# Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
|
|
18
|
+
# keep secrets safe.
|
|
19
|
+
|
|
20
|
+
instance_connection_name = os.environ[
|
|
21
|
+
"saas-473815:asia-south2:saas"
|
|
22
|
+
] # e.g. 'project:region:instance'
|
|
23
|
+
db_user = os.environ["postgres"] # e.g. 'my-db-user'
|
|
24
|
+
db_pass = os.environ["Saasqa@123"] # e.g. 'my-db-password'
|
|
25
|
+
db_name = os.environ["postgres"] # e.g. 'my-database'
|
|
26
|
+
|
|
27
|
+
ip_type = IPTypes.PRIVATE if os.environ.get("PRIVATE_IP") else IPTypes.PUBLIC
|
|
28
|
+
|
|
29
|
+
# initialize Cloud SQL Python Connector object
|
|
30
|
+
connector = Connector(refresh_strategy="LAZY")
|
|
31
|
+
|
|
32
|
+
def getconn() -> pg8000.dbapi.Connection:
|
|
33
|
+
conn: pg8000.dbapi.Connection = connector.connect(
|
|
34
|
+
instance_connection_name,
|
|
35
|
+
"pg8000",
|
|
36
|
+
user=db_user,
|
|
37
|
+
password=db_pass,
|
|
38
|
+
db=db_name,
|
|
39
|
+
ip_type=ip_type,
|
|
40
|
+
)
|
|
41
|
+
return conn
|
|
42
|
+
|
|
43
|
+
# The Cloud SQL Python Connector can be used with SQLAlchemy
|
|
44
|
+
# using the 'creator' argument to 'create_engine'
|
|
45
|
+
pool = sqlalchemy.create_engine(
|
|
46
|
+
"postgresql+pg8000://",
|
|
47
|
+
creator=getconn,
|
|
48
|
+
# ...
|
|
49
|
+
)
|
|
50
|
+
return pool
|
|
File without changes
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
from sqlalchemy import Column, BigInteger, Text, Float, DateTime, Boolean, Identity, ForeignKey, func, Integer
|
|
2
|
+
from database.base import Base
|
|
3
|
+
from models.billing_model import BillingDocument, BillingDocumentItem
|
|
4
|
+
from enum import Enum
|
|
5
|
+
|
|
6
|
+
class PaymentStatusEnum(str, Enum):
|
|
7
|
+
pending = "Pending"
|
|
8
|
+
paid = "Paid"
|
|
9
|
+
partial = "Partial"
|
|
10
|
+
overdue = "Overdue"
|
|
11
|
+
|
|
12
|
+
class ApprovalStatusEnum(str, Enum):
|
|
13
|
+
pending = "Pending"
|
|
14
|
+
approved = "Approved"
|
|
15
|
+
rejected = "Rejected"
|
|
16
|
+
|
|
17
|
+
class BillingDocumentEntity(Base):
|
|
18
|
+
__tablename__ = "billing_documents"
|
|
19
|
+
|
|
20
|
+
id = Column(BigInteger, Identity(always=True), primary_key=True)
|
|
21
|
+
client_id = Column(Text, nullable=True)
|
|
22
|
+
document_type = Column(Text, nullable=True) # Quotation,
|
|
23
|
+
document_number = Column(Text, nullable=True)
|
|
24
|
+
document_date = Column(DateTime, nullable=True)
|
|
25
|
+
due_date = Column(DateTime, nullable=True)
|
|
26
|
+
reference_number = Column(Text, nullable=True)
|
|
27
|
+
order_id = Column(Text, nullable=True)
|
|
28
|
+
customer_id = Column(Text, nullable=True)
|
|
29
|
+
vendor_id = Column(Text, nullable=True)
|
|
30
|
+
currency = Column(Text, nullable=True)
|
|
31
|
+
status = Column(Text, nullable=True) # paid, cancelled, partially paid
|
|
32
|
+
contact_email = Column(Text, nullable=True)
|
|
33
|
+
contact_phone = Column(Text, nullable=True)
|
|
34
|
+
terms = Column(Text, nullable=True)
|
|
35
|
+
notes = Column(Text, nullable=True)
|
|
36
|
+
subtotal = Column(Float, nullable=True)
|
|
37
|
+
tax_amount = Column(Float, nullable=True) #
|
|
38
|
+
discount_amount = Column(Float, nullable=True)
|
|
39
|
+
total_amount = Column(Float, nullable=True)
|
|
40
|
+
linked_document_ids = Column(Text, nullable=True)
|
|
41
|
+
is_active = Column(Boolean, nullable=False, default=True)
|
|
42
|
+
created_by = Column(Text, nullable=True)
|
|
43
|
+
updated_by = Column(Text, nullable=True)
|
|
44
|
+
created_at = Column(DateTime, default=func.now())
|
|
45
|
+
updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
|
|
46
|
+
payment_status = Column(Text, nullable=True, default=PaymentStatusEnum.pending)
|
|
47
|
+
payment_due_date = Column(DateTime, nullable=True)
|
|
48
|
+
payment_method = Column(Text, nullable=True)
|
|
49
|
+
payment_reference = Column(Text, nullable=True)
|
|
50
|
+
approval_status = Column(Text, nullable=True, default=ApprovalStatusEnum.pending) # rejected
|
|
51
|
+
approved_by = Column(Text, nullable=True)
|
|
52
|
+
approval_date = Column(DateTime, nullable=True)
|
|
53
|
+
gl_account_code = Column(Text, nullable=True)
|
|
54
|
+
tax_code = Column(Text, nullable=True)
|
|
55
|
+
accounting_period = Column(Text, nullable=True)
|
|
56
|
+
currency_conversion_rate = Column(Float, nullable=True)
|
|
57
|
+
shipping_address = Column(Text, nullable=True)
|
|
58
|
+
shipping_method = Column(Text, nullable=True)
|
|
59
|
+
delivery_date = Column(DateTime, nullable=True)
|
|
60
|
+
tracking_number = Column(Text, nullable=True)
|
|
61
|
+
document_version = Column(Integer, default=1)
|
|
62
|
+
invoice_date = Column(DateTime, nullable=True)
|
|
63
|
+
note = Column(Text, nullable=True)
|
|
64
|
+
customer_terms = Column(Text, nullable=True)
|
|
65
|
+
|
|
66
|
+
@staticmethod
|
|
67
|
+
def copyToModel(entity):
|
|
68
|
+
model = BillingDocument(**entity.__dict__)
|
|
69
|
+
model.__dict__.pop("_sa_instance_state", None)
|
|
70
|
+
return model
|
|
71
|
+
|
|
72
|
+
@staticmethod
|
|
73
|
+
def copyToModels(entities):
|
|
74
|
+
models = [BillingDocument(**e.__dict__) for e in entities]
|
|
75
|
+
for m in models:
|
|
76
|
+
m.__dict__.pop("_sa_instance_state", None)
|
|
77
|
+
return models
|
|
78
|
+
|
|
79
|
+
class BillingDocumentItemEntity(Base):
|
|
80
|
+
__tablename__ = "billing_document_items"
|
|
81
|
+
|
|
82
|
+
id = Column(BigInteger, Identity(always=True), primary_key=True)
|
|
83
|
+
document_id = Column(BigInteger, ForeignKey("billing_documents.id", ondelete="CASCADE"), nullable=True)
|
|
84
|
+
item_ref_id = Column(Text, nullable=True)
|
|
85
|
+
description = Column(Text, nullable=True)
|
|
86
|
+
quantity = Column(Float, nullable=True)
|
|
87
|
+
unit_price = Column(Float, nullable=True)
|
|
88
|
+
discount = Column(Float, nullable=True)
|
|
89
|
+
tax_rate = Column(Float, nullable=True)
|
|
90
|
+
total = Column(Float, nullable=True)
|
|
91
|
+
is_active = Column(Boolean, nullable=False, default=True)
|
|
92
|
+
created_at = Column(DateTime, default=func.now())
|
|
93
|
+
updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
|
|
94
|
+
unit_of_measure = Column(Text, nullable=True, default="Unit")
|
|
95
|
+
item_category = Column(Text, nullable=True)
|
|
96
|
+
item_discount = Column(Float, nullable=True, default=0.0)
|
|
97
|
+
item_tax_code = Column(Text, nullable=True, default="Standard")
|
|
98
|
+
|
|
99
|
+
@staticmethod
|
|
100
|
+
def copyToModel(entity):
|
|
101
|
+
model = BillingDocumentItem(**entity.__dict__)
|
|
102
|
+
model.__dict__.pop("_sa_instance_state", None)
|
|
103
|
+
return model
|
|
104
|
+
|
|
105
|
+
@staticmethod
|
|
106
|
+
def copyToModels(entities):
|
|
107
|
+
models = [BillingDocumentItem(**e.__dict__) for e in entities]
|
|
108
|
+
for m in models:
|
|
109
|
+
m.__dict__.pop("_sa_instance_state", None)
|
|
110
|
+
return models
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from sqlalchemy import Column, Text, DateTime, func, ARRAY
|
|
2
|
+
from sqlalchemy.dialects.postgresql import UUID
|
|
3
|
+
import uuid
|
|
4
|
+
from database.base import Base
|
|
5
|
+
from models.client_model import ClientModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Client(Base):
|
|
9
|
+
__tablename__ = "client"
|
|
10
|
+
|
|
11
|
+
id = Column(Text, primary_key=True)
|
|
12
|
+
name = Column(Text, nullable=False)
|
|
13
|
+
realm = Column(Text)
|
|
14
|
+
email = Column(Text, unique=True, nullable=True)
|
|
15
|
+
phone = Column(Text, nullable=True)
|
|
16
|
+
logo = Column(Text, nullable=True)
|
|
17
|
+
saved_address_ids = Column(ARRAY(Text), nullable=True)
|
|
18
|
+
created_date_time = Column(DateTime, default=func.now())
|
|
19
|
+
updated_date_time = Column(DateTime, default=func.now(), onupdate=func.now())
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def copyToModel(client):
|
|
24
|
+
model = ClientModel(**client.__dict__)
|
|
25
|
+
model.__dict__.pop("_sa_instance_state", None)
|
|
26
|
+
return model
|
|
27
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from sqlalchemy import Column, Boolean, DateTime, Text, func
|
|
2
|
+
from sqlalchemy.dialects.postgresql import UUID
|
|
3
|
+
import uuid
|
|
4
|
+
from database.base import Base
|
|
5
|
+
from models.document_model import Document
|
|
6
|
+
|
|
7
|
+
class DocumentEntity(Base):
|
|
8
|
+
__tablename__ = "documents"
|
|
9
|
+
|
|
10
|
+
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
11
|
+
client_id = Column(Text, nullable=True)
|
|
12
|
+
category_id = Column(Text, nullable=True)
|
|
13
|
+
name = Column(Text, nullable=True)
|
|
14
|
+
description = Column(Text, nullable=True)
|
|
15
|
+
realm = Column(Text, nullable=True)
|
|
16
|
+
filetype = Column(Text, nullable=True)
|
|
17
|
+
extension = Column(Text, nullable=True)
|
|
18
|
+
size_kb = Column(Text, nullable=True)
|
|
19
|
+
is_protected = Column(Boolean, nullable=True)
|
|
20
|
+
is_active = Column(Boolean, nullable=True)
|
|
21
|
+
uuid_name = Column(Text, nullable=True)
|
|
22
|
+
path = Column(Text, nullable=True)
|
|
23
|
+
storage_type = Column(Text, nullable=True)
|
|
24
|
+
checksum_md5 = Column(Text, nullable=True)
|
|
25
|
+
created_by = Column(Text, nullable=True)
|
|
26
|
+
last_read_by = Column(Text, nullable=True)
|
|
27
|
+
created_date_time = Column(DateTime, default=func.now())
|
|
28
|
+
last_read_date_time = Column(DateTime, default=func.now())
|
|
29
|
+
|
|
30
|
+
deleted = Column(Boolean, nullable=True)
|
|
31
|
+
deleted_at = Column(DateTime, nullable=True)
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def copyToModel(document):
|
|
35
|
+
model = Document(**document.__dict__)
|
|
36
|
+
model.__dict__.pop("_sa_instance_state", None)
|
|
37
|
+
return model
|
|
38
|
+
|
|
39
|
+
@staticmethod
|
|
40
|
+
def copyToModels(docs):
|
|
41
|
+
models = [Document(**doc.__dict__) for doc in docs]
|
|
42
|
+
for m in models:
|
|
43
|
+
m.__dict__.pop("_sa_instance_state", None)
|
|
44
|
+
return models
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from sqlalchemy import Column, Integer, BigInteger, Boolean, Text, DateTime, Float, func, ARRAY
|
|
2
|
+
from database.base import Base
|
|
3
|
+
from models.inventory_model import Inventory, Category
|
|
4
|
+
from sqlalchemy.dialects.postgresql import JSONB
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class InventoryEntity(Base):
|
|
8
|
+
__tablename__ = "inventory"
|
|
9
|
+
|
|
10
|
+
id = Column(BigInteger, primary_key=True, autoincrement=True)
|
|
11
|
+
client_id = Column(Text, nullable=False)
|
|
12
|
+
inventory_id = Column(BigInteger, nullable=True)
|
|
13
|
+
line_item_id = Column(ARRAY(BigInteger), nullable=True)
|
|
14
|
+
name = Column(Text, nullable=True)
|
|
15
|
+
description = Column(Text, nullable=True)
|
|
16
|
+
category_id = Column(Text, nullable=True)
|
|
17
|
+
realm = Column(Text, nullable=True)
|
|
18
|
+
availability = Column(Integer, nullable=True)
|
|
19
|
+
unit = Column(Text, nullable=True)
|
|
20
|
+
unit_price = Column(Float, nullable=True)
|
|
21
|
+
unit_cst = Column(Float, nullable=True)
|
|
22
|
+
unit_gst = Column(Float, nullable=True)
|
|
23
|
+
unit_total_price = Column(Float, nullable=True)
|
|
24
|
+
price = Column(Float, nullable=True)
|
|
25
|
+
cst = Column(Float, nullable=True)
|
|
26
|
+
gst = Column(Float, nullable=True)
|
|
27
|
+
discount = Column(Float, nullable=True)
|
|
28
|
+
total_price = Column(Float, nullable=True)
|
|
29
|
+
slug = Column(Text, nullable=True)
|
|
30
|
+
created_by = Column(Text, nullable=True)
|
|
31
|
+
updated_by = Column(Text, nullable=True)
|
|
32
|
+
created_at = Column(DateTime, default=func.now())
|
|
33
|
+
updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
|
|
34
|
+
|
|
35
|
+
@staticmethod
|
|
36
|
+
def copyToModel(row):
|
|
37
|
+
model = Inventory(**row.__dict__)
|
|
38
|
+
model.__dict__.pop("_sa_instance_state", None)
|
|
39
|
+
return model
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def copyToModels(rows):
|
|
43
|
+
models = [Inventory(**row.__dict__) for row in rows]
|
|
44
|
+
for m in models:
|
|
45
|
+
m.__dict__.pop("_sa_instance_state", None)
|
|
46
|
+
return models
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class CategoryEntity(Base):
|
|
50
|
+
__tablename__ = "category"
|
|
51
|
+
|
|
52
|
+
id = Column(Text, primary_key=True)
|
|
53
|
+
client_id = Column(Text, nullable=False)
|
|
54
|
+
name = Column(Text, nullable=True)
|
|
55
|
+
description = Column(Text, nullable=True)
|
|
56
|
+
sub_categories = Column(ARRAY(Text), nullable=True)
|
|
57
|
+
# sub_categories = Column(JSONB, nullable=True, default=[])
|
|
58
|
+
slug = Column(Text, nullable=True)
|
|
59
|
+
created_by = Column(Text, nullable=True)
|
|
60
|
+
updated_by = Column(Text, nullable=True)
|
|
61
|
+
created_at = Column(DateTime, default=func.now())
|
|
62
|
+
updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def copyToModel(row):
|
|
66
|
+
model = Category(**row.__dict__)
|
|
67
|
+
model.__dict__.pop("_sa_instance_state", None)
|
|
68
|
+
return model
|
|
69
|
+
|
|
70
|
+
@staticmethod
|
|
71
|
+
def copyToModels(rows):
|
|
72
|
+
models = [Category(**row.__dict__) for row in rows]
|
|
73
|
+
for m in models:
|
|
74
|
+
m.__dict__.pop("_sa_instance_state", None)
|
|
75
|
+
return models
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey, ARRAY
|
|
2
|
+
from sqlalchemy.orm import declarative_base
|
|
3
|
+
import datetime
|
|
4
|
+
|
|
5
|
+
Base = declarative_base()
|
|
6
|
+
|
|
7
|
+
# Invoice Table
|
|
8
|
+
class Invoice(Base):
|
|
9
|
+
__tablename__ = "Invoice"
|
|
10
|
+
|
|
11
|
+
id = Column(Integer, primary_key=True)
|
|
12
|
+
clientId = Column(String, nullable=True)
|
|
13
|
+
invoiceId = Column(String, nullable=True)
|
|
14
|
+
orderId = Column(String, nullable=True)
|
|
15
|
+
orderItemId = Column(String, nullable=True)
|
|
16
|
+
itemDescription = Column(String, nullable=True)
|
|
17
|
+
quantity = Column(Integer, nullable=True)
|
|
18
|
+
price = Column(Float, nullable=True)
|
|
19
|
+
cst = Column(Float, nullable=True)
|
|
20
|
+
gst = Column(Float, nullable=True)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey, ARRAY
|
|
2
|
+
from sqlalchemy.orm import declarative_base, relationship
|
|
3
|
+
import datetime
|
|
4
|
+
from models.order_model import OrderItemModel, DineinOrderModel
|
|
5
|
+
Base = declarative_base()
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# DineinOrders Table
|
|
9
|
+
class DineinOrder(Base):
|
|
10
|
+
__tablename__ = "dinein_order"
|
|
11
|
+
|
|
12
|
+
id = Column(Integer, primary_key=True)
|
|
13
|
+
client_id = Column(String, nullable=True)
|
|
14
|
+
dinein_order_id = Column(String, nullable=True)
|
|
15
|
+
table_id = Column(Integer, nullable=True)
|
|
16
|
+
invoice_id = Column(String, nullable=True)
|
|
17
|
+
handler_id = Column(String, nullable=True)
|
|
18
|
+
invoice_status = Column(String, nullable=True)
|
|
19
|
+
price = Column(Float, nullable=True)
|
|
20
|
+
cst = Column(Float, nullable=True)
|
|
21
|
+
gst = Column(Float, nullable=True)
|
|
22
|
+
discount = Column(Float, nullable=True)
|
|
23
|
+
total_price = Column(Float, nullable=True)
|
|
24
|
+
created_by = Column(String, nullable=True)
|
|
25
|
+
updated_by = Column(String, nullable=True)
|
|
26
|
+
created_at = Column(DateTime, default=datetime.datetime.utcnow)
|
|
27
|
+
updated_at = Column(DateTime, default=datetime.datetime.utcnow,
|
|
28
|
+
onupdate=datetime.datetime.utcnow)
|
|
29
|
+
status = Column(String, nullable=True)
|
|
30
|
+
items = relationship("OrderItem", backref="order",
|
|
31
|
+
cascade="all, delete-orphan")
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def copyToModel(dineinOrder):
|
|
35
|
+
"""Convert SQLAlchemy DineinOrders entities into Pydantic models."""
|
|
36
|
+
dineinOrderModel = DineinOrderModel(**dineinOrder.__dict__)
|
|
37
|
+
dineinOrderModel.__dict__.pop("_sa_instance_state", None)
|
|
38
|
+
return dineinOrderModel
|
|
39
|
+
|
|
40
|
+
@staticmethod
|
|
41
|
+
def copyFromModel(dineinOrderModel):
|
|
42
|
+
"""Convert Pydantic DineinOrders models into SQLAlchemy entities."""
|
|
43
|
+
return DineinOrder(**dineinOrderModel.dict(exclude_unset=True))
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def copyToModels(dinein_orders):
|
|
47
|
+
"""Convert SQLAlchemy DineinOrders entities into Pydantic models."""
|
|
48
|
+
dineinOrdersModels = [DineinOrderModel(
|
|
49
|
+
**order.__dict__) for order in dinein_orders]
|
|
50
|
+
|
|
51
|
+
# Remove SQLAlchemy metadata (_sa_instance_state)
|
|
52
|
+
for model in dineinOrdersModels:
|
|
53
|
+
model.__dict__.pop("_sa_instance_state", None)
|
|
54
|
+
|
|
55
|
+
return dineinOrdersModels
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def copyFromModels(dinein_orders_models):
|
|
59
|
+
"""Convert Pydantic DineinOrders models into SQLAlchemy entities."""
|
|
60
|
+
return [DineinOrder(**model.dict(exclude_unset=True)) for model in dinein_orders_models]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# OrderItems Table
|
|
64
|
+
class OrderItem(Base):
|
|
65
|
+
__tablename__ = "order_item"
|
|
66
|
+
|
|
67
|
+
id = Column(Integer, primary_key=True)
|
|
68
|
+
client_id = Column(String, nullable=True)
|
|
69
|
+
order_id = Column(Integer, ForeignKey("dinein_order.id"))
|
|
70
|
+
item_id = Column(Integer, nullable=True)
|
|
71
|
+
item_name = Column(String, nullable=True)
|
|
72
|
+
slug = Column(String, nullable=True)
|
|
73
|
+
quantity = Column(Integer, nullable=True)
|
|
74
|
+
unit_price = Column(Float, nullable=True)
|
|
75
|
+
line_total = Column(Float, nullable=True)
|
|
76
|
+
status = Column(String, nullable=True)
|
|
77
|
+
|
|
78
|
+
@staticmethod
|
|
79
|
+
def copyToModel(orderItem):
|
|
80
|
+
"""Convert SQLAlchemy OrderItems entities into Pydantic models."""
|
|
81
|
+
orderItemModel = OrderItemModel(**orderItem.__dict__)
|
|
82
|
+
orderItemModel.__dict__.pop("_sa_instance_state", None)
|
|
83
|
+
return orderItemModel
|
|
84
|
+
|
|
85
|
+
@staticmethod
|
|
86
|
+
def copyFromModel(orderItemModel):
|
|
87
|
+
"""Convert Pydantic OrderItems models into SQLAlchemy entities."""
|
|
88
|
+
return OrderItem(**orderItemModel.dict(exclude_unset=True))
|
|
89
|
+
|
|
90
|
+
@staticmethod
|
|
91
|
+
def copyToModels(order_items):
|
|
92
|
+
"""Convert SQLAlchemy OrderItems entities into Pydantic models."""
|
|
93
|
+
orderItemModels = [OrderItemModel(**item.__dict__)
|
|
94
|
+
for item in order_items]
|
|
95
|
+
for model in orderItemModels:
|
|
96
|
+
model.__dict__.pop("_sa_instance_state", None)
|
|
97
|
+
return orderItemModels
|
|
98
|
+
|
|
99
|
+
@staticmethod
|
|
100
|
+
def copyFromModels(order_item_models):
|
|
101
|
+
"""Convert Pydantic OrderItems models into SQLAlchemy entities."""
|
|
102
|
+
return [OrderItem(**model.dict(exclude_unset=True)) for model in order_item_models]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from sqlalchemy import Column, Integer, BigInteger, Boolean, Text, DateTime, func, UniqueConstraint, Identity
|
|
2
|
+
from sqlalchemy.dialects.postgresql import UUID
|
|
3
|
+
import uuid
|
|
4
|
+
from database.base import Base
|
|
5
|
+
from models.table_model import Table
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DiningTable(Base):
|
|
9
|
+
__tablename__ = "tables"
|
|
10
|
+
|
|
11
|
+
id = Column(BigInteger, primary_key=True, autoincrement=True)
|
|
12
|
+
client_id = Column(Text, nullable=False)
|
|
13
|
+
name = Column(Text, nullable=False)
|
|
14
|
+
table_type = Column(Text)
|
|
15
|
+
slug = Column(Text, unique=True, nullable=True)
|
|
16
|
+
qr_code_url = Column(Text, nullable=True)
|
|
17
|
+
description = Column(Text, nullable=True)
|
|
18
|
+
status = Column(Text, nullable=True, default="Vacant")
|
|
19
|
+
section = Column(Text, nullable=True)
|
|
20
|
+
location_zone = Column(Text, nullable=True)
|
|
21
|
+
sort_order = Column(Integer, nullable=True)
|
|
22
|
+
is_active = Column(Boolean, nullable=False, default=True)
|
|
23
|
+
created_by = Column(Text, nullable=True)
|
|
24
|
+
updated_by = Column(Text, nullable=True)
|
|
25
|
+
created_at = Column(DateTime, default=func.now())
|
|
26
|
+
updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
def copyToModel(table):
|
|
31
|
+
model = Table(**table.__dict__)
|
|
32
|
+
model.__dict__.pop("_sa_instance_state", None)
|
|
33
|
+
return model
|
|
34
|
+
|
|
35
|
+
@staticmethod
|
|
36
|
+
def copyToModels(tables):
|
|
37
|
+
models = [Table(**table.__dict__) for table in tables]
|
|
38
|
+
for m in models:
|
|
39
|
+
m.__dict__.pop("_sa_instance_state", None)
|
|
40
|
+
return models
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
from database.postgres import Base
|
|
3
|
+
from sqlalchemy import Column , Integer, String, ARRAY, UUID, event, Date,TIMESTAMP,func
|
|
4
|
+
from models.user_model import UserModel, PageDefinitionModel,PersonModel
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Person(Base):
|
|
9
|
+
__tablename__ = "person"
|
|
10
|
+
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
11
|
+
first_name = Column(String, index=True, nullable=False)
|
|
12
|
+
last_name = Column(String, nullable=True)
|
|
13
|
+
dob = Column(Date, nullable=True)
|
|
14
|
+
email = Column(String, nullable=True)
|
|
15
|
+
phone = Column(String, nullable=True)
|
|
16
|
+
created_at = Column(TIMESTAMP, server_default=func.now())
|
|
17
|
+
updated_at = Column(
|
|
18
|
+
TIMESTAMP, server_default=func.now(), onupdate=func.now())
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def generate_uuid(first_name: str, client_id: str) -> uuid.UUID:
|
|
22
|
+
namespace = uuid.UUID("6ba7b810-9dad-11d1-80b4-00c04fd430c8") # DNS namespace
|
|
23
|
+
combined_key = f"{username}-{client_id}"
|
|
24
|
+
return uuid.uuid5(namespace, combined_key)
|
|
25
|
+
@staticmethod
|
|
26
|
+
def copyToModel(person):
|
|
27
|
+
personModel = PersonModel(**person.__dict__)
|
|
28
|
+
personModel.__dict__.pop("_sa_instance_state", None)
|
|
29
|
+
return personModel
|
|
30
|
+
|
|
31
|
+
@staticmethod
|
|
32
|
+
def copyFromModel(personModel):
|
|
33
|
+
"""Convert a single Pydantic DineinOrders model into a SQLAlchemy entity."""
|
|
34
|
+
return Person(**personModel.dict(exclude_unset=True))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class User(Base):
|
|
38
|
+
__tablename__ = "user"
|
|
39
|
+
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
40
|
+
username = Column(String, index=True, nullable=False)
|
|
41
|
+
hashed_password = Column(String, nullable=False)
|
|
42
|
+
client_id = Column(String, nullable=False)
|
|
43
|
+
roles = Column(ARRAY(String), default=[])
|
|
44
|
+
grants = Column(ARRAY(String), default=[])
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def generate_uuid(username: str, client_id: str) -> uuid.UUID:
|
|
48
|
+
namespace = uuid.UUID("6ba7b810-9dad-11d1-80b4-00c04fd430c8") # DNS namespace
|
|
49
|
+
combined_key = f"{username}-{client_id}"
|
|
50
|
+
return uuid.uuid5(namespace, combined_key)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def copyToModel(user):
|
|
55
|
+
"""Convert SQLAlchemy User entities into Pydantic User models."""
|
|
56
|
+
userModel = UserModel(**user.__dict__)
|
|
57
|
+
userModel.__dict__.pop("_sa_instance_state", None)
|
|
58
|
+
return userModel
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def copyFromModel(userModel):
|
|
62
|
+
"""Convert a single Pydantic DineinOrders model into a SQLAlchemy entity."""
|
|
63
|
+
return User(**userModel.dict(exclude_unset=True))
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@staticmethod
|
|
67
|
+
def copyToModels(users):
|
|
68
|
+
"""Convert SQLAlchemy User entities into Pydantic User models."""
|
|
69
|
+
userModels = [UserModel(**user.__dict__) for user in users]
|
|
70
|
+
|
|
71
|
+
# Remove SQLAlchemy metadata (_sa_instance_state)
|
|
72
|
+
for model in userModels:
|
|
73
|
+
model.__dict__.pop("_sa_instance_state", None)
|
|
74
|
+
|
|
75
|
+
return userModels
|
|
76
|
+
|
|
77
|
+
@staticmethod
|
|
78
|
+
def copyFromModels(userModels):
|
|
79
|
+
"""Convert Pydantic User models into SQLAlchemy User entities."""
|
|
80
|
+
return [User(**model.dict(exclude_unset=True)) for model in userModels]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@event.listens_for(User, "before_insert")
|
|
85
|
+
def set_uuid(mapper, connection, target):
|
|
86
|
+
if not target.id and target.username and target.client_id:
|
|
87
|
+
target.id = User.generate_uuid(target.username, target.client_id)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class PageDefinition(Base):
|
|
91
|
+
__tablename__ = "page_definition"
|
|
92
|
+
id = Column (Integer, primary_key=True, index=True)
|
|
93
|
+
client_id = Column(String)
|
|
94
|
+
role = Column(String)
|
|
95
|
+
module = Column(String)
|
|
96
|
+
operations = Column(ARRAY(String))
|
|
97
|
+
screen_id = Column(String)
|
|
98
|
+
load_type = Column(String)
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
101
|
+
def copyToModels(page_definitions):
|
|
102
|
+
"""Convert SQLAlchemy PageDefinition entities into Pydantic models, removing metadata."""
|
|
103
|
+
pageDefinitionModels = [PageDefinitionModel(**page_def.__dict__) for page_def in page_definitions]
|
|
104
|
+
|
|
105
|
+
# Remove SQLAlchemy metadata (_sa_instance_state)
|
|
106
|
+
for model in pageDefinitionModels:
|
|
107
|
+
model.__dict__.pop("_sa_instance_state", None)
|
|
108
|
+
|
|
109
|
+
return pageDefinitionModels
|
|
110
|
+
|
|
111
|
+
@staticmethod
|
|
112
|
+
def copyFromModels(page_models):
|
|
113
|
+
"""Convert Pydantic PageDefinition models into SQLAlchemy entities."""
|
|
114
|
+
page_definitions = [
|
|
115
|
+
PageDefinition(**model.dict(exclude_unset=True)) for model in page_models
|
|
116
|
+
]
|
|
117
|
+
return page_definitions
|
|
118
|
+
|
|
119
|
+
class Notification(Base):
|
|
120
|
+
__tablename__ = "notifications"
|
|
121
|
+
|
|
122
|
+
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
123
|
+
client_id = Column(String, nullable=False)
|
|
124
|
+
template_name = Column(String, nullable=True)
|
|
125
|
+
template_body = Column(String, nullable=True)
|
|
126
|
+
type = Column(String, nullable=True)
|
|
127
|
+
realm = Column(String, nullable=True)
|
|
128
|
+
is_read = Column(String, nullable=True)
|
|
129
|
+
created_at = Column(TIMESTAMP, server_default=func.now())
|
|
130
|
+
updated_at = Column(
|
|
131
|
+
TIMESTAMP, server_default=func.now(), onupdate=func.now())
|
|
132
|
+
|
|
File without changes
|