Improve the frontend modals
This commit is contained in:
@@ -217,44 +217,134 @@ class SupplierRepository(BaseRepository[Supplier]):
|
||||
"total_spend": float(total_spend)
|
||||
}
|
||||
|
||||
def approve_supplier(
|
||||
async def approve_supplier(
|
||||
self,
|
||||
supplier_id: UUID,
|
||||
approved_by: UUID,
|
||||
approval_date: Optional[datetime] = None
|
||||
) -> Optional[Supplier]:
|
||||
"""Approve a pending supplier"""
|
||||
supplier = self.get_by_id(supplier_id)
|
||||
if not supplier or supplier.status != SupplierStatus.PENDING_APPROVAL:
|
||||
supplier = await self.get_by_id(supplier_id)
|
||||
if not supplier or supplier.status != SupplierStatus.pending_approval:
|
||||
return None
|
||||
|
||||
supplier.status = SupplierStatus.ACTIVE
|
||||
|
||||
supplier.status = SupplierStatus.active
|
||||
supplier.approved_by = approved_by
|
||||
supplier.approved_at = approval_date or datetime.utcnow()
|
||||
supplier.rejection_reason = None
|
||||
supplier.updated_at = datetime.utcnow()
|
||||
|
||||
self.db.commit()
|
||||
self.db.refresh(supplier)
|
||||
|
||||
await self.db.commit()
|
||||
await self.db.refresh(supplier)
|
||||
return supplier
|
||||
|
||||
def reject_supplier(
|
||||
async def reject_supplier(
|
||||
self,
|
||||
supplier_id: UUID,
|
||||
rejection_reason: str,
|
||||
approved_by: UUID
|
||||
) -> Optional[Supplier]:
|
||||
"""Reject a pending supplier"""
|
||||
supplier = self.get_by_id(supplier_id)
|
||||
if not supplier or supplier.status != SupplierStatus.PENDING_APPROVAL:
|
||||
supplier = await self.get_by_id(supplier_id)
|
||||
if not supplier or supplier.status != SupplierStatus.pending_approval:
|
||||
return None
|
||||
|
||||
supplier.status = SupplierStatus.INACTIVE
|
||||
|
||||
supplier.status = SupplierStatus.inactive
|
||||
supplier.rejection_reason = rejection_reason
|
||||
supplier.approved_by = approved_by
|
||||
supplier.approved_at = datetime.utcnow()
|
||||
supplier.updated_at = datetime.utcnow()
|
||||
|
||||
self.db.commit()
|
||||
self.db.refresh(supplier)
|
||||
return supplier
|
||||
|
||||
await self.db.commit()
|
||||
await self.db.refresh(supplier)
|
||||
return supplier
|
||||
async def hard_delete_supplier(self, supplier_id: UUID) -> Dict[str, Any]:
|
||||
"""
|
||||
Hard delete supplier and all associated data
|
||||
Returns counts of deleted records
|
||||
"""
|
||||
from app.models.suppliers import (
|
||||
SupplierPriceList, SupplierQualityReview,
|
||||
SupplierAlert, SupplierScorecard, PurchaseOrderStatus, PurchaseOrder
|
||||
)
|
||||
from app.models.performance import SupplierPerformanceMetric
|
||||
from sqlalchemy import delete
|
||||
|
||||
# Get supplier first
|
||||
supplier = await self.get_by_id(supplier_id)
|
||||
if not supplier:
|
||||
return None
|
||||
|
||||
# Check for active purchase orders (block deletion if any exist)
|
||||
active_statuses = [
|
||||
PurchaseOrderStatus.draft,
|
||||
PurchaseOrderStatus.pending_approval,
|
||||
PurchaseOrderStatus.approved,
|
||||
PurchaseOrderStatus.sent_to_supplier,
|
||||
PurchaseOrderStatus.confirmed
|
||||
]
|
||||
|
||||
stmt = select(PurchaseOrder).where(
|
||||
PurchaseOrder.supplier_id == supplier_id,
|
||||
PurchaseOrder.status.in_(active_statuses)
|
||||
)
|
||||
result = await self.db.execute(stmt)
|
||||
active_pos = result.scalars().all()
|
||||
|
||||
if active_pos:
|
||||
raise ValueError(
|
||||
f"Cannot delete supplier with {len(active_pos)} active purchase orders. "
|
||||
"Complete or cancel all purchase orders first."
|
||||
)
|
||||
|
||||
# Count related records before deletion
|
||||
stmt = select(SupplierPriceList).where(SupplierPriceList.supplier_id == supplier_id)
|
||||
result = await self.db.execute(stmt)
|
||||
price_lists_count = len(result.scalars().all())
|
||||
|
||||
stmt = select(SupplierQualityReview).where(SupplierQualityReview.supplier_id == supplier_id)
|
||||
result = await self.db.execute(stmt)
|
||||
quality_reviews_count = len(result.scalars().all())
|
||||
|
||||
stmt = select(SupplierPerformanceMetric).where(SupplierPerformanceMetric.supplier_id == supplier_id)
|
||||
result = await self.db.execute(stmt)
|
||||
metrics_count = len(result.scalars().all())
|
||||
|
||||
stmt = select(SupplierAlert).where(SupplierAlert.supplier_id == supplier_id)
|
||||
result = await self.db.execute(stmt)
|
||||
alerts_count = len(result.scalars().all())
|
||||
|
||||
stmt = select(SupplierScorecard).where(SupplierScorecard.supplier_id == supplier_id)
|
||||
result = await self.db.execute(stmt)
|
||||
scorecards_count = len(result.scalars().all())
|
||||
|
||||
# Delete related records (in reverse dependency order)
|
||||
stmt = delete(SupplierScorecard).where(SupplierScorecard.supplier_id == supplier_id)
|
||||
await self.db.execute(stmt)
|
||||
|
||||
stmt = delete(SupplierAlert).where(SupplierAlert.supplier_id == supplier_id)
|
||||
await self.db.execute(stmt)
|
||||
|
||||
stmt = delete(SupplierPerformanceMetric).where(SupplierPerformanceMetric.supplier_id == supplier_id)
|
||||
await self.db.execute(stmt)
|
||||
|
||||
stmt = delete(SupplierQualityReview).where(SupplierQualityReview.supplier_id == supplier_id)
|
||||
await self.db.execute(stmt)
|
||||
|
||||
stmt = delete(SupplierPriceList).where(SupplierPriceList.supplier_id == supplier_id)
|
||||
await self.db.execute(stmt)
|
||||
|
||||
# Delete the supplier itself
|
||||
await self.delete(supplier_id)
|
||||
|
||||
await self.db.commit()
|
||||
|
||||
return {
|
||||
"supplier_name": supplier.name,
|
||||
"deleted_price_lists": price_lists_count,
|
||||
"deleted_quality_reviews": quality_reviews_count,
|
||||
"deleted_performance_metrics": metrics_count,
|
||||
"deleted_alerts": alerts_count,
|
||||
"deleted_scorecards": scorecards_count,
|
||||
"deletion_timestamp": datetime.utcnow()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user