Initial commit: mini-erp (backend FastAPI + frontend React/Vite)
Base para el flujo de ramas por cliente. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
commit
ab3c613165
154 files changed
+16872
No files matched your search
@@ -0,0 +1,123 @@
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from fastapi import APIRouter, Request
|
||||
|
||||
from core.sap import forward_to_sapb1
|
||||
|
||||
|
||||
def _build_sap_params(
|
||||
skip: int,
|
||||
top: int,
|
||||
fields: Optional[str],
|
||||
filter: Optional[str],
|
||||
orderby: Optional[str] = None,
|
||||
) -> Dict[str, Any]:
|
||||
sap_params: Dict[str, Any] = {
|
||||
"$skip": skip,
|
||||
"$top": top,
|
||||
"$inlinecount": "allpages",
|
||||
}
|
||||
if fields:
|
||||
sap_params["$select"] = fields.replace(" ", "")
|
||||
if filter:
|
||||
sap_params["$filter"] = filter
|
||||
if orderby:
|
||||
sap_params["$orderby"] = orderby
|
||||
return sap_params
|
||||
|
||||
|
||||
def _build_list_headers(top: int, filter: Optional[str]) -> Dict[str, str]:
|
||||
headers = {"B1S-PageSize": str(top)}
|
||||
if filter:
|
||||
headers["B1S-CaseInsensitive"] = "true"
|
||||
return headers
|
||||
|
||||
|
||||
def make_crud_router(
|
||||
resource: str,
|
||||
*,
|
||||
tags: List[str],
|
||||
key_field: Optional[str] = None,
|
||||
key_quoted: bool = False,
|
||||
supports_orderby: bool = False,
|
||||
supports_get_by_key: bool = True,
|
||||
supports_create: bool = True,
|
||||
supports_patch: bool = True,
|
||||
patch_headers: Optional[Dict[str, str]] = None,
|
||||
) -> APIRouter:
|
||||
"""
|
||||
Genera el router list/get/create/update repetido antes en cada módulo de
|
||||
routers/ (mismo bloque de $skip/$top/$filter y de forward_to_sapb1, solo
|
||||
cambiaba el nombre del recurso OData). Centralizarlo evita que un
|
||||
copy-paste entre recursos deje, por ejemplo, un PATCH apuntando al
|
||||
endpoint_path de otro recurso.
|
||||
"""
|
||||
router = APIRouter(tags=tags)
|
||||
|
||||
def key_expr(key: str) -> str:
|
||||
return f"{resource}('{key}')" if key_quoted else f"{resource}({key})"
|
||||
|
||||
if supports_orderby:
|
||||
@router.get(f"/api/{resource}", name=f"list_{resource}")
|
||||
async def list_resource(
|
||||
skip: int = 0,
|
||||
top: int = 50,
|
||||
fields: Optional[str] = None,
|
||||
filter: Optional[str] = None,
|
||||
orderby: Optional[str] = None,
|
||||
):
|
||||
sap_params = _build_sap_params(skip, top, fields, filter, orderby)
|
||||
return forward_to_sapb1(
|
||||
method="GET",
|
||||
endpoint_path=resource,
|
||||
params=sap_params,
|
||||
extra_headers=_build_list_headers(top, filter),
|
||||
).json()
|
||||
else:
|
||||
@router.get(f"/api/{resource}", name=f"list_{resource}")
|
||||
async def list_resource(
|
||||
skip: int = 0,
|
||||
top: int = 50,
|
||||
fields: Optional[str] = None,
|
||||
filter: Optional[str] = None,
|
||||
):
|
||||
sap_params = _build_sap_params(skip, top, fields, filter)
|
||||
return forward_to_sapb1(
|
||||
method="GET",
|
||||
endpoint_path=resource,
|
||||
params=sap_params,
|
||||
extra_headers=_build_list_headers(top, filter),
|
||||
).json()
|
||||
|
||||
if supports_get_by_key:
|
||||
@router.get(f"/api/{resource}/{{key}}", name=f"get_{resource}_by_key")
|
||||
async def get_by_key(key: str):
|
||||
return forward_to_sapb1(
|
||||
method="GET",
|
||||
endpoint_path=key_expr(key),
|
||||
).json()
|
||||
|
||||
if supports_create:
|
||||
@router.post(f"/api/{resource}", status_code=201, name=f"create_{resource}")
|
||||
async def create_resource(request: Request):
|
||||
data = await request.json()
|
||||
resp = forward_to_sapb1(
|
||||
method="POST",
|
||||
endpoint_path=resource,
|
||||
json_data=data,
|
||||
)
|
||||
created = resp.json()
|
||||
return {key_field: created[key_field]}
|
||||
|
||||
if supports_patch:
|
||||
@router.patch(f"/api/{resource}/{{key}}", status_code=204, name=f"update_{resource}")
|
||||
async def update_resource(key: str, request: Request):
|
||||
data = await request.json()
|
||||
forward_to_sapb1(
|
||||
method="PATCH",
|
||||
endpoint_path=key_expr(key),
|
||||
json_data=data,
|
||||
extra_headers=patch_headers,
|
||||
)
|
||||
|
||||
return router
|
||||
Reference in new issue
Block a user