diff --git a/app/main.py b/app/main.py index 473dd21..3b215a7 100644 --- a/app/main.py +++ b/app/main.py @@ -207,7 +207,7 @@ app.include_router( ) app.include_router( order.router, - prefix='/order', + # prefix='/order', tags=['Order'], ) app.include_router( diff --git a/app/methods/account_methods.py b/app/methods/account_methods.py index 49de9f8..789302b 100644 --- a/app/methods/account_methods.py +++ b/app/methods/account_methods.py @@ -401,7 +401,6 @@ def load_account_obj( inc_order_line_list = inc_order_line_list, inc_order_cfg = inc_order_cfg, inc_person = inc_person, - inc_user = inc_user, ) ) account_obj.order_list = order_dict_list diff --git a/app/methods/order_methods.py b/app/methods/order_methods.py index 2635247..dc99f88 100644 --- a/app/methods/order_methods.py +++ b/app/methods/order_methods.py @@ -13,7 +13,7 @@ from app.methods.order_line_methods import get_order_line_rec_list, load_order_l # from app.methods.user_methods import load_user_obj from app.models.order_models import Order_Base -from app.models.order_line_models import Order_Line_Base # This should go away later. +from app.models.order_line_models import Order_Line_Base, Order_Line_DB_Base # This should go away later. # from app.models.person_models import Person_Base # from app.models.user_models import User_Base @@ -153,6 +153,16 @@ def save_order_obj(order_obj_new:Order_Base, repl_order_line_li:bool=False): 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'}) + # log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + try: + order_line_obj_db = Order_Line_DB_Base(**order_line_obj_new) + log.debug(order_line_obj_db) + except ValidationError as e: + log.error(e.json()) + return False + order_line_obj_db_data = order_line_obj_db.dict(by_alias=False, exclude_defaults=False, exclude_unset=True) + log.debug(order_line_obj_db_data) + 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 diff --git a/app/methods/person_methods.py b/app/methods/person_methods.py index 7c3d221..06c66c3 100644 --- a/app/methods/person_methods.py +++ b/app/methods/person_methods.py @@ -192,7 +192,6 @@ def load_person_obj( enabled = enabled, inc_order_cfg = inc_order_cfg, inc_order_line_list = inc_order_line_list, - inc_user = inc_user, ) ) person_obj.order_list = order_result_list diff --git a/app/methods/user_methods.py b/app/methods/user_methods.py index 550726e..d745904 100644 --- a/app/methods/user_methods.py +++ b/app/methods/user_methods.py @@ -164,7 +164,6 @@ def load_user_obj( inc_order_cfg = inc_order_cfg, inc_order_line_list = inc_order_line_list, inc_person = inc_person, - # inc_user = inc_user, ): order_result_list.append(load_order_result) else: order_result_list.append(None) diff --git a/app/models/order_cart_line_models.py b/app/models/order_cart_line_models.py index 487794f..b19ce0b 100644 --- a/app/models/order_cart_line_models.py +++ b/app/models/order_cart_line_models.py @@ -28,12 +28,16 @@ class Order_Cart_Line_Base(BaseModel): product_id_random: str product_id: Optional[int] + product_for_type: Optional[str] # Copied from product record product_for_id_random: Optional[str] # Copied from product record product_for_id: Optional[int] # Copied from product record + product_type_id: Optional[int] # Copied from product record product_type: Optional[str] # Copied from product record; dup from look up? probably not use? + product_type_code: Optional[str] # Copied from product record; from look up product_type_name: Optional[str] # Copied from product record; from look up + product_name: Optional[str] # Copied from product record product_description: Optional[str] # Copied from product record product_unit_price: Optional[int] # Copied from product record @@ -41,12 +45,16 @@ class Order_Cart_Line_Base(BaseModel): curr_product_id_random: Optional[str] # Should be the same as product_id_random above curr_product_id: Optional[int] # Should be the same as product_id above + curr_product_for_type: Optional[str] # Dynamic from v_order_current_line curr_product_for_id_random: Optional[str] # Dynamic from v_order_current_line curr_product_for_id: Optional[int] # Dynamic from v_order_current_line + curr_product_type_id: Optional[int] # Dynamic from v_order_current_line curr_product_type: Optional[str] # Dynamic from v_order_current_line + curr_product_type_code: Optional[str] # Dynamic from v_order_current_line curr_product_type_name: Optional[str] # Dynamic from v_order_current_line + curr_product_name: Optional[str] # Dynamic from v_order_current_line curr_product_description: Optional[str] # Dynamic from v_order_current_line curr_product_unit_price: Optional[int] # Dynamic from v_order_current_line @@ -143,3 +151,50 @@ class Order_Cart_Line_Base(BaseModel): underscore_attrs_are_private = True allow_population_by_field_name = True fields = base_fields + + +class Order_Cart_Line_DB_Base(BaseModel): + log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + id_random: Optional[str] = Field( + alias = 'order_cart_line_id_random', + ) + id: Optional[int] = Field( + alias = 'order_cart_line_id' + ) + + order_cart_id_random: Optional[str] + order_cart_id: Optional[int] + + product_id_random: str + product_id: Optional[int] + + product_for_type: Optional[str] # Copied from product record + product_for_id_random: Optional[str] # Copied from product record + product_for_id: Optional[int] # Copied from product record + + product_type_id: Optional[int] # Copied from product record + + product_name: Optional[str] # Copied from product record + product_unit_price: Optional[int] # Copied from product record + product_recurring: Optional[bool] # Copied from product record + + for_person_id: Optional[int] + for_person_id_random: Optional[str] + + name: Optional[str] # Should be the same as product_name above + quantity: int = Field(0, ge=0, lt=150) + amount: int = Field(0, ge=0, lt=1500000) + recurring: Optional[bool] + recurring_period: Optional[int] + + message: Optional[str] + + notes: Optional[str] + + _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) + + class Config: + underscore_attrs_are_private = True + allow_population_by_field_name = True diff --git a/app/models/order_line_models.py b/app/models/order_line_models.py index 7bf03a9..08c78a9 100644 --- a/app/models/order_line_models.py +++ b/app/models/order_line_models.py @@ -35,6 +35,7 @@ class Order_Line_Base(BaseModel): product_type_id: Optional[int] # Copied from product record product_type: Optional[str] # WARNING: Copied from product record; dup from look up? probably not use? + product_type_code: Optional[str] # Copied from product record; from look up product_type_name: Optional[str] # Copied from product record; from look up product_name: Optional[str] # Copied from product record @@ -52,6 +53,7 @@ class Order_Line_Base(BaseModel): curr_product_type_id: Optional[int] # Dynamic from v_order_line curr_product_type: Optional[str] # Dynamic from v_order_line + curr_product_type_code: Optional[str] # Dynamic from v_order_line curr_product_type_name: Optional[str] # Dynamic from v_order_line curr_product_name: Optional[str] # Dynamic from v_order_line @@ -160,4 +162,51 @@ class Order_Line_Base(BaseModel): allow_population_by_field_name = True fields = base_fields + +class Order_Line_DB_Base(BaseModel): + log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + id_random: Optional[str] = Field( + alias = 'order_line_id_random', + ) + id: Optional[int] = Field( + alias = 'order_line_id' + ) + + order_id_random: Optional[str] + order_id: Optional[int] + + product_id_random: str + product_id: Optional[int] + + product_for_type: Optional[str] # Copied from product record + product_for_id_random: Optional[str] # Copied from product record NOPE + product_for_id: Optional[int] # Copied from product record + + product_type_id: Optional[int] # Copied from product record + + product_name: Optional[str] # Copied from product record + product_unit_price: Optional[int] # Copied from product record + product_recurring: Optional[bool] # Copied from product record + + for_person_id: Optional[int] + for_person_id_random: Optional[str] + + name: Optional[str] # Should be the same as product_name above + quantity: int = Field(0, ge=0, lt=150) + amount: int = Field(0, ge=0, lt=1500000) + recurring: Optional[bool] = False + recurring_period: Optional[int] + + message: Optional[str] + + notes: Optional[str] + + _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) + + class Config: + underscore_attrs_are_private = True + allow_population_by_field_name = True + Order_Line_Base.update_forward_refs() diff --git a/app/models/order_models.py b/app/models/order_models.py index 0e4adf3..dcdd08d 100644 --- a/app/models/order_models.py +++ b/app/models/order_models.py @@ -40,7 +40,19 @@ class Order_Base(BaseModel): 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] + status: Optional[str] # open, locked, reopened, closed, canceled, other + # open = building or creating cart, payment failed and no partial payment already processed + # locked = processing payment, partial payment processed, admin lock? (no changes allowed) + # closed = successful payment(s) with no balance, complete (no changes allowed) + # canceled = order canceled; something odd happened (no changes allowed) + # other = other reasons (no changes allowed) + checkout_status: Optional[str] # canceled, waiting, success, failed, unknown + # none = no checkout attempted + # canceled = checkout attempted but canceled for some reason + # waiting = the payment is processing or awaiting some type of authorization + # success = payment successful (their may still be a balance) + # failed = the payment failed for some reason + # unknown = unknown response... notes: Optional[str] @@ -51,7 +63,7 @@ class Order_Base(BaseModel): cfg: Optional[Order_Cfg_Base] order_line_list: Optional[list] # Order_Line_Base() person: Optional[Person_Base] - user: Optional[User_Base] + # user: Optional[User_Base] _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) @@ -103,3 +115,71 @@ class Order_Base(BaseModel): class Config: underscore_attrs_are_private = True fields = base_fields + + +class Order_DB_Base(BaseModel): + log.setLevel(logging.WARNING) + log.debug(locals()) + + account_id_random: Optional[str] + account_id: Optional[int] # NOTE: This is not really optional + + person_id_random: Union[str, None] = None + person_id: Union[int, None] = None + + user_id_random: Union[str, None] = None + user_id: Union[int, None] = None + + 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] = 'open' # open, locked, reopened, closed, canceled, other + # open = building or creating cart, payment failed and no partial payment already processed + # locked = processing payment, partial payment processed, admin lock? (no changes allowed) + # closed = successful payment(s) with no balance, complete (no changes allowed) + # canceled = order canceled; something odd happened (no changes allowed) + # other = other reasons (no changes allowed) + checkout_status: Union[str, None] = None # canceled, waiting, success, failed, unknown + # none = no checkout attempted + # canceled = checkout attempted but canceled for some reason + # waiting = the payment is processing or awaiting some type of authorization + # success = payment successful (their may still be a balance) + # failed = the payment failed for some reason + # unknown = unknown response... + + notes: Optional[str] + + _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) + + @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 + allow_population_by_field_name = True + fields = base_fields diff --git a/app/models/product_models.py b/app/models/product_models.py index a09d595..fdce34d 100644 --- a/app/models/product_models.py +++ b/app/models/product_models.py @@ -33,9 +33,8 @@ class Product_Base(BaseModel): for_id: Optional[int] type_id: Optional[int] - type_name: Optional[str] = Field( - # alias = 'type' - ) + type_code: Optional[str] + type_name: Optional[str] name: Optional[str] description: Optional[str] diff --git a/app/routers/lookup.py b/app/routers/lookup.py index e255b22..09b038c 100644 --- a/app/routers/lookup.py +++ b/app/routers/lookup.py @@ -27,10 +27,10 @@ async def get_lookup_li( limit: int = 1000, enabled: str = 'enabled', # enabled, disabled, all ): - log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) - allowed_lookup_tables = ['country', 'country_subdivision', 'event_session_type', 'file_purpose', 'membership_group_status', 'membership_person_status', 'membership_type_status', 'order_status', 'post_topic', 'time_zone', 'user_status'] + allowed_lookup_tables = ['country', 'country_subdivision', 'event_session_type', 'file_purpose', 'membership_group_status', 'membership_person_status', 'membership_type_status', 'order_status', 'post_topic', 'product_type', 'time_zone', 'user_status'] if for_lookup_name in allowed_lookup_tables: pass else: diff --git a/app/routers/order.py b/app/routers/order.py index 4fd5840..c0f8b3a 100644 --- a/app/routers/order.py +++ b/app/routers/order.py @@ -12,15 +12,17 @@ from app.routers.api_crud import delete_obj_template, get_obj_template, get_obj_ from app.methods.order_methods import load_order_obj, save_order_obj from app.models.response_models import * -from app.models.order_models import Order_Base +from app.models.order_models import Order_Base, Order_DB_Base router = APIRouter() -@router.post('', response_model=Resp_Body_Base) +# NOTE 2021-08-09: Use with rework of order_cart +# account_id is required, person_id is ideal +@router.post('/order', response_model=Resp_Body_Base) async def post_order_obj( - obj: Order_Base, + order_obj: Order_DB_Base, x_account_id: str = Header(...), return_obj: Optional[bool] = True, by_alias: Optional[bool] = True, @@ -30,18 +32,19 @@ async def post_order_obj( log.debug(locals()) obj_type = 'order' - obj_data_dict = obj.dict(by_alias=False, exclude_unset=True) + order_obj = order_obj.dict(by_alias=False, exclude_unset=False) result = post_obj_template( - obj_type=obj_type, - data=obj_data_dict, - return_obj=True, - by_alias=True, - exclude_unset=True, + obj_type = obj_type, + data = order_obj, + return_obj = True, + by_alias = True, + exclude_unset = True, ) return result -@router.patch('/{obj_id}', response_model=Resp_Body_Base) +# NOTE 2021-08-09: Use with rework of order_cart +@router.patch('/order/{obj_id}', response_model=Resp_Body_Base) async def patch_order_obj( obj_id: str = Query(..., min_length=1, max_length=22), obj: Order_Base = None, @@ -68,7 +71,24 @@ async def patch_order_obj( return result -@router.get('/list', response_model=Resp_Body_Base) + +# NOTE 2021-08-09: Use with rework of order_cart +# NOTE: The router needs to have the prefix (/order) removed. +@router.patch('/order/{order_id}/line/add', response_model=Resp_Body_Base) +async def patch_order_obj_line_add( + order_id: str = Query(..., min_length=1, max_length=22), + obj: Order_Base = None, + x_account_id: Optional[str] = Header(..., ), + return_obj: Optional[bool] = True, + by_alias: Optional[bool] = True, + exclude_unset: Optional[bool] = True, + ): + log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + + +@router.get('/order/list', response_model=Resp_Body_Base) async def get_order_obj_li( for_obj_type: Optional[str] = Query(None, min_length=2, max_length=50), for_obj_id: Optional[str] = Query(None, min_length=1, max_length=22), @@ -149,7 +169,7 @@ async def get_order_obj_li( order_obj_li = [] for order_obj in order_obj_li_result: order_id = order_obj.get('order_id', None) - if order_obj := load_order_obj(order_id=order_id, inc_order_line_list=inc_order_line_list, inc_order_cfg=inc_order_cfg, inc_person_obj=inc_person_obj, inc_user_obj=inc_user_obj): + if order_obj := load_order_obj(order_id=order_id, inc_order_line_list=inc_order_line_list, inc_order_cfg=inc_order_cfg, inc_person_obj=inc_person_obj): data = order_obj.dict(by_alias=by_alias, exclude_unset=exclude_unset) order_obj_li.append(data) return mk_resp(data=order_obj_li) @@ -159,14 +179,16 @@ async def get_order_obj_li( # ### BEGIN ### API Order Routes ### get_order_obj() ### +# NOTE 2021-08-09: Use with rework of order_cart # Updated 2021-08-07 -@router.get('/{order_id}', response_model=Resp_Body_Base) +@router.get('/order/{order_id}', response_model=Resp_Body_Base) async def get_order_obj( order_id: str = Query(..., min_length=11, max_length=22), limit: int = 500, enabled: str = 'enabled', inc_order_line_list: bool = False, inc_order_cfg: bool = False, + inc_person: bool = False, x_account_id: str = Header(...), by_alias: bool = True, exclude_unset: bool = True, @@ -183,6 +205,7 @@ async def get_order_obj( # model_as_dict = model_as_dict, inc_order_line_list = inc_order_line_list, inc_order_cfg = inc_order_cfg, + inc_person = inc_person, ): log.debug(order_obj) data = order_obj.dict(by_alias=by_alias, exclude_unset=False) # NOTE NOTE NOTE NOTE exclude_unset is forced to False for now. Will return more fields than is ideal. Need to create another Order_Line_Base. Probably Order_Line_OUT_Base @@ -192,7 +215,24 @@ async def get_order_obj( # ### END ### API Order Routes ### get_order_obj() ### -@router.delete('/{obj_id}', response_model=Resp_Body_Base) +# NOTE 2021-08-09: Use with rework of order_cart +@router.get('/person/{person_id}/order/open', response_model=Resp_Body_Base) +async def get_person_id_order_open_obj( + person_id: str = Query(..., min_length=11, max_length=22), + enabled: str = 'enabled', + inc_order_line_list: bool = False, + inc_order_cfg: bool = False, + x_account_id: str = Header(...), + by_alias: bool = True, + exclude_unset: bool = True, + ): + log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + return False + + +@router.delete('/order/{obj_id}', response_model=Resp_Body_Base) async def delete_order_obj( obj_id: str = Query(..., min_length=1, max_length=22), x_account_id: str = Header(...), @@ -205,4 +245,19 @@ async def delete_order_obj( obj_type=obj_type, obj_id=obj_id, ) - return result \ No newline at end of file + return result + + +# NOTE 2021-08-09: Use with rework of order_cart +# NOTE: The router needs to have the prefix (/order) removed. +@router.delete('/order/{order_id}/line//remove', response_model=Resp_Body_Base) +async def delete_order_line_obj_NOT_SURE( + order_id: str = Query(..., min_length=1, max_length=22), + obj: Order_Base = None, + x_account_id: Optional[str] = Header(..., ), + return_obj: Optional[bool] = True, + by_alias: Optional[bool] = True, + exclude_unset: Optional[bool] = True, + ): + log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals())