lambda-erp 0.1.36__tar.gz → 0.1.37__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/PKG-INFO +1 -1
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/routers/chat_api.py +28 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/pyproject.toml +1 -1
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/.gitignore +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/LICENSE +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/README.md +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/__init__.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/attachments.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/auth.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/bootstrap.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/chat.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/demo_limits.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/deps.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/errors.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/main.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/oauth.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/pdf.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/providers.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/remarks_md.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/routers/__init__.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/routers/accounting.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/routers/admin.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/routers/analytics.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/routers/bank_reconciliation.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/routers/documents.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/routers/masters.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/routers/proposals.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/routers/reports.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/routers/setup.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/services.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/templates/document.html +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/api/templates/proposal.html +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/docs/agents/README.md +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/frontend/README.md +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/frontend/src/api/client.ts +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/__init__.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/accounting/__init__.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/accounting/bank_transaction.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/accounting/budget.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/accounting/chart_of_accounts.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/accounting/general_ledger.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/accounting/journal_entry.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/accounting/payment_entry.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/accounting/pos_invoice.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/accounting/purchase_invoice.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/accounting/revaluation.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/accounting/sales_invoice.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/accounting/subscription.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/buying/__init__.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/buying/purchase_order.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/controllers/__init__.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/controllers/currency.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/controllers/defaults.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/controllers/pricing_rule.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/controllers/taxes_and_totals.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/database.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/exceptions.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/hooks.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/model.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/selling/__init__.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/selling/proposal.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/selling/quotation.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/selling/sales_order.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/simulation.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/stock/__init__.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/stock/delivery_note.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/stock/purchase_receipt.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/stock/stock_entry.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/stock/stock_ledger.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/lambda_erp/utils.py +0 -0
- {lambda_erp-0.1.36 → lambda_erp-0.1.37}/terraform/README.md +0 -0
|
@@ -16,6 +16,7 @@ Statefulness (see docs/chat-api-plan.md):
|
|
|
16
16
|
caller-owned, ephemeral working memory for a single multi-step ERP task.
|
|
17
17
|
"""
|
|
18
18
|
from fastapi import APIRouter, Depends, HTTPException, Request
|
|
19
|
+
from fastapi.responses import Response
|
|
19
20
|
from pydantic import BaseModel
|
|
20
21
|
|
|
21
22
|
from api.auth import get_api_caller
|
|
@@ -27,6 +28,8 @@ from api.chat import (
|
|
|
27
28
|
run_session_turn,
|
|
28
29
|
save_chat_message,
|
|
29
30
|
)
|
|
31
|
+
from api.pdf import generate_pdf
|
|
32
|
+
from api.services import load_document
|
|
30
33
|
|
|
31
34
|
router = APIRouter(prefix="/v1", tags=["chat-api"])
|
|
32
35
|
|
|
@@ -92,6 +95,31 @@ async def chat(payload: ChatApiRequest, request: Request, caller: dict = Depends
|
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
|
|
98
|
+
@router.get("/documents/{doctype_slug}/{name}/pdf")
|
|
99
|
+
def document_pdf(doctype_slug: str, name: str, caller: dict = Depends(get_api_caller)):
|
|
100
|
+
"""Render a document's PDF for a Bearer-key caller.
|
|
101
|
+
|
|
102
|
+
The chat agent's replies link to `/api/documents/{slug}/{name}/pdf`, but that
|
|
103
|
+
route is cookie-gated (require_role) and so unreachable by an API caller. This
|
|
104
|
+
mirrors it for the programmatic surface so an orchestrator (lambda-web → the
|
|
105
|
+
iPhone app) can fetch the actual bytes. A missing document raises
|
|
106
|
+
ValidationError("… not found") → 404, an unknown doctype ValueError → 422, via
|
|
107
|
+
the global handlers.
|
|
108
|
+
"""
|
|
109
|
+
pdf_bytes = generate_pdf(doctype_slug, name)
|
|
110
|
+
return Response(
|
|
111
|
+
content=pdf_bytes,
|
|
112
|
+
media_type="application/pdf",
|
|
113
|
+
headers={"Content-Disposition": f'inline; filename="{name}.pdf"'},
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@router.get("/documents/{doctype_slug}/{name}")
|
|
118
|
+
def document_json(doctype_slug: str, name: str, caller: dict = Depends(get_api_caller)):
|
|
119
|
+
"""Return a document's structured data for a Bearer-key caller (read-only)."""
|
|
120
|
+
return load_document(doctype_slug, name)
|
|
121
|
+
|
|
122
|
+
|
|
95
123
|
@router.get("/chat/sessions")
|
|
96
124
|
def sessions(caller: dict = Depends(get_api_caller)):
|
|
97
125
|
"""List the caller's chat sessions (id, title, timestamps)."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|