Improve the frontend 2
This commit is contained in:
@@ -16,6 +16,7 @@ from app.schemas.suppliers import (
|
||||
PurchaseOrderSearchParams
|
||||
)
|
||||
from app.models.suppliers import PurchaseOrderStatus
|
||||
from app.models import AuditLog
|
||||
from shared.auth.decorators import get_current_user_dep
|
||||
from shared.routing import RouteBuilder
|
||||
from shared.auth.access_control import require_user_role
|
||||
@@ -27,7 +28,7 @@ route_builder = RouteBuilder('suppliers')
|
||||
|
||||
router = APIRouter(tags=["purchase-orders"])
|
||||
logger = structlog.get_logger()
|
||||
audit_logger = create_audit_logger("suppliers-service")
|
||||
audit_logger = create_audit_logger("suppliers-service", AuditLog)
|
||||
|
||||
|
||||
@router.post(route_builder.build_base_route("purchase-orders"), response_model=PurchaseOrderResponse)
|
||||
|
||||
@@ -22,6 +22,7 @@ from app.schemas.suppliers import (
|
||||
PurchaseOrderStatusUpdate, PurchaseOrderApproval, PurchaseOrderResponse, PurchaseOrderSummary
|
||||
)
|
||||
from app.models.suppliers import SupplierType
|
||||
from app.models import AuditLog
|
||||
from shared.auth.decorators import get_current_user_dep
|
||||
from shared.routing import RouteBuilder
|
||||
from shared.auth.access_control import require_user_role
|
||||
@@ -33,7 +34,7 @@ route_builder = RouteBuilder('suppliers')
|
||||
|
||||
router = APIRouter(tags=["supplier-operations"])
|
||||
logger = structlog.get_logger()
|
||||
audit_logger = create_audit_logger("suppliers-service")
|
||||
audit_logger = create_audit_logger("suppliers-service", AuditLog)
|
||||
|
||||
|
||||
# ===== Supplier Operations =====
|
||||
|
||||
@@ -13,9 +13,11 @@ from sqlalchemy import select
|
||||
from app.core.database import get_db
|
||||
from app.services.supplier_service import SupplierService
|
||||
from app.models.suppliers import SupplierPriceList
|
||||
from app.models import AuditLog
|
||||
from app.schemas.suppliers import (
|
||||
SupplierCreate, SupplierUpdate, SupplierResponse, SupplierSummary,
|
||||
SupplierSearchParams, SupplierDeletionSummary
|
||||
SupplierSearchParams, SupplierDeletionSummary,
|
||||
SupplierPriceListCreate, SupplierPriceListUpdate, SupplierPriceListResponse
|
||||
)
|
||||
from shared.auth.decorators import get_current_user_dep
|
||||
from shared.routing import RouteBuilder
|
||||
@@ -28,7 +30,7 @@ route_builder = RouteBuilder('suppliers')
|
||||
|
||||
router = APIRouter(tags=["suppliers"])
|
||||
logger = structlog.get_logger()
|
||||
audit_logger = create_audit_logger("suppliers-service")
|
||||
audit_logger = create_audit_logger("suppliers-service", AuditLog)
|
||||
|
||||
@router.post(route_builder.build_base_route(""), response_model=SupplierResponse)
|
||||
@require_user_role(['admin', 'owner', 'member'])
|
||||
@@ -359,4 +361,252 @@ async def get_supplier_products(
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="Failed to retrieve supplier products"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
route_builder.build_resource_action_route("", "supplier_id", "price-lists"),
|
||||
response_model=List[SupplierPriceListResponse]
|
||||
)
|
||||
async def get_supplier_price_lists(
|
||||
supplier_id: UUID = Path(..., description="Supplier ID"),
|
||||
tenant_id: str = Path(..., description="Tenant ID"),
|
||||
is_active: bool = Query(True, description="Filter by active price lists"),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Get all price list items for a supplier"""
|
||||
try:
|
||||
service = SupplierService(db)
|
||||
price_lists = await service.get_supplier_price_lists(
|
||||
supplier_id=supplier_id,
|
||||
tenant_id=UUID(tenant_id),
|
||||
is_active=is_active
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"Retrieved supplier price lists",
|
||||
supplier_id=str(supplier_id),
|
||||
count=len(price_lists)
|
||||
)
|
||||
|
||||
return [SupplierPriceListResponse.from_orm(pl) for pl in price_lists]
|
||||
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Error getting supplier price lists",
|
||||
supplier_id=str(supplier_id),
|
||||
error=str(e)
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="Failed to retrieve supplier price lists"
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
route_builder.build_resource_action_route("", "supplier_id", "price-lists/{price_list_id}"),
|
||||
response_model=SupplierPriceListResponse
|
||||
)
|
||||
async def get_supplier_price_list(
|
||||
supplier_id: UUID = Path(..., description="Supplier ID"),
|
||||
price_list_id: UUID = Path(..., description="Price List ID"),
|
||||
tenant_id: str = Path(..., description="Tenant ID"),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Get specific price list item for a supplier"""
|
||||
try:
|
||||
service = SupplierService(db)
|
||||
price_list = await service.get_supplier_price_list(
|
||||
price_list_id=price_list_id,
|
||||
tenant_id=UUID(tenant_id)
|
||||
)
|
||||
|
||||
if not price_list:
|
||||
raise HTTPException(status_code=404, detail="Price list item not found")
|
||||
|
||||
logger.info(
|
||||
"Retrieved supplier price list item",
|
||||
supplier_id=str(supplier_id),
|
||||
price_list_id=str(price_list_id)
|
||||
)
|
||||
|
||||
return SupplierPriceListResponse.from_orm(price_list)
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Error getting supplier price list item",
|
||||
supplier_id=str(supplier_id),
|
||||
price_list_id=str(price_list_id),
|
||||
error=str(e)
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="Failed to retrieve supplier price list item"
|
||||
)
|
||||
|
||||
|
||||
@router.post(
|
||||
route_builder.build_resource_action_route("", "supplier_id", "price-lists"),
|
||||
response_model=SupplierPriceListResponse
|
||||
)
|
||||
@require_user_role(['admin', 'owner', 'member'])
|
||||
async def create_supplier_price_list(
|
||||
supplier_id: UUID = Path(..., description="Supplier ID"),
|
||||
price_list_data: SupplierPriceListCreate = None,
|
||||
tenant_id: str = Path(..., description="Tenant ID"),
|
||||
current_user: Dict[str, Any] = Depends(get_current_user_dep),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Create a new price list item for a supplier"""
|
||||
try:
|
||||
service = SupplierService(db)
|
||||
|
||||
# Verify supplier exists
|
||||
supplier = await service.get_supplier(supplier_id)
|
||||
if not supplier:
|
||||
raise HTTPException(status_code=404, detail="Supplier not found")
|
||||
|
||||
price_list = await service.create_supplier_price_list(
|
||||
supplier_id=supplier_id,
|
||||
price_list_data=price_list_data,
|
||||
tenant_id=UUID(tenant_id),
|
||||
created_by=UUID(current_user["user_id"])
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"Created supplier price list item",
|
||||
supplier_id=str(supplier_id),
|
||||
price_list_id=str(price_list.id)
|
||||
)
|
||||
|
||||
return SupplierPriceListResponse.from_orm(price_list)
|
||||
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Error creating supplier price list item",
|
||||
supplier_id=str(supplier_id),
|
||||
error=str(e)
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="Failed to create supplier price list item"
|
||||
)
|
||||
|
||||
|
||||
@router.put(
|
||||
route_builder.build_resource_action_route("", "supplier_id", "price-lists/{price_list_id}"),
|
||||
response_model=SupplierPriceListResponse
|
||||
)
|
||||
@require_user_role(['admin', 'owner', 'member'])
|
||||
async def update_supplier_price_list(
|
||||
supplier_id: UUID = Path(..., description="Supplier ID"),
|
||||
price_list_id: UUID = Path(..., description="Price List ID"),
|
||||
price_list_data: SupplierPriceListUpdate = None,
|
||||
tenant_id: str = Path(..., description="Tenant ID"),
|
||||
current_user: Dict[str, Any] = Depends(get_current_user_dep),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Update a price list item for a supplier"""
|
||||
try:
|
||||
service = SupplierService(db)
|
||||
|
||||
# Verify supplier and price list exist
|
||||
supplier = await service.get_supplier(supplier_id)
|
||||
if not supplier:
|
||||
raise HTTPException(status_code=404, detail="Supplier not found")
|
||||
|
||||
price_list = await service.get_supplier_price_list(
|
||||
price_list_id=price_list_id,
|
||||
tenant_id=UUID(tenant_id)
|
||||
)
|
||||
if not price_list:
|
||||
raise HTTPException(status_code=404, detail="Price list item not found")
|
||||
|
||||
updated_price_list = await service.update_supplier_price_list(
|
||||
price_list_id=price_list_id,
|
||||
price_list_data=price_list_data,
|
||||
tenant_id=UUID(tenant_id),
|
||||
updated_by=UUID(current_user["user_id"])
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"Updated supplier price list item",
|
||||
supplier_id=str(supplier_id),
|
||||
price_list_id=str(price_list_id)
|
||||
)
|
||||
|
||||
return SupplierPriceListResponse.from_orm(updated_price_list)
|
||||
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Error updating supplier price list item",
|
||||
supplier_id=str(supplier_id),
|
||||
price_list_id=str(price_list_id),
|
||||
error=str(e)
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="Failed to update supplier price list item"
|
||||
)
|
||||
|
||||
|
||||
@router.delete(
|
||||
route_builder.build_resource_action_route("", "supplier_id", "price-lists/{price_list_id}")
|
||||
)
|
||||
@require_user_role(['admin', 'owner'])
|
||||
async def delete_supplier_price_list(
|
||||
supplier_id: UUID = Path(..., description="Supplier ID"),
|
||||
price_list_id: UUID = Path(..., description="Price List ID"),
|
||||
tenant_id: str = Path(..., description="Tenant ID"),
|
||||
current_user: Dict[str, Any] = Depends(get_current_user_dep),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Delete a price list item for a supplier"""
|
||||
try:
|
||||
service = SupplierService(db)
|
||||
|
||||
# Verify supplier and price list exist
|
||||
supplier = await service.get_supplier(supplier_id)
|
||||
if not supplier:
|
||||
raise HTTPException(status_code=404, detail="Supplier not found")
|
||||
|
||||
price_list = await service.get_supplier_price_list(
|
||||
price_list_id=price_list_id,
|
||||
tenant_id=UUID(tenant_id)
|
||||
)
|
||||
if not price_list:
|
||||
raise HTTPException(status_code=404, detail="Price list item not found")
|
||||
|
||||
success = await service.delete_supplier_price_list(
|
||||
price_list_id=price_list_id,
|
||||
tenant_id=UUID(tenant_id)
|
||||
)
|
||||
|
||||
if not success:
|
||||
raise HTTPException(status_code=404, detail="Price list item not found")
|
||||
|
||||
logger.info(
|
||||
"Deleted supplier price list item",
|
||||
supplier_id=str(supplier_id),
|
||||
price_list_id=str(price_list_id)
|
||||
)
|
||||
|
||||
return {"message": "Price list item deleted successfully"}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Error deleting supplier price list item",
|
||||
supplier_id=str(supplier_id),
|
||||
price_list_id=str(price_list_id),
|
||||
error=str(e)
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="Failed to delete supplier price list item"
|
||||
)
|
||||
|
||||
@@ -348,3 +348,93 @@ class SupplierRepository(BaseRepository[Supplier]):
|
||||
"deleted_scorecards": scorecards_count,
|
||||
"deletion_timestamp": datetime.utcnow()
|
||||
}
|
||||
|
||||
async def get_supplier_price_lists(
|
||||
self,
|
||||
supplier_id: UUID,
|
||||
tenant_id: UUID,
|
||||
is_active: bool = True
|
||||
) -> List[Any]:
|
||||
"""Get all price list items for a supplier"""
|
||||
from app.models.suppliers import SupplierPriceList
|
||||
|
||||
stmt = select(SupplierPriceList).filter(
|
||||
and_(
|
||||
SupplierPriceList.supplier_id == supplier_id,
|
||||
SupplierPriceList.tenant_id == tenant_id
|
||||
)
|
||||
)
|
||||
|
||||
if is_active:
|
||||
stmt = stmt.filter(SupplierPriceList.is_active == True)
|
||||
|
||||
result = await self.db.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
async def get_supplier_price_list(
|
||||
self,
|
||||
price_list_id: UUID,
|
||||
tenant_id: UUID
|
||||
) -> Optional[Any]:
|
||||
"""Get specific price list item"""
|
||||
from app.models.suppliers import SupplierPriceList
|
||||
|
||||
stmt = select(SupplierPriceList).filter(
|
||||
and_(
|
||||
SupplierPriceList.id == price_list_id,
|
||||
SupplierPriceList.tenant_id == tenant_id
|
||||
)
|
||||
)
|
||||
result = await self.db.execute(stmt)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
async def create_supplier_price_list(
|
||||
self,
|
||||
create_data: Dict[str, Any]
|
||||
) -> Any:
|
||||
"""Create a new price list item"""
|
||||
from app.models.suppliers import SupplierPriceList
|
||||
|
||||
price_list = SupplierPriceList(**create_data)
|
||||
self.db.add(price_list)
|
||||
await self.db.commit()
|
||||
await self.db.refresh(price_list)
|
||||
return price_list
|
||||
|
||||
async def update_supplier_price_list(
|
||||
self,
|
||||
price_list_id: UUID,
|
||||
update_data: Dict[str, Any]
|
||||
) -> Any:
|
||||
"""Update a price list item"""
|
||||
from app.models.suppliers import SupplierPriceList
|
||||
|
||||
stmt = select(SupplierPriceList).filter(SupplierPriceList.id == price_list_id)
|
||||
result = await self.db.execute(stmt)
|
||||
price_list = result.scalar_one_or_none()
|
||||
|
||||
if not price_list:
|
||||
raise ValueError("Price list item not found")
|
||||
|
||||
# Update fields
|
||||
for key, value in update_data.items():
|
||||
if hasattr(price_list, key):
|
||||
setattr(price_list, key, value)
|
||||
|
||||
await self.db.commit()
|
||||
await self.db.refresh(price_list)
|
||||
return price_list
|
||||
|
||||
async def delete_supplier_price_list(
|
||||
self,
|
||||
price_list_id: UUID
|
||||
) -> bool:
|
||||
"""Delete a price list item"""
|
||||
from app.models.suppliers import SupplierPriceList
|
||||
from sqlalchemy import delete
|
||||
|
||||
stmt = delete(SupplierPriceList).filter(SupplierPriceList.id == price_list_id)
|
||||
result = await self.db.execute(stmt)
|
||||
|
||||
await self.db.commit()
|
||||
return result.rowcount > 0
|
||||
|
||||
@@ -600,6 +600,80 @@ class DeliverySearchParams(BaseModel):
|
||||
offset: int = Field(default=0, ge=0)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# SUPPLIER PRICE LIST SCHEMAS
|
||||
# ============================================================================
|
||||
|
||||
class SupplierPriceListCreate(BaseModel):
|
||||
"""Schema for creating supplier price list items"""
|
||||
inventory_product_id: UUID
|
||||
product_code: Optional[str] = Field(None, max_length=100)
|
||||
unit_price: Decimal = Field(..., gt=0)
|
||||
unit_of_measure: str = Field(..., max_length=20)
|
||||
minimum_order_quantity: Optional[int] = Field(None, ge=1)
|
||||
price_per_unit: Decimal = Field(..., gt=0)
|
||||
tier_pricing: Optional[Dict[str, Any]] = None # [{quantity: 100, price: 2.50}, ...]
|
||||
effective_date: Optional[datetime] = Field(default_factory=lambda: datetime.now())
|
||||
expiry_date: Optional[datetime] = None
|
||||
is_active: bool = True
|
||||
brand: Optional[str] = Field(None, max_length=100)
|
||||
packaging_size: Optional[str] = Field(None, max_length=50)
|
||||
origin_country: Optional[str] = Field(None, max_length=100)
|
||||
shelf_life_days: Optional[int] = None
|
||||
storage_requirements: Optional[str] = None
|
||||
quality_specs: Optional[Dict[str, Any]] = None
|
||||
allergens: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
class SupplierPriceListUpdate(BaseModel):
|
||||
"""Schema for updating supplier price list items"""
|
||||
unit_price: Optional[Decimal] = Field(None, gt=0)
|
||||
unit_of_measure: Optional[str] = Field(None, max_length=20)
|
||||
minimum_order_quantity: Optional[int] = Field(None, ge=1)
|
||||
tier_pricing: Optional[Dict[str, Any]] = None
|
||||
effective_date: Optional[datetime] = None
|
||||
expiry_date: Optional[datetime] = None
|
||||
is_active: Optional[bool] = None
|
||||
brand: Optional[str] = Field(None, max_length=100)
|
||||
packaging_size: Optional[str] = Field(None, max_length=50)
|
||||
origin_country: Optional[str] = Field(None, max_length=100)
|
||||
shelf_life_days: Optional[int] = None
|
||||
storage_requirements: Optional[str] = None
|
||||
quality_specs: Optional[Dict[str, Any]] = None
|
||||
allergens: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
class SupplierPriceListResponse(BaseModel):
|
||||
"""Schema for supplier price list responses"""
|
||||
id: UUID
|
||||
tenant_id: UUID
|
||||
supplier_id: UUID
|
||||
inventory_product_id: UUID
|
||||
product_code: Optional[str] = None
|
||||
unit_price: Decimal
|
||||
unit_of_measure: str
|
||||
minimum_order_quantity: Optional[int] = None
|
||||
price_per_unit: Decimal
|
||||
tier_pricing: Optional[Dict[str, Any]] = None
|
||||
effective_date: datetime
|
||||
expiry_date: Optional[datetime] = None
|
||||
is_active: bool
|
||||
brand: Optional[str] = None
|
||||
packaging_size: Optional[str] = None
|
||||
origin_country: Optional[str] = None
|
||||
shelf_life_days: Optional[int] = None
|
||||
storage_requirements: Optional[str] = None
|
||||
quality_specs: Optional[Dict[str, Any]] = None
|
||||
allergens: Optional[Dict[str, Any]] = None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
created_by: UUID
|
||||
updated_by: UUID
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# STATISTICS AND REPORTING SCHEMAS
|
||||
# ============================================================================
|
||||
@@ -641,4 +715,4 @@ class DeliverySummaryStats(BaseModel):
|
||||
todays_deliveries: int
|
||||
this_week_deliveries: int
|
||||
overdue_deliveries: int
|
||||
in_transit_deliveries: int
|
||||
in_transit_deliveries: int
|
||||
|
||||
@@ -13,7 +13,8 @@ from app.repositories.supplier_repository import SupplierRepository
|
||||
from app.models.suppliers import Supplier, SupplierStatus, SupplierType
|
||||
from app.schemas.suppliers import (
|
||||
SupplierCreate, SupplierUpdate, SupplierResponse,
|
||||
SupplierSearchParams, SupplierStatistics
|
||||
SupplierSearchParams, SupplierStatistics,
|
||||
SupplierPriceListCreate, SupplierPriceListUpdate, SupplierPriceListResponse
|
||||
)
|
||||
from app.core.config import settings
|
||||
|
||||
@@ -378,3 +379,132 @@ class SupplierService:
|
||||
errors['minimum_order_amount'] = "Minimum order amount cannot be negative"
|
||||
|
||||
return errors
|
||||
|
||||
async def get_supplier_price_lists(
|
||||
self,
|
||||
supplier_id: UUID,
|
||||
tenant_id: UUID,
|
||||
is_active: bool = True
|
||||
) -> List[Any]:
|
||||
"""Get all price list items for a supplier"""
|
||||
logger.info(
|
||||
"Getting supplier price lists",
|
||||
supplier_id=str(supplier_id),
|
||||
tenant_id=str(tenant_id),
|
||||
is_active=is_active
|
||||
)
|
||||
|
||||
return await self.repository.get_supplier_price_lists(
|
||||
supplier_id=supplier_id,
|
||||
tenant_id=tenant_id,
|
||||
is_active=is_active
|
||||
)
|
||||
|
||||
async def get_supplier_price_list(
|
||||
self,
|
||||
price_list_id: UUID,
|
||||
tenant_id: UUID
|
||||
) -> Optional[Any]:
|
||||
"""Get specific price list item"""
|
||||
logger.info(
|
||||
"Getting supplier price list item",
|
||||
price_list_id=str(price_list_id),
|
||||
tenant_id=str(tenant_id)
|
||||
)
|
||||
|
||||
return await self.repository.get_supplier_price_list(
|
||||
price_list_id=price_list_id,
|
||||
tenant_id=tenant_id
|
||||
)
|
||||
|
||||
async def create_supplier_price_list(
|
||||
self,
|
||||
supplier_id: UUID,
|
||||
price_list_data: SupplierPriceListCreate,
|
||||
tenant_id: UUID,
|
||||
created_by: UUID
|
||||
) -> Any:
|
||||
"""Create a new price list item for a supplier"""
|
||||
logger.info(
|
||||
"Creating supplier price list item",
|
||||
supplier_id=str(supplier_id),
|
||||
tenant_id=str(tenant_id)
|
||||
)
|
||||
|
||||
# Prepare creation data
|
||||
create_data = price_list_data.model_dump(exclude_unset=True)
|
||||
create_data.update({
|
||||
'tenant_id': tenant_id,
|
||||
'supplier_id': supplier_id,
|
||||
'created_by': created_by,
|
||||
'updated_by': created_by,
|
||||
})
|
||||
|
||||
# Calculate price_per_unit if not provided
|
||||
if 'price_per_unit' not in create_data or create_data['price_per_unit'] is None:
|
||||
create_data['price_per_unit'] = create_data['unit_price']
|
||||
|
||||
price_list = await self.repository.create_supplier_price_list(create_data)
|
||||
|
||||
logger.info(
|
||||
"Supplier price list item created successfully",
|
||||
price_list_id=str(price_list.id),
|
||||
supplier_id=str(supplier_id)
|
||||
)
|
||||
|
||||
return price_list
|
||||
|
||||
async def update_supplier_price_list(
|
||||
self,
|
||||
price_list_id: UUID,
|
||||
price_list_data: SupplierPriceListUpdate,
|
||||
tenant_id: UUID,
|
||||
updated_by: UUID
|
||||
) -> Any:
|
||||
"""Update a price list item"""
|
||||
logger.info(
|
||||
"Updating supplier price list item",
|
||||
price_list_id=str(price_list_id),
|
||||
tenant_id=str(tenant_id)
|
||||
)
|
||||
|
||||
# Prepare update data
|
||||
update_data = price_list_data.model_dump(exclude_unset=True)
|
||||
update_data['updated_by'] = updated_by
|
||||
update_data['updated_at'] = datetime.now()
|
||||
|
||||
price_list = await self.repository.update_supplier_price_list(
|
||||
price_list_id=price_list_id,
|
||||
update_data=update_data
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"Supplier price list item updated successfully",
|
||||
price_list_id=str(price_list_id)
|
||||
)
|
||||
|
||||
return price_list
|
||||
|
||||
async def delete_supplier_price_list(
|
||||
self,
|
||||
price_list_id: UUID,
|
||||
tenant_id: UUID
|
||||
) -> bool:
|
||||
"""Delete a price list item"""
|
||||
logger.info(
|
||||
"Deleting supplier price list item",
|
||||
price_list_id=str(price_list_id),
|
||||
tenant_id=str(tenant_id)
|
||||
)
|
||||
|
||||
success = await self.repository.delete_supplier_price_list(
|
||||
price_list_id=price_list_id
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"Supplier price list item deletion completed",
|
||||
price_list_id=str(price_list_id),
|
||||
success=success
|
||||
)
|
||||
|
||||
return success
|
||||
|
||||
Reference in New Issue
Block a user