70 lines
2.1 KiB
Python
70 lines
2.1 KiB
Python
import asyncio
|
|
import logging
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
from .lknpd_client import LknpdApiError, LknpdClient, PaymentType
|
|
|
|
|
|
class LknpdService:
|
|
def __init__(
|
|
self,
|
|
inn: Optional[str],
|
|
password: Optional[str],
|
|
api_url: str = "https://lknpd.nalog.ru/api",
|
|
) -> None:
|
|
self.inn = inn.strip() if inn else None
|
|
self.password = password
|
|
self.configured = bool(self.inn and self.password)
|
|
self._client = LknpdClient(base_url=api_url) if self.configured else None
|
|
self._auth_lock = asyncio.Lock()
|
|
|
|
if not self.configured:
|
|
logging.warning("LKNPD credentials are missing. Receipt sending disabled.")
|
|
|
|
async def _ensure_authenticated(self) -> bool:
|
|
if not self._client:
|
|
return False
|
|
|
|
async with self._auth_lock:
|
|
if self._client.is_authenticated:
|
|
return True
|
|
|
|
try:
|
|
await self._client.authenticate(self.inn, self.password)
|
|
return True
|
|
except LknpdApiError:
|
|
logging.exception("LKNPD authentication failed.")
|
|
return False
|
|
|
|
async def create_income_receipt(
|
|
self,
|
|
*,
|
|
item_name: str,
|
|
amount: float,
|
|
quantity: float = 1.0,
|
|
operation_time: Optional[datetime] = None,
|
|
) -> Optional[str]:
|
|
if not self.configured:
|
|
return None
|
|
if not await self._ensure_authenticated():
|
|
return None
|
|
|
|
try:
|
|
receipt_uuid = await self._client.create_income(
|
|
name=item_name,
|
|
amount=amount,
|
|
quantity=quantity,
|
|
payment_type=PaymentType.WIRE,
|
|
operation_time=operation_time,
|
|
)
|
|
if not receipt_uuid:
|
|
logging.info("LKNPD receipt created without a UUID in response.")
|
|
return receipt_uuid
|
|
except LknpdApiError:
|
|
logging.exception("Failed to create LKNPD receipt.")
|
|
return None
|
|
|
|
async def close(self) -> None:
|
|
return None
|