diff --git a/src/api/presentation/shared/dtos/order_response_dto.py b/src/api/presentation/shared/dtos/order_response_dto.py index 856aea57..cf418be0 100644 --- a/src/api/presentation/shared/dtos/order_response_dto.py +++ b/src/api/presentation/shared/dtos/order_response_dto.py @@ -11,7 +11,7 @@ class OrderProductResponseDto(BaseModel): class OrderResponseDto(BaseModel): id: str - user: int + user: str total_order: float order_status: str payment_condition: str diff --git a/src/cart/adapters/postgres_gateway.py b/src/cart/adapters/postgres_gateway.py index 7a71830a..7e254af9 100644 --- a/src/cart/adapters/postgres_gateway.py +++ b/src/cart/adapters/postgres_gateway.py @@ -1,7 +1,8 @@ from typing import List +from cart.domain.entities.order_product import OrderProduct +from product.domain.entities.product import Product from src.cart.domain.entities.order import Order -from src.cart.domain.entities.order_product import OrderProduct from src.cart.domain.enums.paymentConditions import PaymentConditions from src.cart.ports.cart_gateway import ICartGateway from src.cart.ports.unit_of_work_interface import ICartUnitOfWork @@ -32,7 +33,7 @@ def create_update_order(self, order: Order) -> Order: 'status': order.order_status.value, 'payment_condition': condition.name, 'products': [{'id': p.id, - 'product_id': p.product.sku, # sku + 'product_id': p.product.sku, # sku 'quantity': p.quantity, 'observation': p.observation} for p in order.products] }) @@ -44,21 +45,28 @@ def delete_order(self, order_id: str) -> None: self.uow.repository.delete(order_id) self.uow.commit() - def build_order_entity(self, order): + @staticmethod + def build_order_entity(order): if not order: return None - products = [self.build_order_product_entity(p) for p in order['products']] - + payment_condition = PaymentConditions[order['payment_condition']] + products = [] + for p in order['products']: + products.append( + OrderProduct( + product=Product(_id=p['id'], + sku=p['sku'], + description=p['description'], + category=p['category'], + stock=p['stock'], + price=p['price']), + quantity=p['quantity'], + observation=p['observation'] + ) + ) return Order(_id=order['id'], user=order['user_id'], - order_datetime=order['order_datetime'], - order_status=order['order_status'], - payment_condition=order['payment_condition'], + order_datetime=order['created_at'], + order_status=order['status'], + payment_condition=payment_condition.value, products=products) - - @staticmethod - def build_order_product_entity(product): - return OrderProduct(_id=product['id'], - product=product['product'], # sku - quantity=product['quantity'], - observation=product.get('observation', '')) diff --git a/src/cart/adapters/postgresql_repository.py b/src/cart/adapters/postgresql_repository.py index 9712b1e1..e4eeb095 100644 --- a/src/cart/adapters/postgresql_repository.py +++ b/src/cart/adapters/postgresql_repository.py @@ -1,9 +1,11 @@ -from typing import Dict, List, Sequence, Any +from typing import Dict, List, Any -from sqlalchemy import select, Row, delete +from sqlalchemy import select, delete from sqlalchemy.dialects.postgresql import insert from sqlalchemy.orm import Session +from cart.domain.entities.order_product import OrderProduct +from product.adapters.product_table import ProductTable from src.cart.adapters.order_table import OrderTable, OrderProductTable from src.cart.ports.repository_interface import IRepository @@ -14,20 +16,116 @@ def __init__(self, session: Session): self.session = session def get_all(self) -> List[Dict]: - stmt = select(OrderTable).order_by(OrderTable.status, OrderTable.created_at) - results: Sequence[Row[tuple[OrderTable]]] = self.session.execute(stmt).all() + + stmt = ( + select( + OrderTable.id, + OrderTable.user_id, + OrderTable.status, + OrderTable.payment_condition, + OrderTable.created_at, + OrderTable.updated_at, + OrderProductTable.quantity, + OrderProductTable.observation, + ProductTable.sku, + ProductTable.description, + ProductTable.price, + ProductTable.category, + ProductTable.stock, + ProductTable.id + ) + .join(OrderProductTable, OrderTable.id == OrderProductTable.order_id) + .join(ProductTable, ProductTable.sku == OrderProductTable.product_id) + .order_by(OrderTable.status, OrderTable.created_at) + ) + + results = self.session.execute(stmt).all() + if not results: return [] - return [row.to_dict() for row in results] + # Processing the results into a more readable format + response = [] + for row in results: + order_data = { + 'id': row[0], + 'user_id': row[1], + 'status': row[2], + 'payment_condition': row[3], + 'created_at': row[4], + 'updated_at': row[5], + 'products': [] + } + + product_data = { + 'sku': row[8], + 'description': row[9], + 'price': row[10], + 'quantity': row[6], + 'observation': row[7], + 'category': row[11], + 'stock': row[12], + 'id': row[13] + } + order_data['products'].append(product_data) + response.append(order_data) + + return response def filter_by_id(self, order_id: str) -> Dict: - stmt = select(OrderTable).where(OrderTable.id == order_id) - results: Sequence[Row[tuple[OrderTable]]] = self.session.execute(stmt).first() + + stmt = ( + select( + OrderTable.id, + OrderTable.user_id, + OrderTable.status, + OrderTable.payment_condition, + OrderTable.created_at, + OrderTable.updated_at, + OrderProductTable.quantity, + OrderProductTable.observation, + ProductTable.sku, + ProductTable.description, + ProductTable.price, + ProductTable.category, + ProductTable.stock, + ProductTable.id + ) + .join(OrderProductTable, OrderTable.id == OrderProductTable.order_id) + .join(ProductTable, ProductTable.sku == OrderProductTable.product_id) + .where(OrderTable.id == order_id) + ) + + results = self.session.execute(stmt).all() + if not results: return {} - return results[0].to_dict() + # Processing the single result + order_data = { + 'id': results[0][0], + 'user_id': results[0][1], + 'status': results[0][2], + 'payment_condition': results[0][3], + 'created_at': results[0][4], + 'updated_at': results[0][5], + 'products': [] + } + + for row in results: + product_data = { + 'sku': row[8], + 'description': row[9], + 'price': row[10], + 'quantity': row[6], + 'observation': row[7], + 'category': row[11], + 'stock': row[12], + 'id': row[13] + } + order_data['products'].append(product_data) + + return order_data def insert_update(self, values: Dict[str, Any]): stmt_order = insert(OrderTable).values({key: values[key] for key in values if key != 'products'}) diff --git a/src/cart/adapters/pydantic_presenter.py b/src/cart/adapters/pydantic_presenter.py index 2c834865..053a127e 100644 --- a/src/cart/adapters/pydantic_presenter.py +++ b/src/cart/adapters/pydantic_presenter.py @@ -1,5 +1,6 @@ from typing import List +from cart.domain.enums.order_status import OrderStatus from src.api.presentation.shared.dtos.order_response_dto import OrderResponseDto, OrderProductResponseDto from src.cart.domain.entities.order import Order from src.cart.ports.cart_presenter import ICartPresenter @@ -16,10 +17,11 @@ def present(self, output: Order | List[Order]) -> OrderResponseDto | List[OrderR def formater(order): if not order: return {} + return OrderResponseDto(id=order.id, user=order.user, total_order=order.total_order, - order_status=order.order_status.name, + order_status=OrderStatus(order.order_status), payment_condition=order.payment_condition, products=[OrderProductResponseDto( product=p.product.id, diff --git a/src/cart/domain/validators/order_product_validator.py b/src/cart/domain/validators/order_product_validator.py index b6719527..d520f2c9 100644 --- a/src/cart/domain/validators/order_product_validator.py +++ b/src/cart/domain/validators/order_product_validator.py @@ -1,5 +1,4 @@ from src.cart.domain.domain_exception import OrderProductDomainException -from src.product.domain.entities.product import Product TEXT_MAX_SIZE = 100 @@ -10,9 +9,6 @@ def validate(order_product): if order_product.quantity <= 0: raise OrderProductDomainException("Quantidade do produto precisa ser maior que zero") - if not isinstance(order_product.product, Product): - raise OrderProductDomainException("Produto precisa ser do tipo `Product`") - if order_product.product.price <= 0: raise OrderProductDomainException("Preço do produto precisa ser maior que zero")