Files
YaoXiang/backend/app/services/batch.py
T
2026-06-15 14:50:15 +08:00

89 lines
2.9 KiB
Python

from typing import List, Optional
from datetime import date, timedelta
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.batch import Batch
from app.schemas.batch import BatchCreate, BatchUpdate
from app.repositories.batch import BatchRepository
from app.services.audit import AuditService
class BatchService:
def __init__(self, db: AsyncSession):
self.db = db
self.repo = BatchRepository(db)
self.audit_service = AuditService(db)
async def get_batches_by_medicine(self, medicine_id: int) -> List[Batch]:
return await self.repo.get_by_medicine_id(medicine_id)
async def get_batch(self, batch_id: int) -> Optional[Batch]:
return await self.repo.get_by_id(batch_id)
async def create_batch(self, medicine_id: int, data: BatchCreate) -> Batch:
batch_data = data.model_dump()
batch_data['medicine_id'] = medicine_id
return await self.repo.create(batch_data)
async def update_batch(self, batch_id: int, data: BatchUpdate) -> Optional[Batch]:
update_data = data.model_dump(exclude_unset=True)
return await self.repo.update(batch_id, update_data)
async def delete_batch(self, batch_id: int) -> bool:
return await self.repo.delete(batch_id)
async def dispense(self, batch_id: int, quantity: int, user_id: int) -> Optional[Batch]:
batch = await self.repo.get_by_id(batch_id)
if not batch:
raise ValueError("批次不存在")
if batch.quantity < quantity:
raise ValueError("库存不足")
await self.audit_service.log_action(
medicine_id=batch.medicine_id,
batch_id=batch_id,
user_id=user_id,
action="dispense",
quantity_change=-quantity,
quantity_after=batch.quantity - quantity
)
batch.quantity -= quantity
await self.db.commit()
return batch
async def add_stock(self, batch_id: int, quantity: int, user_id: int) -> Optional[Batch]:
batch = await self.repo.get_by_id(batch_id)
if not batch:
raise ValueError("批次不存在")
await self.audit_service.log_action(
medicine_id=batch.medicine_id,
batch_id=batch_id,
user_id=user_id,
action="add_stock",
quantity_change=quantity,
quantity_after=batch.quantity + quantity
)
batch.quantity += quantity
await self.db.commit()
return batch
async def check_expiring_batches(self, warning_days: List[int]) -> List[dict]:
expiring = []
today = date.today()
for days in warning_days:
target_date = today + timedelta(days=days)
batches = await self.repo.get_expiring_before(target_date)
for batch in batches:
expiring.append({
'batch': batch,
'days_until_expiry': days
})
return expiring