crappy
This commit is contained in:
@@ -75,7 +75,7 @@ class ClientService(BaseService):
|
||||
try:
|
||||
client = await self.get_by_name(request.data.name)
|
||||
if client:
|
||||
return ClientCreateResponse(ok=False, message='Client already exists')
|
||||
return ClientCreateResponse(ok=False, message='Клиент с таким именем уже существует')
|
||||
await self.create_client_raw(user, request.data.name, request.data.details)
|
||||
await self.session.commit()
|
||||
return ClientCreateResponse(ok=True, message='Client created')
|
||||
@@ -86,11 +86,11 @@ class ClientService(BaseService):
|
||||
try:
|
||||
client = await self.get_by_id(request.data.id)
|
||||
if not client:
|
||||
return ClientUpdateResponse(ok=False, message='Client not found')
|
||||
return ClientUpdateResponse(ok=False, message='Клиент не найден')
|
||||
await self.session.execute(update(Client).where(Client.id == client.id).values(name=request.data.name))
|
||||
await self.update_details(user, client, request.data.details)
|
||||
await self.session.commit()
|
||||
return ClientUpdateResponse(ok=True, message='Client updated')
|
||||
return ClientUpdateResponse(ok=True, message='Клиент обновлен')
|
||||
except Exception as e:
|
||||
return ClientUpdateResponse(ok=False, message=str(e))
|
||||
|
||||
@@ -98,9 +98,9 @@ class ClientService(BaseService):
|
||||
try:
|
||||
client = await self.get_by_id(request.client_id)
|
||||
if not client:
|
||||
return ClientDeleteResponse(ok=False, message='Client not found')
|
||||
return ClientDeleteResponse(ok=False, message='Клиент не найден')
|
||||
await self.session.delete(client)
|
||||
await self.session.commit()
|
||||
return ClientDeleteResponse(ok=True, message='Client deleted')
|
||||
return ClientDeleteResponse(ok=True, message='Клиент удален')
|
||||
except Exception as e:
|
||||
return ClientDeleteResponse(ok=False, message=str(e))
|
||||
|
||||
165
services/deal.py
165
services/deal.py
@@ -5,7 +5,7 @@ from fastapi import HTTPException
|
||||
from sqlalchemy import select, func
|
||||
from sqlalchemy.orm import joinedload, selectinload
|
||||
|
||||
from models import User, Service
|
||||
from models import User, Service, Client
|
||||
from models.deal import *
|
||||
from schemas.client import ClientDetailsSchema
|
||||
from schemas.deal import *
|
||||
@@ -15,6 +15,7 @@ from services.client import ClientService
|
||||
|
||||
class DealService(BaseService):
|
||||
|
||||
# region Deal
|
||||
async def _get_deal_by_id(self, deal_id) -> Union[Deal, None]:
|
||||
return await self.session.get(Deal, deal_id)
|
||||
|
||||
@@ -116,6 +117,56 @@ class DealService(BaseService):
|
||||
)
|
||||
return DealSummaryResponse(summaries=summaries)
|
||||
|
||||
async def get_all(self) -> DealGetAllResponse:
|
||||
deals_query = await self.session.scalars(select(Deal).options(joinedload(Deal.client)))
|
||||
deals = deals_query.all()
|
||||
result = []
|
||||
for deal in deals:
|
||||
result.append(DealSchema.model_validate(deal))
|
||||
return DealGetAllResponse(deals=result)
|
||||
|
||||
async def get_by_id(self, deal_id: int) -> DealSchema:
|
||||
deal = await self.session.scalar(
|
||||
select(Deal)
|
||||
.options(
|
||||
joinedload(Deal.client).joinedload(Client.details),
|
||||
selectinload(Deal.services)
|
||||
.joinedload(models.secondary.DealService.service)
|
||||
.joinedload(Service.category),
|
||||
selectinload(Deal.products)
|
||||
.joinedload(models.secondary.DealProduct.product)
|
||||
.joinedload(models.Product.client),
|
||||
selectinload(Deal.products)
|
||||
.joinedload(models.secondary.DealProduct.product)
|
||||
.joinedload(models.Product.barcodes),
|
||||
selectinload(Deal.status_history)
|
||||
.joinedload(DealStatusHistory.user),
|
||||
selectinload(Deal.status_history)
|
||||
.noload(DealStatusHistory.deal)
|
||||
)
|
||||
.where(Deal.id == deal_id)
|
||||
)
|
||||
if not deal:
|
||||
raise HTTPException(status_code=404, detail="Сделка не найдена")
|
||||
return DealSchema.model_validate(deal)
|
||||
|
||||
async def update_general_info(self, request: DealUpdateGeneralInfoRequest) -> DealUpdateGeneralInfoResponse:
|
||||
try:
|
||||
deal = await self.session.scalar(select(Deal).where(Deal.id == request.deal_id))
|
||||
if not deal:
|
||||
raise HTTPException(status_code=404, detail="Сделка не найдена")
|
||||
deal.name = request.data.name
|
||||
deal.is_deleted = request.data.is_deleted
|
||||
deal.is_completed = request.data.is_completed
|
||||
await self.session.commit()
|
||||
return DealUpdateGeneralInfoResponse(ok=True, message='Данные о сделке успешно обновлены')
|
||||
except Exception as e:
|
||||
await self.session.rollback()
|
||||
return DealUpdateGeneralInfoResponse(ok=False, message=str(e))
|
||||
|
||||
# endregion
|
||||
|
||||
# region Deal services
|
||||
async def add_services(self, request: DealAddServicesRequest):
|
||||
# TODO refactor
|
||||
deal: Deal = await self.session.scalar(
|
||||
@@ -149,41 +200,14 @@ class DealService(BaseService):
|
||||
quantity = request_services_dict[service.id]
|
||||
deal.services.append(
|
||||
models.secondary.DealService(
|
||||
service=service,
|
||||
deal=deal,
|
||||
service_id=service.id,
|
||||
deal_id=deal.id,
|
||||
quantity=quantity
|
||||
)
|
||||
)
|
||||
await self.session.commit()
|
||||
return DealAddServicesResponse(ok=True, message='Услуги успешно добавлены')
|
||||
|
||||
async def get_all(self) -> DealGetAllResponse:
|
||||
deals_query = await self.session.scalars(select(Deal).options(joinedload(Deal.client)))
|
||||
deals = deals_query.all()
|
||||
result = []
|
||||
for deal in deals:
|
||||
result.append(DealSchema.model_validate(deal))
|
||||
return DealGetAllResponse(deals=result)
|
||||
|
||||
async def get_by_id(self, deal_id: int) -> DealSchema:
|
||||
deal = await self.session.scalar(
|
||||
select(Deal)
|
||||
.options(
|
||||
joinedload(Deal.client),
|
||||
selectinload(Deal.services)
|
||||
.joinedload(models.secondary.DealService.service)
|
||||
.joinedload(Service.category),
|
||||
selectinload(Deal.products)
|
||||
.joinedload(models.secondary.DealProduct.product)
|
||||
.joinedload(models.Product.client)
|
||||
.selectinload(models.Product.barcodes)
|
||||
)
|
||||
.where(Deal.id == deal_id)
|
||||
)
|
||||
if not deal:
|
||||
raise HTTPException(status_code=404, detail="Сделка не найдена")
|
||||
return DealSchema.model_validate(deal)
|
||||
|
||||
async def update_service_quantity(self,
|
||||
request: DealUpdateServiceQuantityRequest) -> DealUpdateServiceQuantityResponse:
|
||||
try:
|
||||
@@ -259,3 +283,84 @@ class DealService(BaseService):
|
||||
except Exception as e:
|
||||
await self.session.rollback()
|
||||
return DealDeleteServicesResponse(ok=False, message=str(e))
|
||||
|
||||
# endregion
|
||||
|
||||
# region Deal products
|
||||
async def update_product_quantity(self,
|
||||
request: DealUpdateProductQuantityRequest) -> DealUpdateProductQuantityResponse:
|
||||
try:
|
||||
# check if there is no deal or no product with different exceptions
|
||||
deal_product = await self.session.scalar(
|
||||
select(models.secondary.DealProduct)
|
||||
.where(models.secondary.DealProduct.deal_id == request.deal_id,
|
||||
models.secondary.DealProduct.product_id == request.product_id)
|
||||
)
|
||||
if not deal_product:
|
||||
raise HTTPException(status_code=404, detail="Сделка или товар не найдена")
|
||||
deal_product.quantity = request.quantity
|
||||
await self.session.commit()
|
||||
return DealUpdateProductQuantityResponse(ok=True, message='Количество успешно обновлено')
|
||||
except Exception as e:
|
||||
await self.session.rollback()
|
||||
return DealUpdateProductQuantityResponse(ok=False, message=str(e))
|
||||
|
||||
async def add_product(self, request: DealAddProductRequest) -> DealAddProductResponse:
|
||||
try:
|
||||
deal = await self.session.scalar(select(Deal).where(Deal.id == request.deal_id))
|
||||
if not deal:
|
||||
raise HTTPException(status_code=404, detail="Сделка не найдена")
|
||||
product = await self.session.scalar(select(models.Product).where(models.Product.id == request.product_id))
|
||||
if not product:
|
||||
raise HTTPException(status_code=404, detail="Товар не найден")
|
||||
# Preventing duplicates
|
||||
deal_product = await self.session.scalar(
|
||||
select(models.secondary.DealProduct)
|
||||
.where(models.secondary.DealProduct.deal_id == request.deal_id,
|
||||
models.secondary.DealProduct.product_id == request.product_id)
|
||||
)
|
||||
if deal_product:
|
||||
raise HTTPException(status_code=400, detail="Товар уже добавлен")
|
||||
deal_product = models.secondary.DealProduct(
|
||||
deal_id=request.deal_id,
|
||||
product_id=request.product_id,
|
||||
quantity=request.quantity
|
||||
)
|
||||
self.session.add(deal_product)
|
||||
await self.session.commit()
|
||||
return DealAddProductResponse(ok=True, message='Товар успешно добавлен')
|
||||
except Exception as e:
|
||||
await self.session.rollback()
|
||||
return DealAddProductResponse(ok=False, message=str(e))
|
||||
|
||||
async def delete_product(self, request: DealDeleteProductRequest) -> DealDeleteProductResponse:
|
||||
try:
|
||||
deal_product = await self.session.scalar(
|
||||
select(models.secondary.DealProduct)
|
||||
.where(models.secondary.DealProduct.deal_id == request.deal_id,
|
||||
models.secondary.DealProduct.product_id == request.product_id)
|
||||
)
|
||||
if not deal_product:
|
||||
raise HTTPException(status_code=404, detail="Сделка не найдена")
|
||||
await self.session.delete(deal_product)
|
||||
await self.session.commit()
|
||||
return DealDeleteProductResponse(ok=True, message='Товар успешно удален')
|
||||
except Exception as e:
|
||||
await self.session.rollback()
|
||||
return DealDeleteProductResponse(ok=False, message=str(e))
|
||||
|
||||
async def delete_products(self, request: DealDeleteProductsRequest) -> DealDeleteProductsResponse:
|
||||
try:
|
||||
deal_products = await self.session.scalars(
|
||||
select(models.secondary.DealProduct)
|
||||
.where(models.secondary.DealProduct.deal_id == request.deal_id,
|
||||
models.secondary.DealProduct.product_id.in_(request.product_ids))
|
||||
)
|
||||
for deal_product in deal_products:
|
||||
await self.session.delete(deal_product)
|
||||
await self.session.commit()
|
||||
return DealDeleteProductsResponse(ok=True, message='Товары успешно удалены')
|
||||
except Exception as e:
|
||||
await self.session.rollback()
|
||||
return DealDeleteProductsResponse(ok=False, message=str(e))
|
||||
# endregion
|
||||
|
||||
@@ -2,6 +2,7 @@ from fastapi import HTTPException
|
||||
from sqlalchemy import select, func, Integer, update
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
import utils.barcodes
|
||||
from models.product import Product, ProductBarcode
|
||||
from schemas.base import PaginationSchema
|
||||
from services.base import BaseService
|
||||
@@ -85,6 +86,9 @@ class ProductService(BaseService):
|
||||
return ProductUpdateResponse(ok=True, message='Товар успешно обновлен')
|
||||
|
||||
async def get_by_client_id(self, client_id: int, pagination: PaginationSchema) -> ProductGetResponse:
|
||||
is_pagination_valid = is_valid_pagination(pagination)
|
||||
total_pages = 0
|
||||
total_items = 0
|
||||
stmt = (
|
||||
select(Product)
|
||||
.options(selectinload(Product.barcodes)
|
||||
@@ -92,7 +96,7 @@ class ProductService(BaseService):
|
||||
.where(Product.client_id == client_id)
|
||||
.order_by(Product.id)
|
||||
)
|
||||
if is_valid_pagination(pagination):
|
||||
if is_pagination_valid:
|
||||
total_products_query = await self.session.execute(
|
||||
select(
|
||||
func.cast(func.ceil(func.count() / pagination.items_per_page), Integer),
|
||||
@@ -101,36 +105,101 @@ class ProductService(BaseService):
|
||||
.select_from(stmt.subquery())
|
||||
)
|
||||
total_pages, total_items = total_products_query.first()
|
||||
else:
|
||||
total_items_query = await self.session.execute(
|
||||
select(func.count())
|
||||
.select_from(stmt.subquery())
|
||||
)
|
||||
total_items = total_items_query.scalar()
|
||||
total_pages = 1
|
||||
pagination_info = PaginationInfoSchema(total_pages=total_pages, total_items=total_items)
|
||||
|
||||
if is_valid_pagination(pagination):
|
||||
stmt = (
|
||||
stmt
|
||||
.offset(pagination.page * pagination.items_per_page)
|
||||
.limit(pagination.items_per_page)
|
||||
)
|
||||
|
||||
query = await self.session.execute(
|
||||
stmt
|
||||
.order_by(Product.id)
|
||||
)
|
||||
product_orm = query.scalars().all()
|
||||
if not is_pagination_valid:
|
||||
total_pages = 1
|
||||
total_items = len(product_orm)
|
||||
pagination_info = PaginationInfoSchema(total_pages=total_pages, total_items=total_items)
|
||||
|
||||
products: list[ProductSchema] = []
|
||||
for product in query.scalars().all():
|
||||
product: Product
|
||||
|
||||
barcodes = []
|
||||
for barcode_obj in product.barcodes:
|
||||
barcode_obj: ProductBarcode
|
||||
barcodes.append(barcode_obj.barcode)
|
||||
|
||||
products.append(
|
||||
ProductSchema.from_sql_model(product, {'barcodes': barcodes})
|
||||
)
|
||||
for product in product_orm:
|
||||
products.append(ProductSchema.model_validate(product))
|
||||
return ProductGetResponse(products=products, pagination_info=pagination_info)
|
||||
|
||||
async def get_by_id(self, product_id: int) -> ProductSchema:
|
||||
stmt = (
|
||||
select(Product)
|
||||
.options(selectinload(Product.barcodes)
|
||||
.noload(ProductBarcode.product))
|
||||
.where(Product.id == product_id)
|
||||
)
|
||||
query = await self.session.execute(stmt)
|
||||
product = query.scalar()
|
||||
if not product:
|
||||
raise HTTPException(status_code=404, detail='Товар не найден')
|
||||
return ProductSchema.model_validate(product)
|
||||
|
||||
# region Barcodes
|
||||
async def add_barcode(self, request: ProductAddBarcodeRequest):
|
||||
try:
|
||||
product = await self.session.get(Product, request.product_id)
|
||||
if not product:
|
||||
raise HTTPException(status_code=404, detail='Товар не найден')
|
||||
existing_barcode_query = await self.session.execute(
|
||||
select(ProductBarcode)
|
||||
.where(ProductBarcode.product_id == request.product_id,
|
||||
ProductBarcode.barcode == request.barcode)
|
||||
)
|
||||
existing_barcode = existing_barcode_query.first()
|
||||
if existing_barcode:
|
||||
return ProductAddBarcodeResponse(ok=False, message='Штрих-код уже существует у товара')
|
||||
product_barcode = ProductBarcode(product_id=product.id,
|
||||
barcode=request.barcode)
|
||||
self.session.add(product_barcode)
|
||||
await self.session.commit()
|
||||
return ProductAddBarcodeResponse(ok=True, message='Штрих-код успешно добавлен')
|
||||
except Exception as e:
|
||||
await self.session.rollback()
|
||||
return ProductAddBarcodeResponse(ok=False, message=str(e))
|
||||
|
||||
async def delete_barcode(self, request: ProductDeleteBarcodeRequest):
|
||||
try:
|
||||
product_barcode = await self.session.get(ProductBarcode, (request.product_id, request.barcode))
|
||||
if not product_barcode:
|
||||
return ProductDeleteBarcodeResponse(ok=False, message='Штрих-код не найден')
|
||||
await self.session.delete(product_barcode)
|
||||
await self.session.commit()
|
||||
return ProductDeleteBarcodeResponse(ok=True, message='Штрих-код успешно удален')
|
||||
except Exception as e:
|
||||
await self.session.rollback()
|
||||
return ProductDeleteBarcodeResponse(ok=False, message=str(e))
|
||||
|
||||
async def exists_barcode(self, product_id: int, barcode: str) -> ProductExistsBarcodeResponse:
|
||||
product_barcode_query = await self.session.execute(
|
||||
select(ProductBarcode)
|
||||
.where(ProductBarcode.product_id == product_id,
|
||||
ProductBarcode.barcode == barcode)
|
||||
)
|
||||
product_barcode = product_barcode_query.first()
|
||||
return ProductExistsBarcodeResponse(exists=bool(product_barcode))
|
||||
|
||||
async def generate_barcode(self, request: ProductGenerateBarcodeRequest) -> ProductGenerateBarcodeResponse:
|
||||
try:
|
||||
product = await self.session.get(Product, request.product_id)
|
||||
if not product:
|
||||
raise HTTPException(status_code=404, detail='Товар не найден')
|
||||
barcode = utils.barcodes.generate_barcode(product.id)
|
||||
barcode_exists_query = await self.session.execute(
|
||||
select(ProductBarcode)
|
||||
.where(ProductBarcode.barcode == barcode)
|
||||
)
|
||||
barcode_exists = barcode_exists_query.first()
|
||||
if barcode_exists:
|
||||
raise Exception('Штрих-код уже существует')
|
||||
product_barcode = ProductBarcode(product_id=product.id,
|
||||
barcode=barcode)
|
||||
self.session.add(product_barcode)
|
||||
await self.session.commit()
|
||||
return ProductGenerateBarcodeResponse(ok=True, message='Штрих-код успешно сгенерирован', barcode=barcode)
|
||||
except Exception as e:
|
||||
return ProductGenerateBarcodeResponse(ok=False, message=str(e))
|
||||
# endregion
|
||||
|
||||
Reference in New Issue
Block a user