Working on the basic SQL select API CRUD and lots of models

This commit is contained in:
Scott Idem
2021-03-08 15:53:39 -05:00
parent c7f2b16feb
commit 3d5fafc4bf
36 changed files with 2570 additions and 863 deletions

View File

@@ -0,0 +1,116 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
class Account_Cfg_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
id_random: Optional[str] = Field(
**base_fields['account_cfg_id_random'],
alias='account_cfg_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='account_cfg_id'
)
account_id_random: Optional[str]
account_id: Optional[int]
show_user_availability: Optional[bool]
show_person_create: Optional[bool]
person_create_label: Optional[str]
show_person_view: Optional[bool]
person_view_label: Optional[str]
show_person_load: Optional[bool]
person_load_label: Optional[str]
show_cart: Optional[bool]
cart_label: Optional[str]
default_no_reply_email: Optional[str]
default_no_reply_name: Optional[str]
default_reply_to_email: Optional[str]
default_reply_to_name: Optional[str]
confirm_email: Optional[str]
confirm_name: Optional[str]
help_event_email: Optional[str]
help_event_name: Optional[str]
help_general_email: Optional[str]
help_general_name: Optional[str]
help_member_email: Optional[str]
help_member_name: Optional[str]
help_tech_email: Optional[str]
help_tech_name: Optional[str]
order_header: Optional[str]
order_thanks: Optional[str]
order_message: Optional[str]
order_footer: Optional[str]
order_fundraising_thanks: Optional[str]
order_fundraising_message: Optional[str]
fundraising_message: Optional[str]
post_rules: Optional[str]
post_comment_rules: Optional[str]
show_post_title: Optional[bool]
show_post_comment_title: Optional[bool]
hide_posts_after: Optional[int] # Should posts be singular?
delete_posts_after: Optional[int] # Should posts be singular?
stripe_api_key: Optional[str]
stripe_publishable_key: Optional[str]
stripe_account_id: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('account_cfg_id_random', always=True)
def account_cfg_id_random_copy(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def account_cfg_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
log.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='account_cfg')
return None
@validator('account_id', always=True)
def account_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['account_id_random']:
return redis_lookup_id_random(record_id_random=values['account_id_random'], table_name='account')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
Account_Cfg_Base.update_forward_refs()

View File

@@ -0,0 +1,63 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
class Account_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
id_random: Optional[str] = Field(
**base_fields['account_id_random'],
alias='account_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='account_id'
)
code: Optional[str]
name: Optional[str]
description: Optional[str]
enable: Optional[bool]
enable_from: Optional[datetime.datetime] = None
enable_to: Optional[datetime.datetime] = None
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('account_id_random', always=True)
def account_id_random_copy(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def account_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
log.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='account')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
Account_Base.update_forward_refs()

120
app/models/address_model.py Normal file
View File

@@ -0,0 +1,120 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
#from .account_model import Account_Base
class Address_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
#from .account_model import Account_Base
id_random: Optional[str] = Field(
**base_fields['address_id_random'],
alias='address_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='address_id'
)
account_id_random: Optional[str]
account_id: Optional[int]
for_type: Optional[str]
for_id_random: Optional[str]
for_id: Optional[int] #organization: Optional[Organization_Base] = Organization_Base()
name: Optional[str]
attention_to: Optional[str]
organization_name: Optional[str]
line_1: Optional[str]
line_2: Optional[str]
line_3: Optional[str]
city: Optional[str]
country_subdivision_code: Optional[str]
state_province: Optional[str]
postal_code: Optional[str]
country_alpha_2_code: Optional[str]
country: Optional[str]
lu_time_zone_id: Optional[str]
timezone: Optional[str]
latitude: Optional[str]
longitude: Optional[str]
map_url: Optional[str]
congressional_district: Optional[str]
#priority: Optional[int]
#sort: Optional[int]
#group: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
#account: Optional[Account_Base] = Account_Base()
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('address_id_random', always=True)
def address_id_random_copy(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def address_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
log.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='address')
return None
@validator('account_id', always=True)
def account_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['account_id_random']:
return redis_lookup_id_random(record_id_random=values['account_id_random'], table_name='account')
return None
#@validator('organization_id', always=True)
#def organization_id_lookup(cls, v, values, **kwargs):
#log.setLevel(logging.WARNING)
#log.debug(locals())
#if values['organization_id']:
#return redis_lookup_id_random(record_id_random=values['organization_id'], table_name='organization')
#return None
@validator('for_id', always=True)
def for_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['for_id_random'] and values['for_type']:
return redis_lookup_id_random(record_id_random=values['for_id_random'], table_name=values['for_type'])
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
Address_Base.update_forward_refs()

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,70 @@
import copy, datetime, hashlib, logging, os, pytz, redis, secrets
default_num_bytes = 8 # URL safe 8 bytes is 11 characters long and 16 bytes is 22 characters long
xxx_id_random_field_schema: dict = {
'title': 'XXX ID Random',
'description': 'This is an id_random field for this object.',
'min_length': 11,
'max_length': 22,
'example': secrets.token_urlsafe(8) # random each reloading of app with: secrets.token_urlsafe(8)
}
xxx_id_random_field_schema_default: dict = copy.copy(xxx_id_random_field_schema)
xxx_id_random_field_schema_default['default_factory'] = lambda:secrets.token_urlsafe(8)
created_updated_on_field_schema: dict = {
'title': 'Created or Updated On',
'description': 'This is the created or updated on timestamp field for this object. It is filled in by the SQL DB.',
'example': '2021-12-31T21:10:10'
}
base_fields = {}
#base_fields['id_random'] = xxx_id_random_field_schema_default
base_fields['obj_id_random'] = xxx_id_random_field_schema # General or generic object_id_random
base_fields['account_id_random'] = xxx_id_random_field_schema
base_fields['account_cfg_id_random'] = xxx_id_random_field_schema
base_fields['address_id_random'] = xxx_id_random_field_schema
base_fields['archive_id_random'] = xxx_id_random_field_schema
base_fields['contact_id_random'] = xxx_id_random_field_schema
base_fields['event_exhibit_id_random'] = xxx_id_random_field_schema
base_fields['event_file_id_random'] = xxx_id_random_field_schema
base_fields['event_id_random'] = xxx_id_random_field_schema
base_fields['event_presentation_id_random'] = xxx_id_random_field_schema
base_fields['event_registration_id_random'] = xxx_id_random_field_schema
base_fields['fundraising_id_random'] = xxx_id_random_field_schema
base_fields['hosted_file_id_random'] = xxx_id_random_field_schema
base_fields['membership_id_random'] = xxx_id_random_field_schema
base_fields['membership_profile_id_random'] = xxx_id_random_field_schema
base_fields['order_cart_id_random'] = xxx_id_random_field_schema
base_fields['order_cart_line_id_random'] = xxx_id_random_field_schema
base_fields['order_id_random'] = xxx_id_random_field_schema
base_fields['order_line_id_random'] = xxx_id_random_field_schema
base_fields['order_transaction_id_random'] = xxx_id_random_field_schema
base_fields['organization_id_random'] = xxx_id_random_field_schema
base_fields['page_id_random'] = xxx_id_random_field_schema
base_fields['person_id_random'] = xxx_id_random_field_schema
base_fields['post_id_random'] = xxx_id_random_field_schema
base_fields['post_comment_id_random'] = xxx_id_random_field_schema
base_fields['product_id_random'] = xxx_id_random_field_schema
base_fields['site_id_random'] = xxx_id_random_field_schema
base_fields['site_domain_id_random'] = xxx_id_random_field_schema
base_fields['user_id_random'] = xxx_id_random_field_schema
base_fields['created_on'] = created_updated_on_field_schema
base_fields['updated_on'] = created_updated_on_field_schema
base_fields['obj_type'] = {}
base_fields['obj_id_random'] = xxx_id_random_field_schema_default
base_fields['obj_id_rand'] = xxx_id_random_field_schema_default
base_fields['obj_id'] = {}
base_fields['obj_name'] = {}
base_fields['obj_notes'] = {}
base_fields['for_id_random'] = xxx_id_random_field_schema_default
#xxx_id_random_field_schema['alias'] = 'order_id_random'
#base_fields['id_random'] = xxx_id_random_field_schema_default
#xxx_id_random_field_schema['alias'] = 'user_id_random_x'
#c = {'alias': 'user_id_random_x'}
#base_fields['user_id_random'] = combine_dict(xxx_id_random_field_schema, c)

130
app/models/contact_model.py Normal file
View File

@@ -0,0 +1,130 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
#from .account_model import Account_Base
from .address_model import Address_Base
class Contact_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
#from .account_model import Account_Base
#from .address_model import Address_Base
id_random: Optional[str] = Field(
**base_fields['contact_id_random'],
alias='contact_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='contact_id'
)
account_id_random: Optional[str]
account_id: Optional[int]
address_id_random: Optional[str]
address_id: Optional[int]
for_type: Optional[str]
for_id_random: Optional[str]
for_id: Optional[int]
name: Optional[str]
title: Optional[str]
tagline: Optional[str]
description: Optional[str]
lu_time_zone_id: Optional[str]
timezone: Optional[str]
email: Optional[str]
website: Optional[str]
website_name: Optional[str]
phone_mobile: Optional[str]
phone_home: Optional[str]
phone_office: Optional[str]
phone_land: Optional[str]
phone_fax: Optional[str]
facebook: Optional[str]
instagram: Optional[str]
twitter: Optional[str]
linkedin: Optional[str]
other_site_url: Optional[str]
other_site_name: Optional[str]
other_text: Optional[str]
other_json: Optional[Json]
priority: Optional[int]
sort: Optional[int]
group: Optional[str]
#account: Optional[Account_Base] = Account_Base()
address: Optional[Address_Base] = Address_Base()
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('contact_id_random', always=True)
def contact_id_random_copy(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def contact_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
log.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='contact')
return None
@validator('account_id', always=True)
def account_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['account_id_random']:
return redis_lookup_id_random(record_id_random=values['account_id_random'], table_name='account')
return None
@validator('address_id', always=True)
def address_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values.get('address_id_random', None):
return redis_lookup_id_random(record_id_random=values['address_id_random'], table_name='address')
return None
@validator('for_id', always=True)
def for_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['for_id_random'] and values['for_type']:
return redis_lookup_id_random(record_id_random=values['for_id_random'], table_name=values['for_type'])
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
Contact_Base.update_forward_refs()

View File

@@ -0,0 +1,58 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
class Core_Object_Base(BaseModel):
app.logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
obj_type: str
obj_id_random: str # alias this one based on obj_type?
obj_id_rand: str # alias this one based on obj_type?
obj_id: int # alias this one?
obj_name: Optional[str]
id_random: str # alias this one?
id: int # alias this one?
account_id_random: Optional[str]
account_id: Optional[str]
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
class Example_Object_Base(Core_Object_Base): # Based on Core_Object_Base
title: Optional[str] = None
description: Optional[str] = None
password_set_on: Optional[datetime.datetime] = None
archive_on: Optional[datetime.datetime] = None
logged_in_on: Optional[datetime.datetime] = None
last_activity_on: Optional[datetime.datetime] = None
other_random_fields: dict
list_of_: Optional[dict] = {}
# Create, Read/Get, Update, Delete
# CRUD or CGUD
# def create_object(object_data):
# return False # True, False, or None or object_data
# def get_object(object_id):
# return object_data # False or None
# def update_object(object_id, object_data):
# return False # True, False, or None or object_data
# def delete_object(object_id):
# return False # True, False, or None or object_data

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,83 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
class Hosted_File_Base(BaseModel):
app.logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
id_random: Optional[str] = Field(
**base_fields['hosted_file_id_random'],
alias='hosted_file_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='hosted_file_id'
)
#account_id_random: Optional[str]
#account_id: Optional[int]
hash_sha256: Optional[str]
title: Optional[str]
description: Optional[str]
version: Optional[int]
directory_path: Optional[str]
filename: Optional[str]
extension: Optional[str]
content_type: Optional[str]
mimetype: Optional[str]
size: Optional[int] # In bytes
cloud_storage: Optional[str]
owner_user_id: Optional[int]
group_user_id: Optional[str]
package_name: Optional[str]
#metadata: Optional[str]
#hide: Optional[int]
#priority: Optional[int]
#sort: Optional[int]
#group: Optional[str]
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('hosted_file_id_random', always=True)
def hosted_file_id_random_copy(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def hosted_file_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
app.logger.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='hosted_file')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
Hosted_File_Base.update_forward_refs()

View File

@@ -0,0 +1,470 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
from .address_model import Address_Base
from .contact_model import Contact_Base
from .organization_model import Organization_Base
from .person_model import Person_Base
from .user_model import User_Base
class Membership_Cfg_Base(BaseModel):
app.logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
account_name: Optional[str]
cycle_type: Optional[str]
membership_length: Optional[int] = Field(0, ge=0, lt=150)
prorate: Optional[bool] = False
calendar_year_start_buffer_days: Optional[int] = Field(0, ge=0, lt=150)
calendar_year_start_buffer_on: Optional[datetime.datetime] = None
calendar_year_start_on: Optional[datetime.datetime] = None
calendar_year_end_on: Optional[datetime.datetime] = None
calendar_year_end_buffer_days: Optional[int] = Field(0, ge=0, lt=150)
calendar_year_end_buffer_on: Optional[datetime.datetime] = None
enable_privacy_view: Optional[bool] = False
accept_message: Optional[str]
reject_message: Optional[str]
renew_message: Optional[str]
#cust_membership_profile: Optional[str] # list of dicts outlining custom membership profile fields for client
cust_membership_profile: Optional[Json] = '[]' # list of dicts outlining custom membership profile fields for client
default_no_reply_email: Optional[str]
default_no_reply_name: Optional[str]
confirm_email: Optional[str]
confirm_name: Optional[str]
Membership_Cfg_Base.update_forward_refs()
class Membership_Profile_Base(BaseModel):
app.logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
# if TYPE_CHECKING:
# from .supporting_core_models import Address_Base, Contact_Base, Organization_Base, User_Base
# from .person_model import Person_Base
# from .address_model import Address_Base
# from .contact_model import Contact_Base
# from .organization_model import Organization_Base
# from .person_model import Person_Base
# from .user_model import User_Base
id_random: Optional[str] = Field(
**base_fields['membership_profile_id_random'],
alias='membership_profile_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='membership_profile_id'
)
membership_id_random: Optional[str]
membership_id: Optional[int]
person_id_random: Optional[str]
person_id: Optional[int]
user_id_random: Optional[str]
user_id: Optional[int]
organization_id_random: Optional[str]
organization_id: Optional[int]
contact_id_random: Optional[str]
contact_id: Optional[int]
address_id_random: Optional[str]
address_id: Optional[int]
display_name: Optional[str]
email: Optional[str]
email_allowed: Optional[bool]
email_newsletter: Optional[bool]
mail_newsletter: Optional[bool]
show_online: Optional[bool]
show_printed: Optional[bool]
biography: Optional[str]
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
address: 'Optional[Address_Base]' = Address_Base()
contact: 'Optional[Contact_Base]' = Contact_Base()
organization: 'Optional[Organization_Base]' = Organization_Base()
person: 'Optional[Person_Base]' = Person_Base()
user: 'Optional[User_Base]' = User_Base()
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('membership_profile_id_random', always=True)
def membership_profile_id_random_copy(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def membership_profile_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
app.logger.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='membership_profile')
return None
@validator('membership_id', always=True)
def membership_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['membership_id_random']:
return redis_lookup_id_random(record_id_random=values['membership_id_random'], table_name='membership')
return None
@validator('person_id', always=True)
def person_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['person_id_random']:
return redis_lookup_id_random(record_id_random=values['person_id_random'], table_name='person')
return None
@validator('user_id', always=True)
def user_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['user_id_random']:
return redis_lookup_id_random(record_id_random=values['user_id_random'], table_name='user')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
Membership_Profile_Base.update_forward_refs()
class Membership_Base(BaseModel):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
#from .supporting_core_models import User_Base
# from .account_model import Account_Base
# from .person_model import Person_Base
# from .user_model import User_Base
id_random: Optional[str] = Field(
**base_fields['membership_id_random'],
alias='membership_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='membership_id'
)
account_id_random: Optional[str]
account_id: Optional[int] # NOTE: This is not really optional
person_id_random: Optional[str]
person_id: Optional[int]
user_id_random: Optional[str]
user_id: Optional[int]
level_number: Optional[int] = Field(0, ge=0, lt=150)
level_name: Optional[str]
product_id: Optional[int]
type_id: Optional[int]
type_name: Optional[str]
category_id: Optional[int]
category_name: Optional[str]
division_id: Optional[int]
division_name: Optional[str]
status_id: Optional[int]
status_name: Optional[str]
application_start_on: Optional[datetime.datetime] = None
approved_on: Optional[datetime.datetime] = None
first_start_on: Optional[datetime.datetime] = None
start_buffer_on: Optional[datetime.datetime] = None
start_on: Optional[datetime.datetime] = None
end_on: Optional[datetime.datetime] = None
end_buffer_on: Optional[datetime.datetime] = None
flag: Optional[bool]
flag_message: Optional[str]
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
#account: Optional[Account_Base] = Account_Base()
profile: 'Optional[Membership_Profile_Base]' = Membership_Profile_Base()
person: 'Optional[Person_Base]' = Person_Base()
user: 'Optional[User_Base]' = User_Base()
cfg: 'Optional[Membership_Cfg_Base]' = Membership_Cfg_Base()
cust_profile: Optional[dict] = {}
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('order_id_random', always=True)
def order_id_random_copy(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def membership_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='membership')
return None
@validator('account_id', always=True)
def account_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['account_id_random']:
return redis_lookup_id_random(record_id_random=values['account_id_random'], table_name='account')
return None
@validator('person_id', always=True)
def person_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['person_id_random']:
return redis_lookup_id_random(record_id_random=values['person_id_random'], table_name='person')
return None
@validator('user_id', always=True)
def user_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['user_id_random']:
return redis_lookup_id_random(record_id_random=values['user_id_random'], table_name='user')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
# Membership_Base.update_forward_refs()
# ### BEGIN ### API Membership Model ### save_membership_obj() ###
def save_membership_obj(order_obj_new:Membership_Base=None):
app.logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
if not order_obj_new:
return False
app.logger.debug(order_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=True))
order_line_obj_li_curr = [] # Initialize to store order_line list
if order_obj_new.id_random:
app.logger.info(f'An order.id {order_obj_new.id} or order.id_random {order_obj_new.id_random} was included. We can update an existing order.')
app.logger.info(f'Get the current order_line list to compare with what was sent...')
data = {}
data['order_id_random'] = order_obj_new.id_random
if order_line_rec_li_curr := sql_select(table_name='v_order_line', data=data, rm_id_random=True, as_list=True):
#app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(order_line_rec_li_curr)
for order_line_rec in order_line_rec_li_curr:
try:
order_line_obj = Order_Line_Base(**order_line_rec)
app.logger.debug(order_line_obj)
except ValidationError as e:
app.logger.error(e.json())
order_line_obj_li_curr.append(order_line_obj)
else:
app.logger.info(f'No order_line records were found')
elif order_obj_new.account_id_random and (order_obj_new.person_id_random or order_obj_new.user_id_random):
app.logger.info(f'An account.id_random {order_obj_new.account_id_random} was passed. And either a person.id_random {order_obj_new.person_id_random} or user.id_random {order_obj_new.user_id_random} was passed. We can create a new order.')
# Because there was not an order ID, assume there are no order lines yet. So no look up.
else:
app.logger.info('Either an order ID is required to update an order or an account ID along with a person ID or user ID is required to create an order.')
return False
#app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(order_line_obj_li_curr)
if repl_order_line_list: # This will remove any order line list items not sent with the new order information.
app.logger.info('Removing any order line list items not sent with the new order information...')
for index, order_line_obj_curr in enumerate(order_line_obj_li_curr):
app.logger.info(f'Current: order line ID={order_line_obj_curr.id_random} and product ID= {order_line_obj_curr.product_id_random}')
matched_product_id = False
for order_line_obj_new in order_obj_new.order_line_list:
app.logger.debug(f'Checking new: product ID={order_line_obj_new.product_id_random}')
if order_line_obj_curr.product_id_random == order_line_obj_new.product_id_random:
matched_product_id = True
app.logger.debug(f'Matched: product ID={order_line_obj_new.product_id_random}')
break
else:
app.logger.debug(f'No match: product ID={order_line_obj_new.product_id_random}')
if not matched_product_id: # Was not found in the new order line list sent
app.logger.info(f'Current order line product ID did not match any of the new list. DELETE order line ID {order_line_obj_curr.id_random} with product ID {order_line_obj_curr.product_id_random}')
if order_line_del_result := sql_delete(table_name='order_line', record_id_random=order_line_obj_curr.id_random):
app.logger.info(f'Deleted record and now pop the current list item {index}...')
order_line_obj_li_curr.pop(index)
else:
app.logger.info(f'Current order line product ID matched. Keeping order line ID {order_line_obj_curr.id_random} with product ID {order_line_obj_curr.product_id_random}')
# NOTE: That this current order line item will be updated below.
app.logger.debug(order_line_obj_li_curr)
#app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.info('Loop through the line list that was sent and compare with what was pulled from the DB')
# Loop through the new line list that was sent and compare with the current line list that was pulled from the DB
# Only insert if a product ID does not match
# Only update if a product ID does match
for order_line_obj_new in order_obj_new.order_line_list:
app.logger.info(f'New: order line ID={order_line_obj_new.id_random} and product ID= {order_line_obj_new.product_id_random}')
matched_product_id = False
for index, order_line_obj_curr in enumerate(order_line_obj_li_curr):
app.logger.debug(f'Checking current: product ID={order_line_obj_curr.product_id_random}')
if order_line_obj_new.product_id_random == order_line_obj_curr.product_id_random:
matched_product_id = True
app.logger.debug(f'Matched: product ID={order_line_obj_curr.product_id_random}')
app.logger.info(f'Updating the current line item with the new line item.')
order_line_obj_new.id_random = order_line_obj_curr.id_random
order_line_obj_new.id = order_line_obj_curr.id
order_line_obj_li_curr[index] = order_line_obj_new
break
else:
app.logger.debug(f'No match: product ID={order_line_obj_curr.product_id_random}')
if not matched_product_id: # Was not found in the current order line list that was pulled from the DB
app.logger.info(f'New order line product ID did not match any of the current list. Append order line ID {order_line_obj_new.id_random} with product ID {order_line_obj_new.product_id_random}')
app.logger.info('Append to current list...')
order_line_obj_li_curr.append(order_line_obj_new) # These will be inserted/updated below
# Save merged current and new list to the new order object
order_obj_new.order_line_list = order_line_obj_li_curr
app.logger.debug(order_obj_new)
# Final loop through to get the new order totals
# Calculate totals
order_total_amount:int = 0
order_total_quantity:int = 0
for order_line_obj_new in order_obj_new.order_line_list:
order_total_amount += order_line_obj_new.quantity * order_line_obj_new.amount
order_total_quantity += order_line_obj_new.quantity
order_obj_new.total_bill = order_total_amount # "amount" is used by order_cart and Stripe
order_obj_new.total_quantity = order_total_quantity
order_obj_new.balance = order_total_amount - order_obj_new.total_paid
app.logger.debug(order_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=True, exclude={'order_line_list', 'cfg', 'created_on', 'updated_on'}))
order_obj_data = order_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=True, exclude={'order_line_list', 'cfg', 'created_on', 'updated_on'})
# SQL INSERT or UPDATE the order record
app.logger.info('SQL INSERT or UPDATE the order record')
if order_obj_resp := sql_insert_or_update(data=order_obj_data, table_name='order', rm_id_random=True, id_random_length=8): pass
else: return False
#app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(order_obj_resp)
if isinstance(order_obj_resp, bool) and order_obj_resp:
if order_id := order_obj_new.id: pass
elif order_id := order_obj_new.id_random: pass
elif isinstance(order_obj_resp, int):
order_id = order_obj_resp
else:
return False
app.logger.debug(f'Order ID={order_id}')
# Loop through the order_line list to SQL INSERT or UPDATE the records
app.logger.info('Loop through the order_line list to SQL INSERT or UPDATE the records')
for order_line_obj_new in order_obj_new.order_line_list:
app.logger.info(f"New order_line: order_line_id_random={order_line_obj_new.id_random}; product_id_random={order_line_obj_new.product_id_random}")
app.logger.debug(order_line_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=False, exclude={'order_line_id_random', 'product_type_id', 'product_type', 'created_on', 'updated_on'}))
order_line_obj_data = order_line_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=True, exclude={'order_line_id_random', 'product_type_id', 'product_type', 'created_on', 'updated_on'})
order_line_obj_data['order_id'] = order_id
if order_line_obj_resp := sql_insert_or_update(sql=None, data=order_line_obj_data, table_name='order_line', rm_id_random=True, id_random_length=8): pass
else: return False
app.logger.debug(order_line_obj_resp)
return order_id
# ### END ### API Membership Model ### save_membership_obj() ###
# ### BEGIN ### API Membership Model ### get_membership_obj() ###
def get_membership_obj(membership_id=None, inc_membership_profile=None, inc_membership_cfg=None, inc_cust_profile=None):
app.logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
if membership_id := redis_lookup_id_random(record_id_random=membership_id, table_name='membership'): pass
else:
return False
if membership_rec := sql_select(table_name='v_membership', record_id=membership_id):
#app.logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(membership_rec)
if inc_membership_profile:
if membership_profile_rec := sql_select(table_name='v_membership_profile', field_name='membership_id', field_value=membership_id):
#app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(membership_profile_rec)
membership_rec['profile'] = membership_profile_rec
if inc_membership_cfg:
if membership_cfg_rec := sql_select(table_name='v_membership_cfg', field_name='account_id', field_value=membership_rec.get('account_id', None)):
#app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(membership_cfg_rec)
membership_rec['cfg'] = membership_cfg_rec
if inc_cust_profile:
account_code = membership_rec.get('account_code', None)
table_name = f'c_{account_code}_membership_profile'
if cust_profile_rec := sql_select(table_name=table_name, field_name='membership_id', field_value=membership_id):
#app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(cust_profile_rec)
membership_rec['cust_profile'] = cust_profile_rec
#app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(membership_rec)
else:
return False
try:
membership_obj = Membership_Base(**membership_rec)
app.logger.debug(membership_obj)
except ValidationError as e:
app.logger.error(e.json())
return membership_obj
# ### END ### API Membership Model ### get_membership_obj() ###

View File

@@ -0,0 +1,330 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
class Order_Cart_Cfg_Base(BaseModel):
app.logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
account_name: Optional[str]
show_cart: Optional[bool]
cart_label: Optional[str]
class Order_Cart_Line_Base(BaseModel):
app.logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
id_random: Optional[str] = Field(
**base_fields['order_cart_line_id_random'],
alias='order_cart_line_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='order_cart_line_id'
)
#order_cart_line_id_random: Optional[str]
order_cart_id_random: Optional[str]
order_cart_id: Optional[int]
product_id_random: str
product_id: Optional[int]
product_type_id: Optional[int]
product_type: Optional[str]
product_name: Optional[str]
product_description: Optional[str]
product_unit_price: Optional[int] = Field(0, ge=0, lt=1500000)
product_max_quantity: Optional[int] = Field(0, ge=0, lt=150)
quantity: int = Field(0, ge=0, lt=150)
amount: int = Field(0, ge=0, lt=1500000)
recurring: Optional[bool] = False
message: Optional[str]
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('order_cart_line_id_random', always=True)
def order_cart_line_id_random_copy(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def order_cart_line_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
app.logger.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='order_cart_line')
return None
@validator('order_cart_id', always=True)
def order_cart_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['order_cart_id_random']:
return redis_lookup_id_random(record_id_random=values['order_cart_id_random'], table_name='order_cart')
return None
@validator('product_id', always=True)
def product_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['product_id_random']:
return redis_lookup_id_random(record_id_random=values['product_id_random'], table_name='product')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
class Order_Cart_Base(BaseModel):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
id_random: Optional[str] = Field(
**base_fields['order_cart_id_random'],
alias='order_cart_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='order_cart_id'
)
#order_cart_id_random: Optional[str]
#order_cart_id: Optional[int]
account_id_random: Optional[str]
account_id: Optional[int] # NOTE: This is not really optional
person_id_random: Optional[str]
person_id: Optional[int]
user_id_random: Optional[str]
user_id: Optional[int]
order_id_random: Optional[str]
order_id: Optional[int]
total_quantity: Optional[int] = Field(0, ge=0, lt=150)
total_amount: Optional[int] = Field(0, ge=0, lt=1500000)
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
order_cart_line_list: List[Order_Cart_Line_Base] = []
cfg: Optional[Order_Cart_Cfg_Base] = Order_Cart_Cfg_Base()
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('order_cart_id_random', always=True)
def order_cart_id_random_copy(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def order_cart_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='order_cart')
return None
@validator('account_id', always=True)
def account_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['account_id_random']:
return redis_lookup_id_random(record_id_random=values['account_id_random'], table_name='account')
return None
@validator('person_id', always=True)
def person_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['person_id_random']:
return redis_lookup_id_random(record_id_random=values['person_id_random'], table_name='person')
return None
@validator('user_id', always=True)
def user_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['user_id_random']:
return redis_lookup_id_random(record_id_random=values['user_id_random'], table_name='user')
return None
@validator('order_id', always=True)
def order_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if 'order_id_random' in values and values['order_id_random']:
return redis_lookup_id_random(record_id_random=values['order_id_random'], table_name='order')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
# ### BEGIN ### API Order Cart Model ### save_order_cart_obj() ###
def save_order_cart_obj(order_cart_obj_new=None):
app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
if not order_cart_obj_new:
return False
#app.logger.debug(order_cart_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=True))
# Get the current order_cart_line list to compare with what was sent
data = {}
data['order_cart_id_random'] = order_cart_obj_new.id_random
if order_cart_line_rec_li_curr := sql_select(table_name='v_order_cart_line', data=data, rm_id_random=True, as_list=True):
#app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
#app.logger.debug(order_cart_line_rec_li_curr)
order_cart_line_obj_li_curr = []
for order_cart_line_rec in order_cart_line_rec_li_curr:
try:
order_cart_line_obj = Order_Cart_Line_Base(**order_cart_line_rec)
app.logger.debug(order_cart_line_obj)
except ValidationError as e:
app.logger.error(e.json())
order_cart_line_obj_li_curr.append(order_cart_line_obj)
#app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(order_cart_line_obj_li_curr)
else:
#app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(order_cart_line_rec_li_curr)
order_cart_line_obj_li_curr = []
# Loop through the line list that was sent and compare with what was pulled from the DB
# Only insert if a product ID does not match
# Only update if a product ID does match
for order_cart_line_obj_new in order_cart_obj_new.order_cart_line_list:
app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
if not any(order_cart_line_obj_curr.product_id_random == order_cart_line_obj_new.product_id_random for order_cart_line_obj_curr in order_cart_line_obj_li_curr):
# Need to append to current list
app.logger.info('Need to append to current list')
order_cart_line_obj_li_curr.append(order_cart_line_obj_new)
else:
# Need to update a current list item ... loop through to find
app.logger.info('Need to update a current list item ... loop through to find')
for index, order_cart_line_obj_curr in enumerate(order_cart_line_obj_li_curr):
app.logger.info(index)
if order_cart_line_obj_new.product_id_random == order_cart_line_obj_curr.product_id_random:
app.logger.info(f'Match: {order_cart_line_obj_curr.product_id_random}')
order_cart_line_obj_new.id_random = order_cart_line_obj_curr.id_random
order_cart_line_obj_li_curr[index] = order_cart_line_obj_new
else:
app.logger.info(f'Not a match: {order_cart_line_obj_curr.product_id_random}')
# Save merged current and new list to the new order cart object
order_cart_obj_new.order_cart_line_list = order_cart_line_obj_li_curr
app.logger.debug(order_cart_obj_new)
# Final loop through to get the new order totals
# Calculate totals
order_cart_total_amount = 0
order_cart_total_quantity = 0
for order_cart_line_obj_curr in order_cart_line_obj_li_curr:
order_cart_total_amount += order_cart_line_obj_curr.quantity * order_cart_line_obj_curr.amount
order_cart_total_quantity += order_cart_line_obj_curr.quantity
order_cart_obj_new.total_amount = order_cart_total_amount
order_cart_obj_new.total_quantity = order_cart_total_quantity
app.logger.debug(order_cart_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=True, exclude={'order_cart_id_random', 'order_cart_line_list', 'cfg', 'created_on', 'updated_on'}))
order_cart_obj_data = order_cart_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=True, exclude={'order_cart_id_random', 'order_cart_line_list', 'cfg', 'created_on', 'updated_on'})
# SQL INSERT or UPDATE the order_cart record
app.logger.info('SQL INSERT or UPDATE the order_cart record')
if order_cart_obj_resp := sql_insert_or_update(sql=None, data=order_cart_obj_data, table_name='order_cart', rm_id_random=True, id_random_length=8): pass
else: return False
app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(order_cart_obj_resp)
if isinstance(order_cart_obj_resp, bool) and order_cart_obj_resp:
if order_cart_id := order_cart_obj_new.id: pass
elif order_cart_id := order_cart_obj_new.id_random: pass
elif isinstance(order_cart_obj_resp, int):
order_cart_id = order_cart_obj_resp
else:
return False
# Loop through the order_cart_line list to SQL INSERT or UPDATE the records
app.logger.info('Loop through the order_cart_line list to SQL INSERT or UPDATE the records')
for order_cart_line_obj in order_cart_obj_new.order_cart_line_list:
app.logger.debug(f"--- {order_cart_line_obj}")
app.logger.debug(order_cart_line_obj.dict(by_alias=False, exclude_defaults=False, exclude_unset=False, exclude={}))
order_cart_line_obj_data = order_cart_line_obj.dict(by_alias=False, exclude_defaults=False, exclude_unset=True, exclude={'product_type_id', 'product_type', 'product_name', 'product_description', 'product_unit_price', 'product_max_quantity', 'order_cart_line_id_random', 'created_on', 'updated_on'})
order_cart_line_obj_data['order_cart_id'] = order_cart_id
if order_cart_line_obj_resp := sql_insert_or_update(sql=None, data=order_cart_line_obj_data, table_name='order_cart_line', rm_id_random=True, id_random_length=8): pass
else: return False
app.logger.debug(order_cart_line_obj_resp)
return order_cart_id
# ### END ### API Order Cart Model ### save_order_cart_obj() ###
# ### BEGIN ### API Order Cart Model ### get_order_cart_obj() ###
def get_order_cart_obj(order_cart_id=None, inc_order_cart_line_li=None, inc_order_cart_cfg=None):
app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
if order_cart_id := redis_lookup_id_random(record_id_random=order_cart_id, table_name='order_cart'): pass
else:
return False
if order_cart_rec := sql_select(table_name='v_order_cart', record_id=order_cart_id):
#app.logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(order_cart_rec)
if inc_order_cart_line_li:
order_cart_line_data = {}
order_cart_line_data['order_cart_id'] = order_cart_id
if order_cart_line_rec_li := sql_select(table_name='v_order_cart_line', data=order_cart_line_data, as_list=True):
order_cart_rec['order_cart_line_list'] = order_cart_line_rec_li
if inc_order_cart_cfg:
if order_cart_cfg_rec := sql_select(table_name='v_account_cfg_detail', field_name='account_id', field_value=order_cart_rec.get('account_id', None)):
order_cart_rec['cfg'] = order_cart_cfg_rec
app.logger.debug(order_cart_rec)
else:
return False
try:
order_cart_obj = Order_Cart_Base(**order_cart_rec)
app.logger.debug(order_cart_obj)
except ValidationError as e:
app.logger.error(e.json())
return order_cart_obj
# ### END ### API Order Cart Model ### get_order_cart_obj() ###

209
app/models/order_methods.py Normal file
View File

@@ -0,0 +1,209 @@
from __future__ import annotations
import datetime
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator
from .log import *
from .db_sql import sql_select
from .order_model import Order_Base
from .person_model import Person_Base
from .user_model import User_Base
#from myapp.lib_general import *
#from myapp.help_crud import *
# ### BEGIN ### API Order Model ### save_order_obj() ###
def save_order_obj(order_obj_new:Order_Base=None, repl_order_line_list:bool=False):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
if not order_obj_new:
return False
log.debug(order_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=True))
order_line_obj_li_curr = [] # Initialize to store order_line list
if order_obj_new.id_random:
log.info(f'An order.id {order_obj_new.id} or order.id_random {order_obj_new.id_random} was included. We can update an existing order.')
log.info(f'Get the current order_line list to compare with what was sent...')
data = {}
data['order_id_random'] = order_obj_new.id_random
if order_line_rec_li_curr := sql_select(table_name='v_order_line', data=data, rm_id_random=True, as_list=True):
#log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(order_line_rec_li_curr)
for order_line_rec in order_line_rec_li_curr:
try:
order_line_obj = Order_Line_Base(**order_line_rec)
log.debug(order_line_obj)
except ValidationError as e:
log.error(e.json())
order_line_obj_li_curr.append(order_line_obj)
else:
log.info(f'No order_line records were found')
elif order_obj_new.account_id_random and (order_obj_new.person_id_random or order_obj_new.user_id_random):
log.info(f'An account.id_random {order_obj_new.account_id_random} was passed. And either a person.id_random {order_obj_new.person_id_random} or user.id_random {order_obj_new.user_id_random} was passed. We can create a new order.')
# Because there was not an order ID, assume there are no order lines yet. So no look up.
else:
log.info('Either an order ID is required to update an order or an account ID along with a person ID or user ID is required to create an order.')
return False
#log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(order_line_obj_li_curr)
if repl_order_line_list: # This will remove any order line list items not sent with the new order information.
log.info('Removing any order line list items not sent with the new order information...')
for index, order_line_obj_curr in enumerate(order_line_obj_li_curr):
log.info(f'Current: order line ID={order_line_obj_curr.id_random} and product ID= {order_line_obj_curr.product_id_random}')
matched_product_id = False
for order_line_obj_new in order_obj_new.order_line_list:
log.debug(f'Checking new: product ID={order_line_obj_new.product_id_random}')
if order_line_obj_curr.product_id_random == order_line_obj_new.product_id_random:
matched_product_id = True
log.debug(f'Matched: product ID={order_line_obj_new.product_id_random}')
break
else:
log.debug(f'No match: product ID={order_line_obj_new.product_id_random}')
if not matched_product_id: # Was not found in the new order line list sent
log.info(f'Current order line product ID did not match any of the new list. DELETE order line ID {order_line_obj_curr.id_random} with product ID {order_line_obj_curr.product_id_random}')
if order_line_del_result := sql_delete(table_name='order_line', record_id_random=order_line_obj_curr.id_random):
log.info(f'Deleted record and now pop the current list item {index}...')
order_line_obj_li_curr.pop(index)
else:
log.info(f'Current order line product ID matched. Keeping order line ID {order_line_obj_curr.id_random} with product ID {order_line_obj_curr.product_id_random}')
# NOTE: That this current order line item will be updated below.
log.debug(order_line_obj_li_curr)
#log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.info('Loop through the line list that was sent and compare with what was pulled from the DB')
# Loop through the new line list that was sent and compare with the current line list that was pulled from the DB
# Only insert if a product ID does not match
# Only update if a product ID does match
for order_line_obj_new in order_obj_new.order_line_list:
log.info(f'New: order line ID={order_line_obj_new.id_random} and product ID= {order_line_obj_new.product_id_random}')
matched_product_id = False
for index, order_line_obj_curr in enumerate(order_line_obj_li_curr):
log.debug(f'Checking current: product ID={order_line_obj_curr.product_id_random}')
if order_line_obj_new.product_id_random == order_line_obj_curr.product_id_random:
matched_product_id = True
log.debug(f'Matched: product ID={order_line_obj_curr.product_id_random}')
log.info(f'Updating the current line item with the new line item.')
order_line_obj_new.id_random = order_line_obj_curr.id_random
order_line_obj_new.id = order_line_obj_curr.id
order_line_obj_li_curr[index] = order_line_obj_new
break
else:
log.debug(f'No match: product ID={order_line_obj_curr.product_id_random}')
if not matched_product_id: # Was not found in the current order line list that was pulled from the DB
log.info(f'New order line product ID did not match any of the current list. Append order line ID {order_line_obj_new.id_random} with product ID {order_line_obj_new.product_id_random}')
log.info('Append to current list...')
order_line_obj_li_curr.append(order_line_obj_new) # These will be inserted/updated below
# Save merged current and new list to the new order object
order_obj_new.order_line_list = order_line_obj_li_curr
log.debug(order_obj_new)
# Final loop through to get the new order totals
# Calculate totals
order_total_amount:int = 0
order_total_quantity:int = 0
for order_line_obj_new in order_obj_new.order_line_list:
order_total_amount += order_line_obj_new.quantity * order_line_obj_new.amount
order_total_quantity += order_line_obj_new.quantity
order_obj_new.total_bill = order_total_amount # "amount" is used by order_cart and Stripe
order_obj_new.total_quantity = order_total_quantity
order_obj_new.balance = order_total_amount - order_obj_new.total_paid
log.debug(order_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=True, exclude={'order_line_list', 'cfg', 'created_on', 'updated_on'}))
order_obj_data = order_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=True, exclude={'order_line_list', 'cfg', 'created_on', 'updated_on'})
# SQL INSERT or UPDATE the order record
log.info('SQL INSERT or UPDATE the order record')
if order_obj_resp := sql_insert_or_update(data=order_obj_data, table_name='order', rm_id_random=True, id_random_length=8): pass
else: return False
#log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(order_obj_resp)
if isinstance(order_obj_resp, bool) and order_obj_resp:
if order_id := order_obj_new.id: pass
elif order_id := order_obj_new.id_random: pass
elif isinstance(order_obj_resp, int):
order_id = order_obj_resp
else:
return False
log.debug(f'Order ID={order_id}')
# Loop through the order_line list to SQL INSERT or UPDATE the records
log.info('Loop through the order_line list to SQL INSERT or UPDATE the records')
for order_line_obj_new in order_obj_new.order_line_list:
log.info(f"New order_line: order_line_id_random={order_line_obj_new.id_random}; product_id_random={order_line_obj_new.product_id_random}")
log.debug(order_line_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=False, exclude={'order_line_id_random', 'product_type_id', 'product_type', 'created_on', 'updated_on'}))
order_line_obj_data = order_line_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=True, exclude={'order_line_id_random', 'product_type_id', 'product_type', 'created_on', 'updated_on'})
order_line_obj_data['order_id'] = order_id
if order_line_obj_resp := sql_insert_or_update(sql=None, data=order_line_obj_data, table_name='order_line', rm_id_random=True, id_random_length=8): pass
else: return False
log.debug(order_line_obj_resp)
return order_id
# ### END ### API Order Model ### save_order_obj() ###
# ### BEGIN ### API Order Model ### get_order_obj() ###
def get_order_obj(order_id=None, inc_order_line_li=None, inc_order_cfg=None, inc_person_obj=None, inc_user_obj=None):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
if order_id := redis_lookup_id_random(record_id_random=order_id, table_name='order'): pass
else:
return False
if order_rec := sql_select(table_name='v_order', record_id=order_id):
#log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(order_rec)
if inc_order_line_li:
order_line_data = {}
order_line_data['order_id'] = order_id
if order_line_rec_li := sql_select(table_name='v_order_line', data=order_line_data, as_list=True):#, field_name='order_id', field_value=order_id):
log.debug(order_line_rec_li)
order_rec['order_line_list'] = order_line_rec_li
if inc_order_cfg:
if order_cfg_rec := sql_select(table_name='v_account_cfg_detail', field_name='account_id', field_value=order_rec.get('account_id', None)):
#log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(order_cfg_rec)
order_rec['cfg'] = order_cfg_rec
if inc_person_obj:
if person_rec := sql_select(table_name='v_person', field_name='person_id', field_value=order_rec.get('person_id', None)):
#log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(person_rec)
order_rec['person'] = person_rec
log.debug(order_rec)
else:
return False
try:
order_obj = Order_Base(**order_rec)
log.debug(order_obj)
except ValidationError as e:
log.error(e.json())
return order_obj
# ### END ### API Order Model ### get_order_obj() ###

197
app/models/order_model.py Normal file
View File

@@ -0,0 +1,197 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
#from .supporting_core_models import *
from .person_model import Person_Base
from .user_model import User_Base
class Order_Cfg_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
account_name: Optional[str]
default_no_reply_email: Optional[str]
default_no_reply_name: Optional[str]
confirm_email: Optional[str]
confirm_name: Optional[str]
order_header: Optional[str]
order_thanks: Optional[str]
order_message: Optional[str]
order_footer: Optional[str]
order_fundraising_thanks: Optional[str]
order_fundraising_message: Optional[str]
class Order_Line_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
id_random: Optional[str] = Field(
**base_fields['order_line_id_random'],
alias='order_line_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='order_line_id'
)
#order_line_id_random: Optional[str]
order_id_random: Optional[str]
order_id: Optional[int]
product_id_random: str
product_id: Optional[int]
product_type_id: Optional[int]
product_type: Optional[str]
name: Optional[str]
description: Optional[str]
quantity: int = Field(0, ge=0, lt=150)
amount: int = Field(0, ge=0, lt=1500000)
recurring: Optional[bool] = False
message: Optional[str]
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('order_line_id_random', always=True)
def order_line_id_random_copy(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def order_line_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
log.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='order_line')
return None
@validator('order_id', always=True)
def order_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['order_id_random']:
return redis_lookup_id_random(record_id_random=values['order_id_random'], table_name='order')
return None
@validator('product_id', always=True)
def product_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['product_id_random']:
return redis_lookup_id_random(record_id_random=values['product_id_random'], table_name='product')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
class Order_Base(BaseModel):
log.setLevel(logging.WARNING)
log.debug(locals())
# from .person_model import Person_Base
# from .user_model import User_Base
id_random: Optional[str] = Field(
**base_fields['order_id_random'],
alias='order_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='order_id'
)
#order_id_random: Optional[str]
#order_id: Optional[int]
account_id_random: Optional[str]
account_id: Optional[int] # NOTE: This is not really optional
person_id_random: Optional[str]
person_id: Optional[int]
user_id_random: Optional[str]
user_id: Optional[int]
total_quantity: Optional[int] = Field(0, ge=0, lt=150)
total_bill: Optional[int] = Field(0, ge=0, lt=1500000) # NOTE: This is total_amount in the order_cart
total_paid: Optional[int] = Field(0, ge=0, lt=1500000)
balance: Optional[int] = Field(0, ge=-1500000, lt=1500000) # Balance needs to be calculated
status: Optional[str]
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
order_line_list: List[Order_Line_Base] = []
cfg: Optional[Order_Cfg_Base] = Order_Cfg_Base()
person: Optional[Person_Base] = Person_Base()
user: Optional[User_Base] = User_Base()
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('order_id_random', always=True)
def order_id_random_copy(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def order_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='order')
return None
@validator('account_id', always=True)
def account_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['account_id_random']:
return redis_lookup_id_random(record_id_random=values['account_id_random'], table_name='account')
return None
@validator('person_id', always=True)
def person_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['person_id_random']:
return redis_lookup_id_random(record_id_random=values['person_id_random'], table_name='person')
return None
@validator('user_id', always=True)
def user_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['user_id_random']:
return redis_lookup_id_random(record_id_random=values['user_id_random'], table_name='user')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields

View File

@@ -0,0 +1,135 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
#from .account_model import Account_Base
from .contact_model import Contact_Base
#from .person_model import Person_Base
#from .user_model import User_Base
class Organization_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
#from .account_model import Account_Base
#from .contact_model import Contact_Base
#from .person_model import Person_Base
#from .user_model import User_Base
id_random: Optional[str] = Field(
**base_fields['organization_id_random'],
alias='organization_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='organization_id'
)
account_id_random: Optional[str]
account_id: Optional[int]
contact_id_random: Optional[str]
contact_id: Optional[int]
person_id_random: Optional[str]
person_id: Optional[int]
user_id_random: Optional[str]
user_id: Optional[int]
name: Optional[str]
tagline: Optional[str]
description: Optional[str]
company: Optional[bool]
nonprofit: Optional[bool]
industry: Optional[int]
start_date: Optional[datetime.datetime] = None
end_date: Optional[datetime.datetime] = None
path_logo: Optional[str]
logo_bg_color: Optional[str]
path_thumbnail: Optional[str]
thumbnail_bg_color: Optional[str]
priority: Optional[int]
sort: Optional[int]
group: Optional[str]
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
#account: Optional[Account_Base] = Account_Base()
contact: Optional[Contact_Base] = Contact_Base()
#person: Optional[Person_Base] = Person_Base()
#user: Optional[User_Base] = User_Base()
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('organization_id_random', always=True)
def organization_id_random_copy(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def organization_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
log.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='organization')
return None
@validator('account_id', always=True)
def account_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['account_id_random']:
return redis_lookup_id_random(record_id_random=values['account_id_random'], table_name='account')
return None
@validator('contact_id', always=True)
def contact_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['contact_id_random']:
return redis_lookup_id_random(record_id_random=values['contact_id_random'], table_name='contact')
return None
@validator('person_id', always=True)
def person_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['person_id_random']:
return redis_lookup_id_random(record_id_random=values['person_id_random'], table_name='person')
return None
@validator('user_id', always=True)
def user_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['user_id_random']:
return redis_lookup_id_random(record_id_random=values['user_id_random'], table_name='user')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
#if TYPE_CHECKING:
#from .supporting_core_models import Address_Base, Contact_Base, Person_Base, User_Base
Organization_Base.update_forward_refs()

71
app/models/page_model.py Normal file
View File

@@ -0,0 +1,71 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
class Page_Base(BaseModel):
app.logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
id_random: Optional[str] = Field(
**base_fields['page_id_random'],
alias='page_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='page_id'
)
account_id_random: Optional[str]
account_id: Optional[int]
alias: Optional[str]
name: Optional[str]
enable: Optional[bool]
enable_from: Optional[datetime.datetime] = None
enable_to: Optional[datetime.datetime] = None
title: Optional[str]
body: Optional[str]
style_href: Optional[str]
script_src: Optional[str]
authentication_required: Optional[bool]
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('page_id_random', always=True)
def page_id_random_copy(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def page_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
app.logger.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='page')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
Page_Base.update_forward_refs()

122
app/models/person_model.py Normal file
View File

@@ -0,0 +1,122 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
# from .account_model import Account_Base
from .contact_model import Contact_Base
from .organization_model import Organization_Base
# from .user_model import User_Base
class Person_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
#from .account_model import Account_Base
#from .contact_model import Contact_Base
#from .organization_model import Organization_Base
#from .user_model import User_Base
#from .organization_model import Organization_Base
#if TYPE_CHECKING:
#from .supporting_core_models import Address_Base, Contact_Base, Organization_Base, Person_Base, User_Base
#from .supporting_core_models import Address_Base, Contact_Base, Organization_Base, User_Base
id_random: Optional[str] = Field(
**base_fields['person_id_random'],
alias='person_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='person_id'
)
user_id_random: Optional[str]
user_id: Optional[int]
organization_id_random: Optional[str]
organization_id: Optional[int]
contact_id_random: Optional[str]
contact_id: Optional[int]
given_name: Optional[str]
family_name: Optional[str]
middle_name: Optional[str]
prefix: Optional[str]
suffix: Optional[str]
full_name: Optional[str]
informal_name: Optional[str]
title: Optional[str]
organization_name: Optional[str]
tagline: Optional[str]
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
contact: Optional[Contact_Base] = Contact_Base()
organization: Optional[Organization_Base] = Organization_Base()
#user: Optional[User_Base] = User_Base()
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('person_id_random', always=True)
def person_id_random_copy(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def person_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
log.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='person')
return None
@validator('user_id', always=True)
def user_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['user_id_random']:
return redis_lookup_id_random(record_id_random=values['user_id_random'], table_name='user')
return None
@validator('organization_id', always=True)
def organization_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['organization_id_random']:
return redis_lookup_id_random(record_id_random=values['organization_id_random'], table_name='organization')
return None
@validator('contact_id', always=True)
def contact_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['contact_id_random']:
return redis_lookup_id_random(record_id_random=values['contact_id_random'], table_name='contact')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
#from .supporting_core_models import Address_Base, Contact_Base, Organization_Base, User_Base
Person_Base.update_forward_refs()

View File

@@ -0,0 +1,92 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
class Product_Base(BaseModel):
app.logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
id_random: Optional[str] = Field(
**base_fields['product_id_random'],
alias='product_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='product_id'
)
account_id_random: Optional[str]
account_id: Optional[int]
type_id: Optional[int]
type_name: Optional[str] = Field(
alias='type'
)
name: Optional[str]
description: Optional[str]
image_url: Optional[str]
image_small_url: Optional[str]
unit_price: int = Field(0, ge=0, lt=1500000)
tax_rate: Optional[int]
lu_vat_id: Optional[int]
vat_rate: Optional[int]
max_quantity: Optional[int] = Field(0, ge=0, lt=150)
recurring: Optional[bool] = False
recurring_period: Optional[int]
recurring_lu_unit_id: Optional[int]
recurring_unit: Optional[str]
enable: Optional[bool]
enable_from: Optional[datetime.datetime] = None
enable_to: Optional[datetime.datetime] = None
lu_account_code_id: Optional[int]
lu_account_code_deferred_id: Optional[int]
metadata: Optional[str]
hide: Optional[int]
priority: Optional[int]
sort: Optional[int]
group: Optional[str]
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('product_id_random', always=True)
def product_id_random_copy(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def product_id_lookup(cls, v, values, **kwargs):
app.logger.setLevel(logging.WARNING)
app.logger.debug(locals())
if values['id_random']:
app.logger.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='product')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
Product_Base.update_forward_refs()

View File

@@ -0,0 +1,64 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from app.config import settings
from .common_field_schema import base_fields, default_num_bytes
# The pydantic BaseModel to help make consistent REST responses - STI 2021-03-05
class Resp_Body_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
data: Union[dict, list]
meta: Optional[dict]
# The make response function for REST - STI 2021-03-05
def mk_resp(data={}, dict_to_json=None, status_code=200, status_message=None, status_name=None, success=True, details=None, by_alias=True, exclude_unset=True):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
if data is None: data = { 'result': None }
elif data == False: data = { 'result': False }
elif data == True: data = { 'result': True }
resp_body = {}
resp_body['data'] = data
resp_body['meta'] = {}
resp_body['meta']['details'] = details
resp_body['meta']['status_code'] = status_code
resp_body['meta']['status_message'] = settings.HTTP_STATUS_LI[status_code]['message']
resp_body['meta']['status_name'] = settings.HTTP_STATUS_LI[status_code]['name']
resp_body['meta']['success'] = success
if isinstance(data, bool):
resp_body['meta']['data_type'] = 'bool'
elif isinstance(data, int):
resp_body['meta']['data_type'] = 'int'
elif isinstance(data, str):
resp_body['meta']['data_type'] = 'str'
elif isinstance(data, dict):
resp_body['meta']['data_type'] = 'dict'
elif isinstance(data, list):
resp_body['meta']['data_type'] = 'list'
resp_body['meta']['data_list_count'] = len(data)
log.debug(type(resp_body['data']))
resp_body = Resp_Body_Base(**resp_body).dict(by_alias=by_alias, exclude_unset=exclude_unset)
#resp_body_json = resp_body.json(by_alias=True, exclude_unset=False)
#response = app.response_class(
#response=resp_body_json,
#status=status_code,
#mimetype='application/json'
#)
return resp_body

View File

@@ -0,0 +1,74 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
class Site_Domain_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
id_random: Optional[str] = Field(
**base_fields['site_domain_id_random'],
alias='site_domain_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='site_domain_id'
)
site_id_random: Optional[str]
site_id: Optional[int]
fqdn: Optional[str]
# restrict_access: Optional[bool]
access_key: Optional[str]
required_referrer: Optional[bool]
valid_for: Optional[int] # number of hours
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('site_domain_id_random', always=True)
def site_domain_id_random_copy(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def site_domain_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
log.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='site_domain')
return None
@validator('site_id', always=True)
def site_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['site_id_random']:
return redis_lookup_id_random(record_id_random=values['site_id_random'], table_name='site')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
Site_Domain_Base.update_forward_refs()

115
app/models/site_model.py Normal file
View File

@@ -0,0 +1,115 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
class Site_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
id_random: Optional[str] = Field(
**base_fields['site_id_random'],
alias='site_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='site_id'
)
account_id_random: Optional[str]
account_id: Optional[int]
code: Optional[str]
# fqdn_1: Optional[str]
# fqdn_2: Optional[str]
# fqdn_3: Optional[str]
name: Optional[str]
description: Optional[str]
restrict_access: Optional[bool]
access_key: Optional[str]
enable: Optional[bool]
enable_from: Optional[datetime.datetime] = None
enable_to: Optional[datetime.datetime] = None
path_logo: Optional[str]
logo_bg_color: Optional[str]
path_banner_image: Optional[str]
banner_bg_color: Optional[str]
path_background_image: Optional[str]
background_bg_color: Optional[str]
path_html_menu: Optional[str]
title: Optional[str]
html_menu: Optional[str]
html_header: Optional[str]
html_header_h1: Optional[str]
html_header_h2: Optional[str]
html_banner: Optional[str]
html_root_body: Optional[str]
html_tagline: Optional[str]
logo_filename: Optional[str]
banner_image_filename: Optional[str]
banner_html: Optional[str]
site_title: Optional[str]
site_menu_html_path: Optional[str]
site_header_h1: Optional[str]
site_header_h2: Optional[str]
site_body: Optional[str]
site_tagline: Optional[str]
style_href: Optional[str]
script_src: Optional[str]
google_tracking_id: Optional[str]
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('site_id_random', always=True)
def site_id_random_copy(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def site_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
log.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='site')
return None
@validator('account_id', always=True)
def account_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['account_id_random']:
return redis_lookup_id_random(record_id_random=values['account_id_random'], table_name='account')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
Site_Base.update_forward_refs()

141
app/models/user_model.py Normal file
View File

@@ -0,0 +1,141 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
#from .account_model import Account_Base
from .contact_model import Contact_Base
#from .organization_model import Organization_Base
#from .person_model import Person_Base
class User_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
#from .account_model import Account_Base
#from .contact_model import Contact_Base
#from .organization_model import Organization_Base
#from .person_model import Person_Base
#if TYPE_CHECKING:
#from .person_model import Person_Base
id_random: Optional[str] = Field(
**base_fields['user_id_random'],
alias='user_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='user_id'
)
account_id_random: Optional[str]
account_id: Optional[int]
contact_id_random: Optional[str]
contact_id: Optional[int]
organization_id_random: Optional[str]
organization_id: Optional[int]
person_id_random: Optional[str]
person_id: Optional[int]
username: Optional[str]
name: Optional[str]
email: Optional[str]
email_verified: Optional[bool]
password: Optional[str]
auth_key: Optional[str]
enable: Optional[bool]
enable_from: Optional[datetime.datetime] = None
enable_to: Optional[datetime.datetime] = None
super: Optional[bool]
manager: Optional[bool]
administrator: Optional[bool]
public: Optional[bool]
verified: Optional[bool]
status_id: Optional[int]
status_name: Optional[str]
password_set_on: Optional[datetime.datetime] = None
password_reset_token: Optional[str] = None
password_reset_expire_on: Optional[datetime.datetime] = None
logged_in_on: Optional[datetime.datetime] = None
last_activity_on: Optional[datetime.datetime] = None
#account: Optional[Account_Base]# = Account_Base()
contact: Optional[Contact_Base]# = Contact_Base()
#organization: Optional[Organization_Base]# = Organization_Base()
#person: Optional[Person_Base]# = Person_Base()
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('user_id_random', always=True)
def user_id_random_copy(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
return values['id_random']
return None
@validator('id', always=True)
def user_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
log.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='user')
return None
@validator('account_id', always=True)
def account_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['account_id_random']:
return redis_lookup_id_random(record_id_random=values['account_id_random'], table_name='account')
return None
@validator('contact_id', always=True)
def contact_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['contact_id_random']:
return redis_lookup_id_random(record_id_random=values['contact_id_random'], table_name='contact')
return None
@validator('organization_id', always=True)
def organization_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['organization_id_random']:
return redis_lookup_id_random(record_id_random=values['organization_id_random'], table_name='organization')
return None
@validator('person_id', always=True)
def person_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['person_id_random']:
return redis_lookup_id_random(record_id_random=values['person_id_random'], table_name='person')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
User_Base.update_forward_refs()