195 lines
5.9 KiB
Python
195 lines
5.9 KiB
Python
import os
|
|
from aiohttp import ClientSession
|
|
from typing import Dict, List, Optional, Union, TypedDict
|
|
|
|
API_KEY = os.getenv("PANCAKE_API_KEY")
|
|
API_URL = os.getenv("PANCAKE_API_URL")
|
|
|
|
|
|
class PaginationParams(TypedDict, total=False):
|
|
limit: int
|
|
start: int
|
|
sort_by: str
|
|
sort_dir: str # "asc" or "desc"
|
|
|
|
|
|
class ClientResponse(TypedDict):
|
|
id: str
|
|
first_name: str
|
|
last_name: str
|
|
company: str
|
|
total: float
|
|
unpaid_total: float
|
|
|
|
|
|
class ProjectResponse(TypedDict):
|
|
name: str
|
|
tasks: List[Dict]
|
|
times: List[Dict]
|
|
|
|
|
|
class InvoiceResponse(TypedDict):
|
|
id: int
|
|
invoice_number: str
|
|
client_id: str
|
|
amount: str
|
|
due_date: str
|
|
description: str
|
|
is_viewable: str # "0" or "1"
|
|
has_sent_notification: str # "0" or "1"
|
|
is_paid: bool
|
|
date_entered: str
|
|
overdue: bool
|
|
payment_status: str
|
|
payment_date: str
|
|
company: str
|
|
email: str
|
|
last_sent: str
|
|
last_viewed: str
|
|
|
|
|
|
class ListResponse(TypedDict, total=False):
|
|
status: bool
|
|
message: str
|
|
count: int
|
|
clients: List[ClientResponse]
|
|
projects: List[ProjectResponse]
|
|
invoices: List[InvoiceResponse]
|
|
|
|
|
|
class PancakeAPI:
|
|
def __init__(self):
|
|
self.headers = {"x-api-key": API_KEY}
|
|
self.prefix_url = API_URL
|
|
|
|
async def _get(self, url: str, params: Optional[Dict] = None) -> Dict:
|
|
async with ClientSession() as session:
|
|
async with session.get(f"{self.prefix_url}/{url}", headers=self.headers, params=params) as response:
|
|
return await response.json()
|
|
|
|
async def _post(self, url: str, json: Optional[Dict] = None) -> Dict:
|
|
async with ClientSession() as session:
|
|
async with session.post(f"{self.prefix_url}/{url}", headers=self.headers, json=json) as response:
|
|
return await response.json()
|
|
|
|
# Clients
|
|
async def get_all_clients(self, params: PaginationParams) -> ListResponse:
|
|
url = "clients"
|
|
return await self._get(url, params)
|
|
|
|
async def get_one_client(self, client_id: str) -> ClientResponse:
|
|
url = "clients/show"
|
|
return await self._get(url, {"id": client_id})
|
|
|
|
async def create_new_client(self, data: Dict) -> Dict:
|
|
url = "clients/new"
|
|
return await self._post(url, data)
|
|
|
|
async def update_client(self, data: Dict) -> Dict:
|
|
url = "clients/edit"
|
|
return await self._post(url, data)
|
|
|
|
async def delete_client(self, client_id: str) -> Dict:
|
|
url = "clients/delete"
|
|
return await self._post(url, {"id": client_id})
|
|
|
|
# Projects
|
|
async def get_all_projects(self, params: PaginationParams) -> ListResponse:
|
|
url = "projects"
|
|
return await self._get(url, params)
|
|
|
|
async def get_one_project(self, project_id: str) -> ProjectResponse:
|
|
url = "projects/show"
|
|
return await self._get(url, {"id": project_id})
|
|
|
|
async def create_new_project(self, data: Dict) -> Dict:
|
|
url = "projects/new"
|
|
return await self._post(url, data)
|
|
|
|
async def update_project(self, data: Dict) -> Dict:
|
|
url = "projects/edit"
|
|
return await self._post(url, data)
|
|
|
|
# Tasks
|
|
async def get_tasks_by_project(self, project_id: str) -> Dict:
|
|
url = "projects/tasks"
|
|
return await self._get(url, {"id": project_id})
|
|
|
|
async def create_task(self, data: Dict) -> Dict:
|
|
url = "projects/tasks/new"
|
|
return await self._post(url, data)
|
|
|
|
async def update_task(self, data: Dict) -> Dict:
|
|
url = "projects/tasks/update"
|
|
return await self._post(url, data)
|
|
|
|
async def delete_task(self, task_id: str) -> Dict:
|
|
url = "projects/tasks/show"
|
|
return await self._post(url, {"id": task_id})
|
|
|
|
async def log_time_on_task(self, data: Dict) -> Dict:
|
|
url = "projects/tasks/log_time"
|
|
return await self._post(url, data)
|
|
|
|
async def complete_task(self, task_id: str) -> Dict:
|
|
url = "projects/tasks/compete"
|
|
return await self._post(url, {"id": task_id})
|
|
|
|
async def reopen_task(self, task_id: str) -> Dict:
|
|
url = "projects/tasks/reopen"
|
|
return await self._post(url, {"id": task_id})
|
|
|
|
# Invoices
|
|
async def get_all_invoices(self, params: Dict) -> ListResponse:
|
|
url = "invoices"
|
|
return await self._get(url, params)
|
|
|
|
async def get_one_invoice(self, invoice_id: str) -> Dict:
|
|
url = "invoices/show"
|
|
return await self._get(url, {"id": invoice_id})
|
|
|
|
async def create_new_invoice(self, data: Dict) -> Dict:
|
|
url = "invoices/new"
|
|
return await self._post(url, data)
|
|
|
|
async def update_invoice(self, data: Dict) -> Dict:
|
|
url = "invoices/edit"
|
|
return await self._post(url, data)
|
|
|
|
async def delete_invoice(self, invoice_id: str) -> Dict:
|
|
url = "invoices/delete"
|
|
return await self._post(url, {"id": invoice_id})
|
|
|
|
async def open_invoice(self, invoice_id: str) -> Dict:
|
|
url = "invoices/open"
|
|
return await self._post(url, {"id": invoice_id})
|
|
|
|
async def close_invoice(self, invoice_id: str) -> Dict:
|
|
url = "invoices/close"
|
|
return await self._post(url, {"id": invoice_id})
|
|
|
|
async def mark_invoice_paid(self, invoice_id: str) -> Dict:
|
|
url = "invoices/paid"
|
|
return await self._post(url, {"id": invoice_id})
|
|
|
|
async def send_invoice(self, invoice_id: str) -> Dict:
|
|
url = "invoices/send"
|
|
return await self._post(url, {"id": invoice_id})
|
|
|
|
# Users
|
|
async def get_all_users(self, params: PaginationParams) -> ListResponse:
|
|
url = "users"
|
|
return await self._get(url, params)
|
|
|
|
async def get_one_user(self, user_id: str) -> Dict:
|
|
url = "users/show"
|
|
return await self._get(url, {"id": user_id})
|
|
|
|
async def update_user(self, data: Dict) -> Dict:
|
|
url = "users/edit"
|
|
return await self._post(url, data)
|
|
|
|
async def delete_user(self, user_id: str) -> Dict:
|
|
url = "users/delete"
|
|
return await self._post(url, {"id": user_id})
|