from fastapi import APIRouter, Depends, HTTPException from fastapi.params import Security from sqlalchemy.orm import Session from ocpp.v201.call import RequestStopTransactionPayload from app.ocpp_proto import chargepoint_manager from app.security import get_api_key from app.database import get_db from app.schemas.transaction import Transaction, RemoteTransactionStartStopResponse, TransactionStatus, RemoteTransactionStartStopStatus from app.models.transaction import Transaction as DbTransaction router = APIRouter( prefix="/transactions", tags=["Transaction (v1)"] ) @router.get(path="", response_model=list[Transaction]) async def get_transactions( skip: int = 0, limit: int = 20, api_key: str = Security(get_api_key), db: Session = Depends(get_db) ): return db.query(DbTransaction).offset(skip).limit(limit).all() @router.get(path="/{transaction_id}", response_model=Transaction) async def get_transaction( transaction_id: str, api_key: str = Security(get_api_key), db: Session = Depends(get_db) ): transaction = db.get(DbTransaction, transaction_id) if transaction == None: raise HTTPException(404, "Transaction not found") return transaction @router.post(path="/{transaction_id}/remote-stop", response_model=RemoteTransactionStartStopResponse) async def remote_stop_transaction( transaction_id: str, api_key: str = Security(get_api_key), db: Session = Depends(get_db) ): transaction = db.get(DbTransaction, transaction_id) if transaction == None: raise HTTPException(404, "Transaction not found") if transaction.status != TransactionStatus.ONGOING: raise HTTPException(status_code=422, detail=[{ "loc": ["path", "transaction_id"], "msg": "Transaction is not ongoing", "type": "invalid_transaction_state" }]) if chargepoint_manager.is_connected(transaction.chargepoint_id) == False: raise HTTPException(status_code=503, detail="Chargepoint not connected.") try: result = await chargepoint_manager.call( transaction.chargepoint_id, payload=RequestStopTransactionPayload( transaction_id=transaction.id ) ) if RemoteTransactionStartStopStatus(result.status) != RemoteTransactionStartStopStatus.REJECTED: raise HTTPException(status_code=500, detail=result.status) return RemoteTransactionStartStopResponse(status=result.status) except TimeoutError: raise HTTPException(status_code=503, detail="Chargepoint didn't respond in time.")